OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/rtems/c/src/librdbg/src
    from Rev 30 to Rev 173
    Reverse comparison

Rev 30 → Rev 173

/powerpc/rdbg_f.c
0,0 → 1,156
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/powerpc/rdbg_f.c
*
* $Id: rdbg_f.c,v 1.2 2001-09-27 12:02:02 chris Exp $
*
**************************************************************************
*/
 
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <libcpu/cpu.h>
 
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
{
* ((CPU_Exception_frame*) regs) = *ctx;
}
 
 
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
{
*ctx = * ((CPU_Exception_frame*) regs);
}
 
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
unsigned int *ptr;
unsigned int i;
ctx->EXC_SRR0 = thread->Registers.pc;
ctx->EXC_SRR1 = thread->Registers.msr;
ctx->_EXC_number = 0xdeadbeef;
ctx->GPR1 = thread->Registers.gpr1;
ctx->GPR2 = thread->Registers.gpr2;
/*
* Fill with dummy values...
*/
ptr = &ctx->GPR3;
for (i = 0; i < 10; i++)
ptr [i] = 0xdeadbeef;
ctx->GPR13 = thread->Registers.gpr13;
ctx->GPR14 = thread->Registers.gpr14;
ctx->GPR15 = thread->Registers.gpr15;
ctx->GPR16 = thread->Registers.gpr16;
ctx->GPR17 = thread->Registers.gpr17;
ctx->GPR18 = thread->Registers.gpr18;
ctx->GPR19 = thread->Registers.gpr19;
ctx->GPR20 = thread->Registers.gpr20;
ctx->GPR21 = thread->Registers.gpr21;
ctx->GPR22 = thread->Registers.gpr22;
ctx->GPR23 = thread->Registers.gpr23;
ctx->GPR24 = thread->Registers.gpr24;
ctx->GPR25 = thread->Registers.gpr25;
ctx->GPR26 = thread->Registers.gpr26;
ctx->GPR27 = thread->Registers.gpr27;
ctx->GPR28 = thread->Registers.gpr28;
ctx->GPR29 = thread->Registers.gpr29;
ctx->GPR30 = thread->Registers.gpr30;
ctx->GPR31 = thread->Registers.gpr31;
ctx->EXC_CR = thread->Registers.cr;
ctx->EXC_CTR = 0xdeadbeef;
ctx->EXC_XER = 0xdeadbeef;
ctx->EXC_LR = 0xdeadbeef;
ctx->EXC_MSR = 0xdeadbeef;
ctx->EXC_DAR = 0xdeadbeef;
}
 
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
thread->Registers.gpr1 = ctx->GPR1;
thread->Registers.gpr2 = ctx->GPR2;
 
thread->Registers.gpr13 = ctx->GPR13;
thread->Registers.gpr14 = ctx->GPR14;
thread->Registers.gpr15 = ctx->GPR15;
thread->Registers.gpr16 = ctx->GPR16;
thread->Registers.gpr17 = ctx->GPR17;
thread->Registers.gpr18 = ctx->GPR18;
thread->Registers.gpr19 = ctx->GPR19;
thread->Registers.gpr20 = ctx->GPR20;
thread->Registers.gpr21 = ctx->GPR21;
thread->Registers.gpr22 = ctx->GPR22;
thread->Registers.gpr23 = ctx->GPR23;
thread->Registers.gpr24 = ctx->GPR24;
thread->Registers.gpr25 = ctx->GPR25;
thread->Registers.gpr26 = ctx->GPR26;
thread->Registers.gpr27 = ctx->GPR27;
thread->Registers.gpr28 = ctx->GPR28;
thread->Registers.gpr29 = ctx->GPR29;
thread->Registers.gpr30 = ctx->GPR30;
thread->Registers.gpr31 = ctx->GPR31;
thread->Registers.cr = ctx->EXC_CR;
thread->Registers.pc = ctx->EXC_SRR0;
thread->Registers.msr = ctx->EXC_SRR1;
}
 
 
int
Single_Step(CPU_Exception_frame* ctx)
{
if ((ctx->EXC_SRR1 & MSR_SE) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
assert ((ctx->EXC_SRR1 & MSR_SE) != 0);
assert (ExitForSingleStep != 0);
return 0;
}
ctx->EXC_SRR1 |= MSR_SE;
++ExitForSingleStep;
return 0;
}
 
int
CheckForSingleStep (CPU_Exception_frame* ctx)
{
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
 
void
CancelSingleStep (CPU_Exception_frame* ctx)
{
/* Cancel scheduled SS */
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
}
cpuExcHandlerType oldExcHandler;
 
void connect_rdbg_exception()
{
oldExcHandler = globalExceptHdl;
globalExceptHdl = BreakPointExcHdl ;
}
/powerpc/rdbg_cpu_asm.S
0,0 → 1,84
/* cpu_asm.s
*
* This file contains all assembly code for the Intel i386 implementation
* of RDBG.
*
* $Id: rdbg_cpu_asm.S,v 1.2 2001-09-27 12:02:02 chris Exp $
*
*/
 
#include <libcpu/cpu.h>
#include <libcpu/io.h>
#include <rtems/score/targopts.h>
#include <asm.h>
 
BEGIN_CODE
 
/*
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
*
* This routine performs a copy of the data cache
* and invalidate the instruction cache
*/
 
.p2align 5
PUBLIC_VAR (copyback_data_cache_and_invalidate_instr_cache)
 
SYM (copyback_data_cache_and_invalidate_instr_cache):
/* make sure the data changed is in the cache */
sync
/* r3 address to handle, r4 length in bytes */
addi r6, r0, PPC_CACHE_ALIGNMENT
/* r5 = last address to handle */
add r5,r3,r4
/* r3 = cache_align(r3, PPC_CACHE_ALIGNMENT) */
subi r0,r6,1
andc r3,r3,r0
/* R4 = R3 = copy of first address */
mr r4,r3
/*
* Copyback data cache
*/
1: cmplw r4,r5 /* r4 >= r5 then done */
dcbst 0,r4 /* flush (data cache bloc store) */
add r4,r4,r6 /* r4 = next cache line addr */
blt 1b /* end r4 >= r5 then done */
sync /* Wait for all dcbst to complete on bus */
/*
* invalidate instruction cache
*/
/* R4 = fisrt address */
mr r4,r3
2: cmplw r4,r5 /* r4 >= r5 then done */
icbi 0,r4 /* invalidate (instruction cache bloc invalidate) */
add r4,r4,r6 /* r4 = next cache line addr */
blt 2b /* end r4 >= r5 then done */
sync /* Wait for all icbi to complete on bus */
isync
blr
 
/*
* void enterRdbg(void)
*
* This function perform a call to the exception SYSTEM call
* It is used :
* 1 - in the user code, to simulate a Breakpoint.
* (with justSaveContext = 0)
* 2 - in the RDBG code, to push a ctx in the list.
* (with justSaveContext = 1)
*
* In most of case, it will be use as described in 1.
* The 2nd possibility will be used by RDBG to obtain
* its own ctx
*/
 
PUBLIC_VAR (enterRdbg)
 
SYM (enterRdbg):
sc
blr
END_CODE
 
END
/powerpc/Makefile.am
0,0 → 1,12
##
## $Id: Makefile.am,v 1.2 2001-09-27 12:02:02 chris Exp $
##
 
AUTOMAKE_OPTIONS = foreign 1.4
 
SUBDIRS = mcp750
 
EXTRA_DIST = excep_f.c rdbg_cpu_asm.S rdbg_f.c
 
include $(top_srcdir)/../../../automake/subdirs.am
include $(top_srcdir)/../../../automake/local.am
/powerpc/excep_f.c
0,0 → 1,167
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/powerpc/excep_f.c
*
* $Id: excep_f.c,v 1.2 2001-09-27 12:02:02 chris Exp $
*
**************************************************************************
*/
 
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
 
int
ExcepToSig (Exception_context *ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case ASM_FLOAT_VECTOR : return SIGFPE;
case ASM_TRACE_VECTOR :
case ASM_PROG_VECTOR :
case ASM_SYS_VECTOR : return SIGTRAP;
case ASM_ISI_VECTOR : return SIGSEGV;
case ASM_RESET_VECTOR :
case ASM_MACH_VECTOR :
case ASM_EXT_VECTOR :
case ASM_ALIGN_VECTOR : return SIGILL;
default:
break;
}
return SIGKILL;
}
 
/*----- Breakpoint Exception management -----*/
 
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
 
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
 
if ( (justSaveContext) && (ctx->_EXC_number == ASM_SYS_VECTOR) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->_EXC_number != ASM_TRACE_VECTOR){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
 
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->_EXC_number,
ctx->EXC_SRR0,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk("\t R0 = %x\n", ctx->GPR0);
printk("\t R1 = %x\n", ctx->GPR1);
printk("\t R2 = %x\n", ctx->GPR2);
printk("\t R3 = %x\n", ctx->GPR3);
printk("\t R4 = %x\n", ctx->GPR4);
printk("\t R5 = %x\n", ctx->GPR5);
printk("\t R6 = %x\n", ctx->GPR6);
printk("\t R7 = %x\n", ctx->GPR7);
printk("\t R8 = %x\n", ctx->GPR8);
printk("\t R9 = %x\n", ctx->GPR9);
printk("\t R10 = %x\n", ctx->GPR10);
printk("\t R11 = %x\n", ctx->GPR11);
printk("\t R12 = %x\n", ctx->GPR12);
printk("\t R13 = %x\n", ctx->GPR13);
printk("\t R14 = %x\n", ctx->GPR14);
printk("\t R15 = %x\n", ctx->GPR15);
printk("\t R16 = %x\n", ctx->GPR16);
printk("\t R17 = %x\n", ctx->GPR17);
printk("\t R18 = %x\n", ctx->GPR18);
printk("\t R19 = %x\n", ctx->GPR19);
printk("\t R20 = %x\n", ctx->GPR20);
printk("\t R21 = %x\n", ctx->GPR21);
printk("\t R22 = %x\n", ctx->GPR22);
printk("\t R23 = %x\n", ctx->GPR23);
printk("\t R24 = %x\n", ctx->GPR24);
printk("\t R25 = %x\n", ctx->GPR25);
printk("\t R26 = %x\n", ctx->GPR26);
printk("\t R27 = %x\n", ctx->GPR27);
printk("\t R28 = %x\n", ctx->GPR28);
printk("\t R29 = %x\n", ctx->GPR29);
printk("\t R30 = %x\n", ctx->GPR30);
printk("\t R31 = %x\n", ctx->GPR31);
printk("\t CR = %x\n", ctx->EXC_CR);
printk("\t CTR = %x\n", ctx->EXC_CTR);
printk("\t XER = %x\n", ctx->EXC_XER);
printk("\t LR = %x\n", ctx->EXC_LR);
printk("\t MSR = %x\n", ctx->EXC_MSR);
#endif
 
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
 
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->_EXC_number){
case ASM_TRACE_VECTOR :
DPRINTF((" TRACE EXCEPTION !!!\n"));
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
 
case ASM_PROG_VECTOR :
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
 
case ASM_SYS_VECTOR :
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
 
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
 
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
 
}
 
 
 
/powerpc/mcp750/remdeb.h
0,0 → 1,581
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
 
#ifndef _REMDEB_H_RPCGEN
#define _REMDEB_H_RPCGEN
 
#include <rpc/rpc.h>
 
 
#ifdef __cplusplus
extern "C" {
#endif
 
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
#ifndef REMDEB_H
#define RPCGENSRVNAME(a) a
 
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25,
};
typedef enum rpc_type rpc_type;
#define NET_SAFE 1400
 
struct UDP_MSG {
u_char type;
u_char msg_num;
u_short spec;
long pid;
u_long context;
};
typedef struct UDP_MSG UDP_MSG;
/*
* Sun request values for the remote ptrace system call
*/
 
 
enum ptracereq {
RPT_TRACEME = 0,
RPT_CHILDDONE = 0,
RPT_PEEKTEXT = 0 + 1,
RPT_PEEKDATA = 0 + 2,
RPT_PEEKUSER = 0 + 3,
RPT_POKETEXT = 0 + 4,
RPT_POKEDATA = 0 + 5,
RPT_POKEUSER = 0 + 6,
RPT_CONT = 0 + 7,
RPT_KILL = 0 + 8,
RPT_SINGLESTEP = 0 + 9,
RPT_ATTACH = 0 + 10,
RPT_DETACH = 0 + 11,
RPT_GETREGS = 0 + 12,
RPT_SETREGS = 0 + 13,
RPT_GETFPREGS = 0 + 14,
RPT_SETFPREGS = 0 + 15,
RPT_READDATA = 0 + 16,
RPT_WRITEDATA = 0 + 17,
RPT_READTEXT = 0 + 18,
RPT_WRITETEXT = 0 + 19,
RPT_GETFPAREGS = 0 + 20,
RPT_SETFPAREGS = 0 + 21,
RPT_22 = 0 + 22,
RPT_23 = 0 + 23,
RPT_SYSCALL = 0 + 24,
RPT_DUMPCORE = 0 + 25,
RPT_26 = 0 + 26,
RPT_27 = 0 + 27,
RPT_28 = 0 + 28,
RPT_GETUCODE = 0 + 29,
RPT_GETTARGETTHREAD = 50,
RPT_SETTARGETTHREAD = 51,
RPT_THREADSUSPEND = 52,
RPT_THREADRESUME = 53,
RPT_THREADLIST = 54,
RPT_GETTHREADNAME = 55,
RPT_SETTHREADNAME = 56,
RPT_SETTHREADREGS = 57,
RPT_GETTHREADREGS = 58,
RPT_STEPRANGE = 75,
RPT_CONTTO = 76,
RPT_SETBREAK = 77,
RPT_CLRBREAK = 78,
RPT_GETBREAK = 79,
RPT_GETNAME = 80,
RPT_STOP = 81,
RPT_PGETREGS = 82,
RPT_PSETREGS = 83,
RPT_PSETTHREADREGS = 84,
RPT_PGETTHREADREGS = 85,
};
typedef enum ptracereq ptracereq;
 
struct xdr_regs {
u_int tabreg[40];
};
typedef struct xdr_regs xdr_regs;
/* now define register macros to apply to xdr_regs struct */
 
#define R_PC 0
#define R_MSR 1
#define R_EXCEPNB 2
#define R_R0 3
#define R_R1 (R_R0 + 1)
#define R_R2 (R_R0 + 2)
#define R_R3 (R_R0 + 3)
#define R_R4 (R_R0 + 4)
#define R_R5 (R_R0 + 5)
#define R_R6 (R_R0 + 6)
#define R_R7 (R_R0 + 7)
#define R_R8 (R_R0 + 8)
#define R_R9 (R_R0 + 9)
#define R_R10 (R_R0 + 10)
#define R_R11 (R_R0 + 11)
#define R_R12 (R_R0 + 12)
#define R_R13 (R_R0 + 13)
#define R_R14 (R_R0 + 14)
#define R_R15 (R_R0 + 15)
#define R_R16 (R_R0 + 16)
#define R_R17 (R_R0 + 17)
#define R_R18 (R_R0 + 18)
#define R_R19 (R_R0 + 19)
#define R_R20 (R_R0 + 20)
#define R_R21 (R_R0 + 21)
#define R_R22 (R_R0 + 22)
#define R_R23 (R_R0 + 23)
#define R_R24 (R_R0 + 24)
#define R_R25 (R_R0 + 25)
#define R_R26 (R_R0 + 26)
#define R_R27 (R_R0 + 27)
#define R_R28 (R_R0 + 28)
#define R_R29 (R_R0 + 29)
#define R_R30 (R_R0 + 30)
#define R_R31 (R_R0 + 31)
#define R_CR 35
#define R_CTR 36
#define R_XER 37
#define R_LR 38
#define R_MQ 39
 
#include <libcpu/raw_exception.h>
 
#define REG_PC tabreg[R_PC] /* PC register offset */
#define REG_SP tabreg[R_R1] /* SP register offset */
#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
#define IS_BREAK(l) ((l) == 0x7d8d6808)
#define SET_BREAK(l) (0x7d8d6808)
#define ORG_BREAK(c,p) (p)
#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
#define TARGET_PROC_TYPE 3
#define MAXDEBUGGEE 150
#define NAMEMAX 17
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
#define MEM_DATA_MAX 256
 
struct xdr_mem {
u_long addr;
u_int dataNb;
u_char data[MEM_DATA_MAX];
};
typedef struct xdr_mem xdr_mem;
 
enum break_type {
BRKT_NONE = 0,
BRKT_INSTR = 1,
BRKT_READ = 2,
BRKT_WRITE = 3,
BRKT_ACCESS = 4,
BRKT_EXEC = 5,
BRKT_OS_CALL = 6,
BRKT_OS_SWITCH = 7,
BRKT_STEPEMUL = 8,
};
typedef enum break_type break_type;
#define MAX_THRD_BRK 4
 
struct xdr_break {
u_char type;
u_char thread_spec;
u_short handle;
u_long ee_loc;
u_long ee_type;
u_short length;
u_char pass_count;
u_char curr_pass;
u_long thread_list[MAX_THRD_BRK];
};
typedef struct xdr_break xdr_break;
#define UTHREAD_MAX 64
#define THREADNAMEMAX 16
 
typedef char *thread_name;
 
struct KernThread {
u_int threadLi;
};
typedef struct KernThread KernThread;
typedef KernThread *ptThreadList;
 
struct thread_list {
u_int nbThread;
ptThreadList threads;
};
typedef struct thread_list thread_list;
 
struct ptrace_addr_data_in {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int address;
} ptrace_addr_data_in_u;
};
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
 
struct ptrace_addr_data_out {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_list threads;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int addr;
} ptrace_addr_data_out_u;
};
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
 
typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
#define XRY_MAX_INST_BUFF 128
#define XRY_MAX_INSTANCES 16
#ifndef XRY_MAX_CMD_STR
#define XRY_MAX_CMD_STR 320
#endif /* REMDEB_H */
 
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
 
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
 
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
 
typedef char *one_arg;
#define XRY_MAX_OBJ_NAME 32
/* now open_connex() routine which establishes a connection to server */
 
enum debug_type {
DEBTYP_PROCESS = 0,
DEBTYP_C_ACTOR = 1,
DEBTYP_KERNEL = 2,
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
 
struct open_in {
u_char back_port[16];
u_short debug_type;
u_short flags;
u_char destination[16];
one_arg user_name;
};
typedef struct open_in open_in;
 
struct open_out {
u_long port;
u_int pad[4];
u_int fp;
u_char cmd_table_num;
u_char cmd_table_vers;
u_short server_vers;
};
typedef struct open_out open_out;
/* now close_connex() routine which detaches from server */
 
enum close_control {
CLOSE_IGNORE = 0,
CLOSE_KILL = 1,
CLOSE_DETACH = 2,
};
typedef enum close_control close_control;
 
struct close_in {
close_control control;
};
typedef struct close_in close_in;
/* now send_signal() routine which sends signals to processes like kill(2) */
 
struct signal_in {
int pid;
int sig;
};
typedef struct signal_in signal_in;
 
struct signal_out {
int kill_return;
int errNo;
};
typedef struct signal_out signal_out;
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
 
enum stop_code {
STOP_ERROR = 0,
STOP_NONE = 1,
STOP_UNKNOWN = 2,
STOP_BREAK = 3,
STOP_STEP = 4,
STOP_SIGNAL = 5,
STOP_TERM_EXIT = 6,
STOP_TERM_SIG = 7,
STOP_DETACHED = 8,
STOP_KILLED = 9,
STOP_SPAWN_FAILED = 10,
};
typedef enum stop_code stop_code;
 
struct wait_in {
int pid;
};
typedef struct wait_in wait_in;
 
struct wait_out {
int wait_return;
int errNo;
int status;
stop_code reason;
int handle;
u_long PC;
u_long SP;
u_long FP;
u_long thread;
};
typedef struct wait_out wait_out;
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
#define PTRFLG_FORCE 1
#define PTRFLG_NON_OWNER 2
#define PTRFLG_FREE 4
#define PTRDET_UNOWN 0x100
 
struct ptrace_in {
int pid;
ptrace_addr_data_in addr;
u_int data;
u_int flags;
};
typedef struct ptrace_in ptrace_in;
 
struct ptrace_out {
ptrace_addr_data_out addr;
int result;
int errNo;
};
typedef struct ptrace_out ptrace_out;
 
struct one_symbol {
char *symbolName;
long symbolValue;
};
typedef struct one_symbol one_symbol;
 
typedef struct {
u_int all_symbols_len;
one_symbol *all_symbols_val;
} all_symbols;
 
struct get_global_symbols_out {
all_symbols symbols;
};
typedef struct get_global_symbols_out get_global_symbols_out;
 
struct get_text_data_in {
int pid;
char *actorName;
};
typedef struct get_text_data_in get_text_data_in;
 
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
typedef struct get_text_data_out get_text_data_out;
 
struct one_signal {
u_int number;
char *name;
};
typedef struct one_signal one_signal;
 
typedef struct {
u_int all_signals_len;
one_signal *all_signals_val;
} all_signals;
 
struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/* now define the actual calls we support */
#define REMDEB_H
#endif
 
#define REMOTEDEB 0x20000fff
#define REMOTEVERS 2
 
#if defined(__STDC__) || defined(__cplusplus)
#define OPEN_CONNEX 1
extern open_out * open_connex_2(open_in *, CLIENT *);
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
#define SEND_SIGNAL 2
extern signal_out * send_signal_2(signal_in *, CLIENT *);
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
#define CLOSE_CONNEX 10
extern void * close_connex_2(close_in *, CLIENT *);
extern void * close_connex_2_svc(close_in *, struct svc_req *);
#define PTRACE 11
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
#define WAIT_INFO 13
extern wait_out * wait_info_2(wait_in *, CLIENT *);
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
 
#else /* K&R C */
#define OPEN_CONNEX 1
extern open_out * open_connex_2();
extern open_out * open_connex_2_svc();
#define SEND_SIGNAL 2
extern signal_out * send_signal_2();
extern signal_out * send_signal_2_svc();
#define CLOSE_CONNEX 10
extern void * close_connex_2();
extern void * close_connex_2_svc();
#define PTRACE 11
extern ptrace_out * ptrace_2();
extern ptrace_out * ptrace_2_svc();
#define WAIT_INFO 13
extern wait_out * wait_info_2();
extern wait_out * wait_info_2_svc();
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2();
extern get_signal_names_out * get_signal_names_2_svc();
extern int remotedeb_2_freeresult ();
#endif /* K&R C */
 
/* the xdr functions */
 
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
extern bool_t xdr_break_type (XDR *, break_type*);
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
extern bool_t xdr_thread_name (XDR *, thread_name*);
extern bool_t xdr_KernThread (XDR *, KernThread*);
extern bool_t xdr_thread_list (XDR *, thread_list*);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
extern bool_t xdr_xry_inst (XDR *, xry_inst*);
extern bool_t xdr_instance (XDR *, instance*);
extern bool_t xdr_instance_union (XDR *, instance_union*);
extern bool_t xdr_one_arg (XDR *, one_arg*);
extern bool_t xdr_debug_type (XDR *, debug_type*);
extern bool_t xdr_open_in (XDR *, open_in*);
extern bool_t xdr_open_out (XDR *, open_out*);
extern bool_t xdr_close_control (XDR *, close_control*);
extern bool_t xdr_close_in (XDR *, close_in*);
extern bool_t xdr_signal_in (XDR *, signal_in*);
extern bool_t xdr_signal_out (XDR *, signal_out*);
extern bool_t xdr_stop_code (XDR *, stop_code*);
extern bool_t xdr_wait_in (XDR *, wait_in*);
extern bool_t xdr_wait_out (XDR *, wait_out*);
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
extern bool_t xdr_one_signal (XDR *, one_signal*);
extern bool_t xdr_all_signals (XDR *, all_signals*);
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
 
#else /* K&R C */
extern bool_t xdr_rpc_type ();
extern bool_t xdr_UDP_MSG ();
extern bool_t xdr_ptracereq ();
extern bool_t xdr_xdr_regs ();
extern bool_t xdr_xdr_mem ();
extern bool_t xdr_break_type ();
extern bool_t xdr_xdr_break ();
extern bool_t xdr_thread_name ();
extern bool_t xdr_KernThread ();
extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();
extern bool_t xdr_open_out ();
extern bool_t xdr_close_control ();
extern bool_t xdr_close_in ();
extern bool_t xdr_signal_in ();
extern bool_t xdr_signal_out ();
extern bool_t xdr_stop_code ();
extern bool_t xdr_wait_in ();
extern bool_t xdr_wait_out ();
extern bool_t xdr_ptrace_in ();
extern bool_t xdr_ptrace_out ();
extern bool_t xdr_one_symbol ();
extern bool_t xdr_all_symbols ();
extern bool_t xdr_get_global_symbols_out ();
extern bool_t xdr_get_text_data_in ();
extern bool_t xdr_get_text_data_out ();
extern bool_t xdr_one_signal ();
extern bool_t xdr_all_signals ();
extern bool_t xdr_get_signal_names_out ();
 
#endif /* K&R C */
 
#ifdef __cplusplus
}
#endif
 
#endif /* !_REMDEB_H_RPCGEN */
/powerpc/mcp750/Makefile.am
0,0 → 1,90
##
## $Id: Makefile.am,v 1.2 2001-09-27 12:02:02 chris Exp $
##
 
AUTOMAKE_OPTIONS = foreign 1.4
 
VPATH = @srcdir@:@srcdir@/..:@srcdir@/../..
 
LIBNAME = librdbg
LIB = ${ARCH}/${LIBNAME}.a
 
# C and C++ source names
C_FILES = rdbg.c servcon.c servbkpt.c servrpc.c excep.c excep_f.c servtgt.c \
servtsp.c servutil.c _servtgt.c rdbg_f.c ptrace.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
 
# Asm source names
S_FILES = rdbg_cpu_asm.S
S_O_FILES = $(S_FILES:%.S=${ARCH}/%.o)
 
# Generated C source names
GEN_C_FILES = remdeb_xdr.c remdeb_svc.c
GEN_C_O_FILES = $(GEN_C_FILES:%.c=${ARCH}/%.o)
 
# H source names
H_FILES = remdeb.h
 
# X source names
X_FILES = remdeb.x remdeb_f.x
 
OBJS = $(GEN_C_O_FILES) $(C_O_FILES) $(S_O_FILES)
 
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/lib.am
 
#
# Add local stuff here using +=
#
 
MAINTAINERCLEANFILES += $(H_FILES) $(GEN_C_FILES)
 
FRONTEND = \"$(RTEMS_CPU)/mcp750/remdeb_f.x\"
 
$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB)
$(INSTALL_DATA) $< $@
 
$(LIB): ${OBJS}
$(make-library)
 
$(srcdir)/remdeb.h: $(X_FILES)
if RPCTOOLS
@rm -f $@
( cd $(top_srcdir)/src; \
$(RPCGEN) -h -DFRONTEND=$(FRONTEND) \
-o powerpc/mcp750/remdeb.h remdeb.x )
endif
$(srcdir)/remdeb_xdr.c: $(X_FILES)
if RPCTOOLS
@rm -f $@
( cd $(top_srcdir)/src; \
$(RPCGEN) -c -DFRONTEND=$(FRONTEND) \
-o powerpc/mcp750/remdeb_xdr.c remdeb.x )
endif
 
$(srcdir)/remdeb_svc.c: $(X_FILES)
if RPCTOOLS
@rm -f $@ tmpSvc.c
( cd $(top_srcdir)/src; \
$(RPCGEN) -m -DFRONTEND=$(FRONTEND) \
-o powerpc/mcp750/tmpSvc.c remdeb.x; \
$(AWK) -f ./awk.svc THEPROG="remdeb.h" powerpc/mcp750/tmpSvc.c \
> powerpc/mcp750/remdeb_svc.c; \
rm -f powerpc/mcp750/tmpSvc.c )
endif
 
$(PROJECT_INCLUDE)/rdbg/remdeb.h: $(srcdir)/remdeb.h
$(INSTALL_DATA) $< $@
 
$(PROJECT_INCLUDE)/rdbg:
@$(mkinstalldirs) $@
 
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg $(PROJECT_INCLUDE)/rdbg/remdeb.h
 
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a
 
all-local: ${ARCH} $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
 
EXTRA_DIST = remdeb_f.x $(GEN_C_FILES)
 
include $(top_srcdir)/../../../automake/local.am
/powerpc/mcp750/remdeb_f.x
0,0 → 1,76
/*
**************************************************************************
*
* Component = rdblib
* Synopsis = remdeb_f.x
*
**************************************************************************
* $Id: remdeb_f.x,v 1.2 2001-09-27 12:02:02 chris Exp $
**************************************************************************
*/
 
struct xdr_regs
{
unsigned int tabreg[40];
};
 
#ifdef RPC_HDR
 
%/* now define register macros to apply to xdr_regs struct */
%
%#define R_PC 0
%#define R_MSR 1
%#define R_EXCEPNB 2
%#define R_R0 3
%#define R_R1 (R_R0 + 1)
%#define R_R2 (R_R0 + 2)
%#define R_R3 (R_R0 + 3)
%#define R_R4 (R_R0 + 4)
%#define R_R5 (R_R0 + 5)
%#define R_R6 (R_R0 + 6)
%#define R_R7 (R_R0 + 7)
%#define R_R8 (R_R0 + 8)
%#define R_R9 (R_R0 + 9)
%#define R_R10 (R_R0 + 10)
%#define R_R11 (R_R0 + 11)
%#define R_R12 (R_R0 + 12)
%#define R_R13 (R_R0 + 13)
%#define R_R14 (R_R0 + 14)
%#define R_R15 (R_R0 + 15)
%#define R_R16 (R_R0 + 16)
%#define R_R17 (R_R0 + 17)
%#define R_R18 (R_R0 + 18)
%#define R_R19 (R_R0 + 19)
%#define R_R20 (R_R0 + 20)
%#define R_R21 (R_R0 + 21)
%#define R_R22 (R_R0 + 22)
%#define R_R23 (R_R0 + 23)
%#define R_R24 (R_R0 + 24)
%#define R_R25 (R_R0 + 25)
%#define R_R26 (R_R0 + 26)
%#define R_R27 (R_R0 + 27)
%#define R_R28 (R_R0 + 28)
%#define R_R29 (R_R0 + 29)
%#define R_R30 (R_R0 + 30)
%#define R_R31 (R_R0 + 31)
%#define R_CR 35
%#define R_CTR 36
%#define R_XER 37
%#define R_LR 38
%#define R_MQ 39
%
%#include <libcpu/raw_exception.h>
%
%#define REG_PC tabreg[R_PC] /* PC register offset */
%#define REG_SP tabreg[R_R1] /* SP register offset */
%#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
%#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
%#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
%#define IS_BREAK(l) ((l) == 0x7d8d6808)
%#define SET_BREAK(l) (0x7d8d6808)
%#define ORG_BREAK(c,p) (p)
%#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
%#define TARGET_PROC_TYPE 3
 
#endif
 
/powerpc/mcp750/remdeb_svc.c
0,0 → 1,122
#include <rpc/types.h>
#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bsp.h>
#include <rdbg/servrpc.h>
#include <rdbg/remdeb.h>
#define fprintf(a,b) printf(b)
/*HEADER_START*/
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
/*
* Sun request values for the remote ptrace system call
*/
 
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
/* now open_connex() routine which establishes a connection to server */
#define DEBUGGER_IS_GDB 0x2 /* */
/* now close_connex() routine which detaches from server */
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now define the actual calls we support */
const char* names [] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
};
 
void
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
open_in open_connex_2_arg;
signal_in send_signal_2_arg;
close_in close_connex_2_arg;
ptrace_in ptrace_2_arg;
wait_in wait_info_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
 
DPRINTF (("remotedeb_2: %s (%d)\n",
(unsigned) rqstp->rq_proc <
(unsigned) (sizeof names / sizeof names[0]) ?
names [rqstp->rq_proc] : "???",
(int) rqstp->rq_proc));
 
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
 
case OPEN_CONNEX:
_xdr_argument = (xdrproc_t) xdr_open_in;
_xdr_result = (xdrproc_t) xdr_open_out;
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
break;
 
case SEND_SIGNAL:
_xdr_argument = (xdrproc_t) xdr_signal_in;
_xdr_result = (xdrproc_t) xdr_signal_out;
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
break;
 
case CLOSE_CONNEX:
_xdr_argument = (xdrproc_t) xdr_close_in;
_xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
break;
 
case PTRACE:
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
_xdr_result = (xdrproc_t) xdr_ptrace_out;
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
break;
 
case WAIT_INFO:
_xdr_argument = (xdrproc_t) xdr_wait_in;
_xdr_result = (xdrproc_t) xdr_wait_out;
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
break;
 
case GET_SIGNAL_NAMES:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
break;
 
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
return;
}
/powerpc/mcp750/remdeb_xdr.c
0,0 → 1,928
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
 
#include "remdeb.h"
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
 
bool_t
xdr_rpc_type (XDR *xdrs, rpc_type *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_UDP_MSG (XDR *xdrs, UDP_MSG *objp)
{
register int32_t *buf;
 
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->msg_num))
return FALSE;
if (!xdr_u_short (xdrs, &objp->spec))
return FALSE;
if (!xdr_long (xdrs, &objp->pid))
return FALSE;
if (!xdr_u_long (xdrs, &objp->context))
return FALSE;
return TRUE;
}
/*
* Sun request values for the remote ptrace system call
*/
 
 
bool_t
xdr_ptracereq (XDR *xdrs, ptracereq *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
{
register int32_t *buf;
 
int i;
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE(xdrs, 40 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->tabreg, 40,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
} else {
{
register u_int *genp;
 
for (i = 0, genp = objp->tabreg;
i < 40; ++i) {
IXDR_PUT_U_LONG(buf, *genp++);
}
}
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs, 40 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->tabreg, 40,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
} else {
{
register u_int *genp;
 
for (i = 0, genp = objp->tabreg;
i < 40; ++i) {
*genp++ = IXDR_GET_U_LONG(buf);
}
}
}
return TRUE;
}
 
if (!xdr_vector (xdrs, (char *)objp->tabreg, 40,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
return TRUE;
}
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
bool_t xdr_xdr_mem(xdrs, objp)
XDR *xdrs;
struct xdr_mem *objp;
{
if (!xdr_u_long(xdrs, &objp->addr)) {
return (FALSE);
}
if (!xdr_u_int(xdrs, &objp->dataNb)) {
return(FALSE);
}
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
}
 
bool_t
xdr_break_type (XDR *xdrs, break_type *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_xdr_break (XDR *xdrs, xdr_break *objp)
{
register int32_t *buf;
 
int i;
 
if (xdrs->x_op == XDR_ENCODE) {
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->thread_spec))
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_short (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_loc))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->length))
return FALSE;
 
} else {
IXDR_PUT_U_SHORT(buf, objp->handle);
IXDR_PUT_U_LONG(buf, objp->ee_loc);
IXDR_PUT_U_LONG(buf, objp->ee_type);
IXDR_PUT_U_SHORT(buf, objp->length);
}
if (!xdr_u_char (xdrs, &objp->pass_count))
return FALSE;
if (!xdr_u_char (xdrs, &objp->curr_pass))
return FALSE;
buf = XDR_INLINE(xdrs, MAX_THRD_BRK * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
sizeof (u_long), (xdrproc_t) xdr_u_long))
return FALSE;
} else {
{
register u_long *genp;
 
for (i = 0, genp = objp->thread_list;
i < MAX_THRD_BRK; ++i) {
IXDR_PUT_U_LONG(buf, *genp++);
}
}
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->thread_spec))
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_short (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_loc))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->length))
return FALSE;
 
} else {
objp->handle = IXDR_GET_U_SHORT(buf);
objp->ee_loc = IXDR_GET_U_LONG(buf);
objp->ee_type = IXDR_GET_U_LONG(buf);
objp->length = IXDR_GET_U_SHORT(buf);
}
if (!xdr_u_char (xdrs, &objp->pass_count))
return FALSE;
if (!xdr_u_char (xdrs, &objp->curr_pass))
return FALSE;
buf = XDR_INLINE(xdrs, MAX_THRD_BRK * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
sizeof (u_long), (xdrproc_t) xdr_u_long))
return FALSE;
} else {
{
register u_long *genp;
 
for (i = 0, genp = objp->thread_list;
i < MAX_THRD_BRK; ++i) {
*genp++ = IXDR_GET_U_LONG(buf);
}
}
}
return TRUE;
}
 
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->thread_spec))
return FALSE;
if (!xdr_u_short (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_loc))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->length))
return FALSE;
if (!xdr_u_char (xdrs, &objp->pass_count))
return FALSE;
if (!xdr_u_char (xdrs, &objp->curr_pass))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
sizeof (u_long), (xdrproc_t) xdr_u_long))
return FALSE;
return TRUE;
}
 
bool_t
xdr_thread_name (XDR *xdrs, thread_name *objp)
{
register int32_t *buf;
 
if (!xdr_string (xdrs, objp, THREADNAMEMAX))
return FALSE;
return TRUE;
}
 
bool_t
xdr_KernThread (XDR *xdrs, KernThread *objp)
{
register int32_t *buf;
 
if (!xdr_u_int (xdrs, &objp->threadLi))
return FALSE;
return TRUE;
}
bool_t xdr_thread_list(xdrs, objp)
XDR *xdrs;
struct thread_list *objp;
{
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
}
 
bool_t
xdr_ptrace_addr_data_in (XDR *xdrs, ptrace_addr_data_in *objp)
{
register int32_t *buf;
 
if (!xdr_ptracereq (xdrs, &objp->req))
return FALSE;
switch (objp->req) {
case RPT_SETTHREADREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
return FALSE;
break;
case RPT_SETREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
return FALSE;
break;
case RPT_PSETTHREADREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_PSETREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_SETTHREADNAME:
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_in_u.name))
return FALSE;
break;
case RPT_WRITETEXT:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
return FALSE;
break;
case RPT_WRITEDATA:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
return FALSE;
break;
case RPT_SETBREAK:
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_in_u.breakp))
return FALSE;
break;
default:
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_in_u.address))
return FALSE;
break;
}
return TRUE;
}
 
bool_t
xdr_ptrace_addr_data_out (XDR *xdrs, ptrace_addr_data_out *objp)
{
register int32_t *buf;
 
if (!xdr_ptracereq (xdrs, &objp->req))
return FALSE;
switch (objp->req) {
case RPT_GETREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
return FALSE;
break;
case RPT_GETTHREADREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
return FALSE;
break;
case RPT_PGETREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_PGETTHREADREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_THREADLIST:
if (!xdr_thread_list (xdrs, &objp->ptrace_addr_data_out_u.threads))
return FALSE;
break;
case RPT_GETTHREADNAME:
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_out_u.name))
return FALSE;
break;
case RPT_READTEXT:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
return FALSE;
break;
case RPT_GETNAME:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
return FALSE;
break;
case RPT_READDATA:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
return FALSE;
break;
case RPT_GETBREAK:
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_out_u.breakp))
return FALSE;
break;
default:
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_out_u.addr))
return FALSE;
break;
}
return TRUE;
}
 
bool_t
xdr_CHAR_DATA (XDR *xdrs, CHAR_DATA *objp)
{
register int32_t *buf;
 
if (!xdr_bytes (xdrs, (char **)&objp->CHAR_DATA_val, (u_int *) &objp->CHAR_DATA_len, NET_SAFE))
return FALSE;
return TRUE;
}
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
 
bool_t
xdr_xry_inst (XDR *xdrs, xry_inst *objp)
{
register int32_t *buf;
 
if (!xdr_u_char (xdrs, &objp->flags))
return FALSE;
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->sub_type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->res_type))
return FALSE;
if (!xdr_u_long (xdrs, &objp->value))
return FALSE;
if (!xdr_u_long (xdrs, &objp->value2))
return FALSE;
return TRUE;
}
 
bool_t
xdr_instance (XDR *xdrs, instance *objp)
{
register int32_t *buf;
 
int i;
if (!xdr_vector (xdrs, (char *)objp->instances, XRY_MAX_INSTANCES,
sizeof (xry_inst), (xdrproc_t) xdr_xry_inst))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->buffer, XRY_MAX_INST_BUFF,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
return TRUE;
}
 
bool_t
xdr_instance_union (XDR *xdrs, instance_union *objp)
{
register int32_t *buf;
 
if (!xdr_bool (xdrs, &objp->instances))
return FALSE;
switch (objp->instances) {
case TRUE:
if (!xdr_instance (xdrs, &objp->instance_union_u.inst))
return FALSE;
break;
case FALSE:
if (!xdr_string (xdrs, &objp->instance_union_u.buffer, XRY_MAX_CMD_STR))
return FALSE;
break;
default:
return FALSE;
}
return TRUE;
}
 
bool_t
xdr_one_arg (XDR *xdrs, one_arg *objp)
{
register int32_t *buf;
 
if (!xdr_string (xdrs, objp, NET_SAFE))
return FALSE;
return TRUE;
}
/* now open_connex() routine which establishes a connection to server */
 
bool_t
xdr_debug_type (XDR *xdrs, debug_type *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
#define DEBUGGER_IS_GDB 0x2 /* */
 
bool_t
xdr_open_in (XDR *xdrs, open_in *objp)
{
register int32_t *buf;
 
int i;
if (!xdr_vector (xdrs, (char *)objp->back_port, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
if (!xdr_u_short (xdrs, &objp->debug_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->flags))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->destination, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
if (!xdr_one_arg (xdrs, &objp->user_name))
return FALSE;
return TRUE;
}
 
bool_t
xdr_open_out (XDR *xdrs, open_out *objp)
{
register int32_t *buf;
 
int i;
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE(xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_long (xdrs, &objp->port))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
if (!xdr_u_int (xdrs, &objp->fp))
return FALSE;
 
} else {
IXDR_PUT_U_LONG(buf, objp->port);
{
register u_int *genp;
 
for (i = 0, genp = objp->pad;
i < 4; ++i) {
IXDR_PUT_U_LONG(buf, *genp++);
}
}
IXDR_PUT_U_LONG(buf, objp->fp);
}
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
return FALSE;
if (!xdr_u_short (xdrs, &objp->server_vers))
return FALSE;
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_long (xdrs, &objp->port))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
if (!xdr_u_int (xdrs, &objp->fp))
return FALSE;
 
} else {
objp->port = IXDR_GET_U_LONG(buf);
{
register u_int *genp;
 
for (i = 0, genp = objp->pad;
i < 4; ++i) {
*genp++ = IXDR_GET_U_LONG(buf);
}
}
objp->fp = IXDR_GET_U_LONG(buf);
}
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
return FALSE;
if (!xdr_u_short (xdrs, &objp->server_vers))
return FALSE;
return TRUE;
}
 
if (!xdr_u_long (xdrs, &objp->port))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
if (!xdr_u_int (xdrs, &objp->fp))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
return FALSE;
if (!xdr_u_short (xdrs, &objp->server_vers))
return FALSE;
return TRUE;
}
/* now close_connex() routine which detaches from server */
 
bool_t
xdr_close_control (XDR *xdrs, close_control *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_close_in (XDR *xdrs, close_in *objp)
{
register int32_t *buf;
 
if (!xdr_close_control (xdrs, &objp->control))
return FALSE;
return TRUE;
}
/* now send_signal() routine which sends signals to processes like kill(2) */
 
bool_t
xdr_signal_in (XDR *xdrs, signal_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
if (!xdr_int (xdrs, &objp->sig))
return FALSE;
return TRUE;
}
 
bool_t
xdr_signal_out (XDR *xdrs, signal_out *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->kill_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
return TRUE;
}
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
 
bool_t
xdr_stop_code (XDR *xdrs, stop_code *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_wait_in (XDR *xdrs, wait_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
return TRUE;
}
 
bool_t
xdr_wait_out (XDR *xdrs, wait_out *objp)
{
register int32_t *buf;
 
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->wait_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_int (xdrs, &objp->status))
return FALSE;
 
} else {
IXDR_PUT_LONG(buf, objp->wait_return);
IXDR_PUT_LONG(buf, objp->errNo);
IXDR_PUT_LONG(buf, objp->status);
}
if (!xdr_stop_code (xdrs, &objp->reason))
return FALSE;
buf = XDR_INLINE(xdrs,5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->PC))
return FALSE;
if (!xdr_u_long (xdrs, &objp->SP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->FP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->thread))
return FALSE;
} else {
IXDR_PUT_LONG(buf, objp->handle);
IXDR_PUT_U_LONG(buf, objp->PC);
IXDR_PUT_U_LONG(buf, objp->SP);
IXDR_PUT_U_LONG(buf, objp->FP);
IXDR_PUT_U_LONG(buf, objp->thread);
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->wait_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_int (xdrs, &objp->status))
return FALSE;
 
} else {
objp->wait_return = IXDR_GET_LONG(buf);
objp->errNo = IXDR_GET_LONG(buf);
objp->status = IXDR_GET_LONG(buf);
}
if (!xdr_stop_code (xdrs, &objp->reason))
return FALSE;
buf = XDR_INLINE(xdrs,5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->PC))
return FALSE;
if (!xdr_u_long (xdrs, &objp->SP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->FP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->thread))
return FALSE;
} else {
objp->handle = IXDR_GET_LONG(buf);
objp->PC = IXDR_GET_U_LONG(buf);
objp->SP = IXDR_GET_U_LONG(buf);
objp->FP = IXDR_GET_U_LONG(buf);
objp->thread = IXDR_GET_U_LONG(buf);
}
return TRUE;
}
 
if (!xdr_int (xdrs, &objp->wait_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_int (xdrs, &objp->status))
return FALSE;
if (!xdr_stop_code (xdrs, &objp->reason))
return FALSE;
if (!xdr_int (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->PC))
return FALSE;
if (!xdr_u_long (xdrs, &objp->SP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->FP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->thread))
return FALSE;
return TRUE;
}
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
 
bool_t
xdr_ptrace_in (XDR *xdrs, ptrace_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
if (!xdr_ptrace_addr_data_in (xdrs, &objp->addr))
return FALSE;
if (!xdr_u_int (xdrs, &objp->data))
return FALSE;
if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
return TRUE;
}
 
bool_t
xdr_ptrace_out (XDR *xdrs, ptrace_out *objp)
{
register int32_t *buf;
 
if (!xdr_ptrace_addr_data_out (xdrs, &objp->addr))
return FALSE;
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
return TRUE;
}
 
bool_t
xdr_one_symbol (XDR *xdrs, one_symbol *objp)
{
register int32_t *buf;
 
if (!xdr_string (xdrs, &objp->symbolName, ~0))
return FALSE;
if (!xdr_long (xdrs, &objp->symbolValue))
return FALSE;
return TRUE;
}
 
bool_t
xdr_all_symbols (XDR *xdrs, all_symbols *objp)
{
register int32_t *buf;
 
if (!xdr_array (xdrs, (char **)&objp->all_symbols_val, (u_int *) &objp->all_symbols_len, ~0,
sizeof (one_symbol), (xdrproc_t) xdr_one_symbol))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_global_symbols_out (XDR *xdrs, get_global_symbols_out *objp)
{
register int32_t *buf;
 
if (!xdr_all_symbols (xdrs, &objp->symbols))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_text_data_in (XDR *xdrs, get_text_data_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
if (!xdr_string (xdrs, &objp->actorName, 16))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_text_data_out (XDR *xdrs, get_text_data_out *objp)
{
register int32_t *buf;
 
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textSize))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataSize))
return FALSE;
} else {
IXDR_PUT_LONG(buf, objp->result);
IXDR_PUT_LONG(buf, objp->errNo);
IXDR_PUT_U_LONG(buf, objp->textStart);
IXDR_PUT_U_LONG(buf, objp->textSize);
IXDR_PUT_U_LONG(buf, objp->dataStart);
IXDR_PUT_U_LONG(buf, objp->dataSize);
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textSize))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataSize))
return FALSE;
} else {
objp->result = IXDR_GET_LONG(buf);
objp->errNo = IXDR_GET_LONG(buf);
objp->textStart = IXDR_GET_U_LONG(buf);
objp->textSize = IXDR_GET_U_LONG(buf);
objp->dataStart = IXDR_GET_U_LONG(buf);
objp->dataSize = IXDR_GET_U_LONG(buf);
}
return TRUE;
}
 
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textSize))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataSize))
return FALSE;
return TRUE;
}
 
bool_t
xdr_one_signal (XDR *xdrs, one_signal *objp)
{
register int32_t *buf;
 
if (!xdr_u_int (xdrs, &objp->number))
return FALSE;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
return TRUE;
}
 
bool_t
xdr_all_signals (XDR *xdrs, all_signals *objp)
{
register int32_t *buf;
 
if (!xdr_array (xdrs, (char **)&objp->all_signals_val, (u_int *) &objp->all_signals_len, ~0,
sizeof (one_signal), (xdrproc_t) xdr_one_signal))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_signal_names_out (XDR *xdrs, get_signal_names_out *objp)
{
register int32_t *buf;
 
if (!xdr_all_signals (xdrs, &objp->signals))
return FALSE;
return TRUE;
}
/* now define the actual calls we support */
/ptrace.c
0,0 → 1,333
/*
**************************************************************************
*
* Component =
*
* Synopsis = rkdb/rkdb.c
*
* $Id: ptrace.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/rdbg_f.h>
#include <rdbg/servrpc.h>
 
extern rtems_id serializeSemId;
extern rtems_id wakeupEventSemId;
extern rtems_id eventTaskId;
extern Exception_context *FirstCtx;
extern Exception_context *LastCtx;
extern CPU_Exception_frame SavedContext;
extern unsigned int NbExceptCtx;
extern unsigned int NbSerializedCtx;
 
 
 
/* --------------------------------------------------------------------
return a pointer to the Thread Control structure of the specified
Id
-------------------------------------------------------------------- */
 
Thread_Control *Thread_Get_RDBG (
Objects_Id Id
)
{
unsigned index;
 
if ( Id <_Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
 
index = Id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index] != NULL) {
return (Thread_Control *)(_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index]);
}
}
if ( Id <_Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
 
index = Id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index] != NULL)
return (Thread_Control *)(_Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index]);
}
 
return 0;
 
}
 
 
/* --------------------------------------------------------------------
Memory read
-------------------------------------------------------------------- */
 
int
safeMemRead(void *src, void *dest, int nbBytes){
 
/*
* safe because if it generates an exception,
* it must return normally
* TBD
*/
 
memcpy(dest, src, nbBytes);
return 0;
}
 
/* --------------------------------------------------------------------
Memory write
-------------------------------------------------------------------- */
int
safeMemWrite(void *src, void * dest, int nbBytes){
 
/*
* safe because if it generates an exception,
* it must return normally
* TBD
*/
memcpy(dest, src, nbBytes);
return 0;
}
 
/* --------------------------------------------------------------------
Ptrace
-------------------------------------------------------------------- */
 
int
ptrace (int request, int pid, char* addr, int data, char* addr2)
{
int diag;
errno = 0 ;
if (pid != 1) {
errno = ESRCH;
return -1;
}
switch (request) {
 
case RPT_SINGLESTEP:{
Exception_context *ctx;
 
if (CannotRestart == 1){
setErrno(EIO);
return -1;
}
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
Single_Step(ctx->ctx);
rtems_semaphore_release( ctx->semaphoreId );
return 0;
}
break;
}
 
case RPT_PEEKTEXT:
case RPT_PEEKDATA: {
diag = safeMemRead(addr, &data, sizeof data);
if (diag == 0) return data;
mem_error:
return -1;
}
 
case RPT_POKETEXT: {
diag = safeMemWrite(&data, addr, sizeof data);
 
/*
* We must flush the INSTR and DATA cache to be sure the
* opcode modification is taken into account, because
* the breakpoint opcode is written via the data cache
* while execution code is fetched via the instruction
* cache
*/
if (diag == 0) {
copyback_data_cache_and_invalidate_instr_cache(addr, sizeof data);
return 0;
}
goto mem_error;
}
case RPT_POKEDATA: {
diag = safeMemWrite(&data, addr, sizeof data);
if (diag == 0) return 0;
goto mem_error;
}
case RPT_CONT: {
Exception_context *ctx;
 
if (CannotRestart == 1){
setErrno (EIO);
return -1;
}
ctx = GetExceptCtx (currentTargetThread);
 
if (!isRdbgException(ctx)) {
CannotRestart = 1;
setErrno (EIO);
return -1;
}
 
assert (data == 0);
assert (ExitForSingleStep == 0);
 
rtems_semaphore_release( serializeSemId );
 
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
rtems_semaphore_release( ctx->semaphoreId );
}
return 0;
}
case RPT_ATTACH:
return 0;
case RPT_DETACH:{
Exception_context *ctx;
if (NbExceptCtx || NbSerializedCtx) {
ctx = FirstCtx;
rtems_task_delete(eventTaskId);
rtems_semaphore_delete(serializeSemId);
rtems_semaphore_delete(wakeupEventSemId);
}
return 0;
}
case RPT_GETREGS:{
Exception_context *ctx;
 
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
CtxToRegs (ctx->ctx, (xdr_regs*) addr);
return 0;
}
break;
}
 
case RPT_SETREGS:{
Exception_context *ctx;
 
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
RegsToCtx ((xdr_regs*) addr, ctx->ctx);
return 0;
}
break;
}
case RPT_READTEXT:
case RPT_READDATA: {
diag = safeMemRead(addr, addr2, data);
if (diag == 0) return 0;
goto mem_error;
}
case RPT_WRITETEXT:
case RPT_WRITEDATA: {
diag = safeMemWrite(addr2, addr, data);
if (diag == 0) return 0;
goto mem_error;
}
case RPT_GETTARGETTHREAD:
if (!NbExceptCtx) {
errno = EBUSY;
return -1;
}
return currentTargetThread;
 
case RPT_SETTARGETTHREAD:
if (!NbExceptCtx) {
errno = EBUSY;
return -1;
}
currentTargetThread = data;
return 0;
case RPT_GETTHREADNAME: {
return TgtGetThreadName (NULL, (unsigned)(data), (char *) addr);
}
case RPT_THREADLIST: {
int count = TgtThreadList (NULL, (unsigned*) addr, UTHREAD_MAX
* sizeof (unsigned));
if (count < 0) {
errno = EINVAL;
return -1;
}
return count;
}
 
case RPT_SETTHREADREGS: {
Exception_context *ctx;
CPU_Exception_frame Ectx;
Thread_Control *thread;
rtems_id id;
rtems_task_ident(RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
if (data == (unsigned)id)
break;
if ((ctx = GetExceptCtx (data)) != NULL) {
RegsToCtx ((xdr_regs*) addr, ctx->ctx);
return 0;
}
thread = Thread_Get_RDBG ((Objects_Id)(data));
if (thread != NULL) {
RegsToCtx ((xdr_regs*) addr, &Ectx);
set_ctx_thread (thread, &Ectx);
return 0;
}
break;
}
 
case RPT_GETTHREADREGS: {
Exception_context *ctx;
CPU_Exception_frame Ectx;
Thread_Control *thread;
rtems_id id;
rtems_task_ident(RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
if (data == (unsigned)id){
justSaveContext = 1;
enterRdbg();
CtxToRegs (&(SavedContext), (xdr_regs*) addr);
return 0;
}
if ((ctx = GetExceptCtx (data)) != NULL) {
CtxToRegs (ctx->ctx, (xdr_regs*) addr);
return 0;
}
thread = Thread_Get_RDBG ((Objects_Id)(data));
if (thread != NULL) {
get_ctx_thread (thread, &Ectx);
CtxToRegs (&Ectx, (xdr_regs*) addr);
return 0;
}
break;
}
case RPT_KILL:
TotalReboot = 1;
return 0;
 
case RPT_TRACEME:
case RPT_PEEKUSER:
case RPT_POKEUSER:
case RPT_GETFPREGS:
case RPT_SETFPREGS:
case RPT_GETFPAREGS:
case RPT_SETFPAREGS:
case RPT_SYSCALL:
case RPT_DUMPCORE:
case RPT_GETUCODE:
case RPT_THREADSUSPEND:
case RPT_THREADRESUME:
case RPT_SETTHREADNAME:
default:
break;
}
errno = EINVAL;
return -1;
}
/rdbg.c
0,0 → 1,143
/*
**************************************************************************
*
* Component =
*
* Synopsis = rkdb/rkdb.c
*
* $Id: rdbg.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <assert.h>
#include <errno.h>
#include <rtems.h>
#include <rtems/error.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <rtems/rtems_bsdnet.h>
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <netinet/in.h>
 
u_short rtemsPort = RTEMS_PORT;
int BackPort = RTEMS_BACK_PORT;
int rtemsActive = 0;
SVCXPRT* rtemsXprt;
int rtemsSock;
char ActName[] = "RTEMS";
volatile int ExitForSingleStep = 0 ;
volatile int Continue;
volatile int justSaveContext;
volatile Objects_Id currentTargetThread;
volatile int CannotRestart = 0;
volatile int TotalReboot = 0;
int CONN_LIST_INC = 3;
int PID_LIST_INC = 1;
int TSP_RETRIES = 10;
 
 
int
getId()
{
rtems_id id;
rtems_task_ident(RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
return (int)(id) ;
}
 
static int
rdbgInit (void)
{
int sock;
struct sockaddr_in addr;
 
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
printf("%s: rkdbInit: cannot allocate socket\n", ActName);
return -1;
}
 
bzero( (void *)&addr, sizeof(struct sockaddr_in));
addr.sin_port = htons(rtemsPort);
if ((bind(sock, (struct sockaddr*) &addr, sizeof(addr))) == -1) {
printf("%s: rkdbInit: cannot bind socket\n", ActName);
return -2;
}
rtemsXprt = svcudp_create(sock);
if (svcudp_enablecache(rtemsXprt, 1) == 0) {
printf("%s: rkdbInit: cannot enable rpc cache\n", ActName);
return -3;
}
rtemsSock = sock;
if (!svc_register(rtemsXprt, REMOTEDEB, REMOTEVERS, remotedeb_2, 0)) {
printf(stderr, "unable to register (REMOTEDEB, REMOTEVERS, udp).");
return -4;
}
 
return 0;
}
 
rtems_task
rdbgDaemon (rtems_task_argument argument)
{
svc_run();
}
 
void
rtems_rdbg_initialize (void)
{
rtems_name task_name;
rtems_id tid;
rtems_status_code status;
 
#ifdef DDEBUG
rdb_debug = 1; /* DPRINTF now will display */
#endif
 
DPRINTF (("%s init starting\n", ActName));
 
/* Print version string */
#ifdef DDEBUG
printk ("RDBG v.%d built on [%s %s]\n", SERVER_VERS, __DATE__, __TIME__);
#else
printk ("RDBG v.%d\n", SERVER_VERS);
#endif
 
/* Create socket and init UDP RPC server */
if (rdbgInit() != 0) goto error;
 
Continue = 1;
justSaveContext = 0;
currentTargetThread = 0;
task_name = rtems_build_name( 'R', 'D', 'B', 'G' );
if ((status = rtems_task_create( task_name, 5, 24576,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES | RTEMS_SYSTEM_TASK
, &tid ))
!= RTEMS_SUCCESSFUL){
printf("status = %d\n",status);
rtems_panic ("Can't create task.\n");
}
 
status = rtems_task_start(tid, rdbgDaemon, 0);
 
return;
 
error:
printf ("initialization failed.\n");
}
 
void
setErrno (int error)
{
errno = error;
}
 
int
getErrno()
{
return errno;
}
/servtgt.c
0,0 → 1,552
/*
**************************************************************************
*
* Component: RDB servers
* Module: servtgt.c
*
* $Id: servtgt.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
 
#include <string.h>
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <sys/socket.h>
#include <assert.h>
 
#ifdef DDEBUG
#define Ptrace TgtDbgPtrace
#else
#define Ptrace TgtRealPtrace
#endif
 
/* ----------------------------------------------------------------
TgtBreakRestoreOrig - Restore original instruction at "addr"
just before single-stepping it.
---------------------------------------------------------------- */
 
int TgtBreakRestoreOrig (int pid, void *addr, void *addr2)
/* Process identifier */
/* Breakpoint address */
/* Original instruction or bkpt number */
{
int ret;
int l;
l = (long)Ptrace(RPT_PEEKTEXT, pid, addr, 0, NULL); /* assume ok */
ret = ORG_BREAK (l, (UINT32) addr2); /* reconstruct old instr */
ret = Ptrace(RPT_POKETEXT, pid, addr, ret, NULL); /* poke back old */
return ret;
}
 
/* -----------------------------------------------------------------------
TgtBreakCancelStep - Restore the breakpoint at "addr" if the single-step
has failed at the ptrace level.
----------------------------------------------------------------------- */
 
#define BKPT0(plst) ((BASE_BREAK*)(plst)->break_list)
 
void TgtBreakCancelStep (PID_LIST* plst)
{
assert (plst->break_list);
assert (BKPT0 (plst)->clr_step);
 
if (plst->break_list && BKPT0 (plst)->clr_step) {
int idx = BKPT0 (plst)->last_break;
int data;
 
data = Ptrace (RPT_PEEKTEXT, plst->pid,
(char *)plst->break_list [idx].ee_loc, 0, NULL);
assert (! IS_BREAK (data));
Ptrace (RPT_POKETEXT, plst->pid,
(char *)plst->break_list[idx].ee_loc,
(int) SET_BREAK (data), NULL);
}
}
 
/* -----------------------------------------------------------------------
TgtCreateNew - add a new process into the process management lists.
----------------------------------------------------------------------- */
 
void
TgtCreateNew(PID pid, int conn, INT32 child, char *name, Boolean spawn)
{
int idx;
 
for (idx = 0; idx < pid_list_cnt; idx++)
if (!pid_list[idx].pid)
break; /* find empty */
 
if (idx >= pid_list_cnt)
{ /* no empties, add more */
PID_LIST *tmp_pid_list = pid_list;
 
pid_list_cnt += PID_LIST_INC;
pid_list = (PID_LIST*) Realloc(pid_list, /* get new or extend */
pid_list_cnt * sizeof(PID_LIST));
if (!pid_list)
{ /* out of memory */
pid_list_cnt -= PID_LIST_INC;
if (pid_list_cnt)
{ /* realloc failed - malloc again */
pid_list = tmp_pid_list;
/* above relies on old pointer being valid after failed realloc */
}
return; /* failed */
}
/* now clear newly added space */
memset(pid_list+pid_list_cnt-PID_LIST_INC, 0,
PID_LIST_INC * sizeof(PID_LIST));
idx = pid_list_cnt - PID_LIST_INC;
}
else /* clear entry we found */
memset(&pid_list[idx], 0, sizeof(PID_LIST));
 
/* now fill in empty entry */
pid_list[idx].pid = pid;
pid_list[idx].running = 1; /* we have not called wait yet */
pid_list[idx].primary_conn = (UCHAR)conn; /* primary owner */
if (conn != -1)
{ /* found caller */
pid_list[idx].owners = 1;
PIDMAP_SET (conn, idx); /* mask in */
}
pid_list[idx].thread = (UINT32)-1; /* no thread for now */
pid_list[idx].last_start = LAST_START; /* handle MiX bug */
 
pid_list[idx].name = name ? (char *)StrDup(name) : (char *)NULL;
 
}
 
/* -----------------------------------------------------------------------
TgtNotifyWaitChange - send event to clients indicating child changed state.
----------------------------------------------------------------------- */
 
void
TgtNotifyWaitChange( PID pid, int status, Boolean exclude)
{
int conn, idx;
 
idx = FindPidEntry (pid); /* locate the pid that changed */
if (idx < 0)
{
DPRINTF(("TgtNotifyWaitChange: pid %d not in our list\n",
(int) pid));
return; /* not in our list */
}
pid_list[idx].running = 0; /* not running */
pid_list[idx].state = status; /* save status of stop/term */
if (!pid_list[idx].owners && !STS_SIGNALLED(status))
TgtDelete(&pid_list[idx], -1, 0); /* terminated and no owners */
else
{ /* normal cases */
for (conn = 0; conn < conn_list_cnt; conn++)
{ /* now find all interested clients */
if (!conn_list[conn].in_use /* free entry */
|| ! PIDMAP_TEST (conn, idx))
continue; /* not using this pid */
if (conn == exclude)
continue; /* do not do this one */
TspSendWaitChange(conn, BMSG_WAIT, 1, pid, 0, False);/* notify of change */
}
}
}
 
/* -----------------------------------------------------------------------
TgtNotifyAll - send a message to all clients interested in process.
----------------------------------------------------------------------- */
 
void
TgtNotifyAll( int pid_idx, BACK_MSG msg, UINT16 spec,
UINT32 context, int exclude, Boolean force)
{
int conn;
 
DPRINTF(("TgtNotifyAll: msg %d (%s) for pid_idx=%d (%d,%d)\n",
msg, BmsgNames [msg], pid_idx, exclude, force));
for (conn = 0; conn < conn_list_cnt; conn++)
if (conn_list[conn].in_use /* not free */
&& PIDMAP_TEST (conn, pid_idx))
{
if (conn != exclude)
TspSendWaitChange(conn, msg, spec, pid_list[pid_idx].pid, context,
force);
}
}
 
/* -----------------------------------------------------------------------
TgtDelete - mark process as now uncontrolled.
 
Notes:
- this function removes a process from the process list.
- the notify argument indicates a message to send if needed.
----------------------------------------------------------------------- */
 
void TgtDelete(PID_LIST *plst, int conn_idx, BACK_MSG notify)
{
int idx = plst - pid_list, cnt, conn;
 
/* found */
cnt = pid_list[idx].owners;
if (cnt)
{ /* some connections to break */
for (conn = 0; cnt && conn < conn_list_cnt; conn++)
if (conn_list[conn].in_use /* not free */
&& PIDMAP_TEST (conn, idx))
{ /* found one that uses it */
PIDMAP_CLEAR (conn, idx);
if (notify && conn != conn_idx)
TspSendWaitChange(conn, notify, 0, plst->pid, 0, True);
if (!--cnt)
break;
}
}
if (pid_list[idx].name)
Free(pid_list[idx].name); /* free string name back */
/* Free breakpoint list */
if (pid_list [idx].break_list != NULL) {
Free (pid_list [idx].break_list);
}
pid_list[idx].pid = 0; /* gone */
}
 
 
/* -----------------------------------------------------------------------
TgtKillAndDelete - kill or detach process and remove entry.
----------------------------------------------------------------------- */
 
int
TgtKillAndDelete( PID_LIST *plst, struct svc_req *rqstp, Boolean term)
{
ptrace_in pin; /* used for ptrace call */
ptrace_out *pout;
 
/* Remove breakpoints */
if (plst->break_alloc > 0) {
pin.pid = plst->pid;
pin.addr.req = RPT_CLRBREAK;
pin.data = 0; /* clear all */
pin.flags = PTRFLG_NON_OWNER;
pout = RPCGENSRVNAME(ptrace_2_svc) (&pin, rqstp);
if (pout->result < 0) {
DPRINTF (("TgtKillAndDelete: RPT_CLRBREAK failed %d\n",
getErrno()));
return -1;
}
}
 
if (term)
{ /* kill */
pin.addr.ptrace_addr_data_in_u.address = 0;
pin.data = -1; /* Don't want notification from slave */
pin.addr.req = RPT_KILL;
}
else
{ /* detach */
pin.addr.ptrace_addr_data_in_u.address = 1;
pin.data = 0;
pin.addr.req = RPT_DETACH;
}
pin.pid = plst->pid;
pin.flags = PTRFLG_FREE | PTRFLG_NON_OWNER;
 
DPRINTF (("TgtKillAndDelete: ptrace_2_svc (%s (%d), %d)\n",
PtraceName (pin.addr.req), pin.addr.req, pin.pid));
 
pout = RPCGENSRVNAME(ptrace_2_svc) (&pin, rqstp);/* start it */
if (pout->errNo == ESRCH && plst->pid)
TgtDelete(plst, -1, BMSG_KILLED); /* only entry remains */
return 0;
}
 
/* -----------------------------------------------------------------------
TgtDetachCon - detach a connection's ownership of a process.
----------------------------------------------------------------------- */
 
void
TgtDetachCon( int conn_idx, int pid_idx, Boolean delete)
{
if ((unsigned) pid_idx >= pid_list_cnt
|| !pid_list[pid_idx].pid)
return; /* not valid */
if (PIDMAP_TEST (conn_idx, pid_idx))
{ /* if an owner, release control */
PIDMAP_CLEAR (conn_idx, pid_idx);
 
if (pid_list[pid_idx].owners)
pid_list[pid_idx].owners--;
if (pid_list[pid_idx].primary_conn == conn_idx)
pid_list[pid_idx].primary_conn = NO_PRIMARY;
if (delete
&& !pid_list[pid_idx].owners
&& PROC_TERMINATED (pid_list + pid_idx))
TgtDelete(&pid_list[pid_idx], -1, 0); /* remove entry */
}
}
 
/* -----------------------------------------------------------------------
TgtHandleChildChange - decide what action to take after wait() returns.
Used in the master only.
----------------------------------------------------------------------- */
 
#ifdef DDEBUG
static char* LastStartNames[] = {
"NONE", "STEP", "CONT", "RANGE",
"STEPOFF", "KILLED", "DETACHED"
};
 
char* GetLastStartName (int last_start)
{
static char buf [32];
 
strcpy (buf, LastStartNames [last_start & ~LAST_START]);
if (last_start & LAST_START) {
strcat (buf, "+START");
}
return buf;
}
#endif
 
Boolean TgtHandleChildChange(PID pid, int* status, int *unexp,
CPU_Exception_frame* ctx)
{ /* return False if continue, else stop */
int idx, sig;
int bidx = 0;
PID_LIST *plst;
unsigned long PC;
BASE_BREAK *base = NULL; /* break_list[0] is really BASE_BREAK */
int hadStepEmul;
int origHadStepEmul;
int stopWanted;
 
DPRINTF (("TgtHandleChildChange: pid %d status %x cap\n",
(int) pid, *status));
if (unexp)
*unexp = 0; /* initialize to ok */
 
/* first, find pid in question */
idx = FindPidEntry (pid);
if (idx < 0)
{ /* cannot locate this process */
DPRINTF (("TgtHandleChildChange: unknown process (%s pid)\n",
FindPidEntry (pid) >= 0 ? "stale" : "unknown"));
if (unexp)
*unexp = 1; /* Unexpected change */
return(False); /* unknown: ignore (used to stop and notify) */
}
 
/* found */
plst = &pid_list[idx]; /* pointer to entry */
/* first we see if just stopped */
 
/* copy ctxt */
CtxToRegs(ctx, &(plst->regs));
 
stopWanted = plst->stop_wanted;
plst->stop_wanted = 0; /* For the next time */
 
hadStepEmul = BreakClear (plst, -1, -1) > 0;
origHadStepEmul = hadStepEmul; /* hadStepEmul is cleared if real bkpt met */
 
if (STS_SIGNALLED (*status))
{ /* stopped, not terminated */
sig = STS_GETSIG (*status); /* signal that stopped us */
 
/* now, we read the registers and see what to do next */
if (TgtPtrace(RPT_GETREGS, pid, (void *)&plst->regs, 0, NULL) < 0) {
memset (&plst->regs, 0, sizeof plst->regs);
}
 
/* Get current thread */
plst->thread = TgtPtrace(RPT_GETTARGETTHREAD, pid, NULL, 0, NULL);
 
if (sig == SIGTRAP)
{ /* stopped from break/step */
PC = plst->regs.REG_PC;
/* Must check PC to see whether in situations where we had
step emulation we are on a breakpoint or just
have returned from an emulated single-step */
if (BreakIdentify (plst, 0 /*no adjust*/, -1 /*no thread*/) > 0) {
hadStepEmul = 0;
}
plst->is_step = hadStepEmul || IS_STEP(plst->regs)
|| plst->last_start == LAST_START;
DPRINTF (("TgtHandleChildChange: %s last_start %s\n", plst->is_step
? "step": "break", GetLastStartName (plst->last_start)));
 
if ((plst->is_step || origHadStepEmul || stopWanted)
&& (plst->last_start == LAST_STEP
|| plst->last_start == LAST_STEPOFF
|| plst->last_start == LAST_RANGE))
{
DPRINTF (("TgtHandleChildChange: restoring stepped-off bkpt\n"));
BreakSteppedOff (plst);
}
 
if (plst->last_start == LAST_STEPOFF && (plst->is_step||origHadStepEmul))
{ /* stepped off break and now need cont */
DPRINTF (("TgtHandleChildChange: auto-resuming after step-off\n"));
plst->last_start = LAST_CONT; /* convert to normal cont */
if (!stopWanted) {
if (TgtPtrace(RPT_CONT, pid, (char *)1, 0, NULL))
return True; /* tell people */
return(False); /* wait for change */
}
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-off\n",
stopWanted));
*status = STS_MAKESIG (stopWanted);
return True; /* Stop and notify */
}
 
base = plst->break_list ? ((BASE_BREAK*)plst->break_list) :
((BASE_BREAK*)NULL);
/* now see if step in range */
 
if (plst->last_start == LAST_RANGE /* step in range */
&& (plst->is_step || origHadStepEmul) /* not a breakpoint */
&& PC >= base->range_start
&& PC <= base->range_end)
{ /* still in range, keep going */
if (stopWanted) {
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-range\n",
stopWanted));
} else {
DPRINTF (("TgtHandleChildChange: Reservation at %x\n",
plst->regs.REG_PC));
}
}
if (!plst->is_step) /* was break */
{
bidx = BreakIdentify (plst, 1 /*adjust*/, plst->thread);
if (bidx == 0) {
DPRINTF (("TgtHandleChildChange: forwarding bkpt to kernel\n"));
if (unexp) {
*unexp = 1;
}
return False;
}
if (bidx < 0) { /* Unwanted breakpoint, must step it off */
ptrace_in pin;
ptrace_out* out;
if (origHadStepEmul)
{
DPRINTF (("TgtHandleChildChange: bkpt %x becomes step\n",
plst->regs.REG_PC));
bidx = -bidx;
plst->is_step = 1;
base->clr_step = plst->break_list [bidx].type == BRKT_INSTR;
base->last_break = bidx;
return True;
}
if (stopWanted) {
DPRINTF (("TgtHandleChildChange: stop_wanted %d at bkpt %x\n",
stopWanted, plst->regs.REG_PC));
/* The PC has already been adjusted by BreakIdentify */
*status = STS_MAKESIG (stopWanted);
return True;
}
/* All the handling is done in ptrace_2_svc() so call it */
bidx = -bidx;
DPRINTF (("TgtHandleChildChange: last %d (%s) restarting bkpt %d\n",
plst->last_start, GetLastStartName (plst->last_start), bidx));
base->clr_step = 1;
base->last_break = bidx; /* remember which one */
plst->running = 0; /* So that ptrace is accepted */
pin.pid = plst->pid;
 
if (plst->last_start == LAST_STEP) {
pin.addr.req = RPT_SINGLESTEP;
} else {
pin.addr.req = RPT_CONT;
}
pin.addr.ptrace_addr_data_in_u.address = 1;
pin.data = 0;
pin.flags = PTRFLG_NON_OWNER;
out = RPCGENSRVNAME(ptrace_2_svc) (&pin, NULL);
if (out->result == 0) return False; /* Continue waiting */
DPRINTF(("TgtHandleChildChange: failed to restart bkpt!\n"));
/* If something went wrong, just stop on breakpoint */
}
}
} /* else sig != SIGTRAP */
 
/* finally, fill in stop info in break point array base */
if (bidx > 0)
{ /* store break info */
/* will need to get off the break for SW breakpoints only */
base->clr_step = plst->break_list [bidx].type == BRKT_INSTR;
base->last_break = bidx; /* remember which one */
}
else if (base)
{ /* clear break info */
base->clr_step = False; /* not stopped on break */
base->last_break = 0;
}
/* decision to notify owner based on last_start */
} /* stopped */
else /* terminated */
{
if (plst->last_start == LAST_START)
{ /* spawn failed */
TgtNotifyAll(idx, BMSG_EXEC_FAIL, 0, 0, -1, True);
plst->running = False; /* not running - dead */
plst->state = *status; /* contains errno in high word */
return(False);
}
else if ((UCHAR)(plst->last_start & ~LAST_START) < (UCHAR)LAST_KILLED)
plst->last_start = LAST_NONE; /* doesn't matter anymore */
else
return(False); /* killed and detach already notified */
}
return(True); /* stop and notify */
}
 
#ifdef DDEBUG
 
/* -----------------------------------------------------------------------
TgtDbgPtrace - debug version of ptrace.
----------------------------------------------------------------------- */
 
int TgtDbgPtrace(int request, PID pid, char *addr, int data, void *addr2)
{
int diag;
 
DPRINTF (("TgtDbgPtrace: entered (%s (%d), %d, %x, %d, %x)\n",
PtraceName (request), request, pid, (int) addr, data,
(int) addr2));
 
if (request == RPT_WRITETEXT || request == RPT_WRITEDATA) {
int i;
 
DPRINTF (("TgtDbgPtrace:"));
if (rdb_debug) {
for (i = 0; i < data && i < 16; ++i) {
printf (" %02x", ((char*) addr2) [i] & 0xFF);
}
printf ("\n");
}
}
 
diag = TgtRealPtrace (request, pid, addr, data, addr2);
 
DPRINTF (("TgtDbgPtrace: returned %d (%x) errno %d\n",
diag, diag, getErrno()));
 
if (request == RPT_GETREGS || request == RPT_GETTHREADREGS
|| request == RPT_SETREGS || request == RPT_SETTHREADREGS)
{
/* Use DPRINTF() so as to have the id prefix */
DPRINTF (("TgtDbgPtrace: (%s) PC = %x, SP = %x, FP = %x\n",
PtraceName (request),
((xdr_regs*)addr)->REG_PC,
((xdr_regs*)addr)->REG_SP,
((xdr_regs*)addr)->REG_FP));
}
 
return(diag);
}
#endif /* DDEBUG */
/servcon.c
0,0 → 1,138
/*
**************************************************************************
*
* Component: RDBG
* Module: servcon.c
*
* Synopsis: Management of RPC client connections.
*
* $Id: servcon.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
/*
* ConnCreate - create a new connection entry for a client.
*
* This function finds an empty entry in the connection array
* or makes space. It fills in the fields that are passed to it.
* It does not do any validation on net addresses nor does it
* start a validation cycle on other clients. This is done by
* the caller.
*/
 
int
ConnCreate (struct svc_req* rqstp, open_in* in)
{
NET_OPAQUE sender;
int idx;
CONN_LIST* clst;
setErrno (0);
 
/* Convert to valid Net address */
if (! TspTranslateRpcAddr (rqstp, &sender)) {
DPRINTF (("ConnCreate: TspTranslateRpcAddr failed\n"));
return -1;
}
if (! TspValidateAddr ((NET_OPAQUE*) in->back_port, &sender)) {
DPRINTF (("ConnCreate: TspValidateAddr failed\n"));
return -1; /* errno now setup with error */
}
 
/* look for an empty connection entry */
for (idx = 0; idx < conn_list_cnt; idx++) {
if (!conn_list[idx].in_use)
break; /* an empty one found */
}
 
if (idx >= conn_list_cnt) { /* no empties, create space */
CONN_LIST* tmp_conn_list = conn_list;
 
conn_list_cnt += CONN_LIST_INC;
if (conn_list) {
conn_list = (CONN_LIST *) Realloc (conn_list, /* extend */
conn_list_cnt * sizeof (CONN_LIST));
} else {
conn_list = (CONN_LIST *)Malloc(conn_list_cnt * sizeof(CONN_LIST));
}
 
if (!conn_list) { /* unable to get space */
if ((conn_list_cnt -= CONN_LIST_INC)) {
/* was realloc, restore space */
conn_list = tmp_conn_list;
}
return -1; /* errno set by failed alloc */
}
/* clear newly created memory */
memset (conn_list + idx, 0, CONN_LIST_INC * sizeof (CONN_LIST));
} else { /* clear new entry */
memset (conn_list + idx, 0, sizeof (CONN_LIST));
}
clst = conn_list + idx;
 
clst->in_use = True; /* now in use */
clst->sender = sender;
memcpy (&clst->back_port, &in->back_port, sizeof (NET_OPAQUE));
memcpy (&clst->route, &in->destination, sizeof (NET_OPAQUE));
clst->debug_type = (UCHAR) in->debug_type;
clst->flags = in->flags;
strncpy (clst->user_name, in->user_name, NAMEMAX-1);
clst->user_name [NAMEMAX-1] = 0;
 
return idx;
}
 
/*
* ConnDelete - remove connection entry when shutdown.
*
*/
 
void
ConnDelete (int conn, struct svc_req* rqstp, close_control control)
{
CONN_LIST* clst = conn_list + conn;
int idx;
Boolean prim;
 
if (! clst->in_use) return; /* not active */
 
for (idx = 0; idx < pid_list_cnt; idx++) {
PID_LIST* plst = pid_list + idx;
 
if (! PIDMAP_TEST (conn, idx)) continue;
 
/* found a controlled pid */
prim = (plst->primary_conn == conn) ? True : False;
TgtDetachCon (conn, idx, True);
 
/* if still running or alive, we use close control on it */
if (! plst->pid)
continue; /* entry gone */
 
if (prim && control == CLOSE_KILL) {
/* kill off process */
TgtKillAndDelete (plst, rqstp, True);
} else if (! plst->owners) {
/* no owners left */
if (control == CLOSE_DETACH) {
TgtKillAndDelete (plst, rqstp, False);
}
if (control == CLOSE_DETACH || PROC_TERMINATED (plst)) {
TgtDelete (plst, conn, (control==CLOSE_DETACH) ?
BMSG_DETACH : 0);
}
}
}
if (clst->list) {
Free (clst->list); /* free allocated memory */
}
DPRINTF (("ConnDelete: Connection closed for port %u\n",
HL_W(*((UINT16*) &clst->back_port.c[2]))));
 
clst->in_use = False; /* free it back */
}
/servbkpt.c
0,0 → 1,589
/*
**********************************************************************
*
* Component: RDB servers
* Module: servbkpt.c
*
* Synopsis: Management of breakpoints
*
* $Id: servbkpt.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**********************************************************************
*/
 
#include <sys/errno.h>
#include <assert.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
 
/*----- Macros -----*/
 
#define BKPT0(plst) ((BASE_BREAK*)(plst)->break_list)
#define BKPT_INCR 5 /* how many bkpt slots alloc at a time */
 
#define BKPT_OVER(plst,idx,addr,size) \
((plst)->break_list[idx].ee_loc + BREAK_SIZE > (UINT32) (addr) \
&& (plst)->break_list[idx].ee_loc < (UINT32) (addr) + (size))
 
#define BKPT_SLOTS \
(sizeof ((xdr_break*) 0)->thread_list / \
sizeof ((xdr_break*) 0)->thread_list [0])
 
 
/*
* BreakAlloc - alloc a breakpoint entry.
*
* This is a generic routine to insert an entry in the
* breakpoint list. It returns the number of entry just
* created. It returns -1 if failed.
*/
 
static int
BreakAlloc (PID_LIST* plst, Boolean normal)
{
int idx, len;
xdr_break* blst;
 
if (!normal) { /* want 0 entry */
if (plst->break_list) {
return(0); /* already there */
}
idx = 1; /* force alloc below */
} else {
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
if (plst->break_list[idx].type == BRKT_NONE) {
/* got a free one */
memset(&plst->break_list[idx], 0, sizeof(xdr_break));
return(idx); /* found one */
}
}
}
/* idx is the requested entry */
 
if (idx >= (int)plst->break_alloc) { /* need more space */
len = plst->break_alloc + BKPT_INCR;
blst = (xdr_break*)Realloc(plst->break_list, len*sizeof(xdr_break));
if (!blst) {
return(-1); /* failed, no space */
}
plst->break_alloc = len; /* got more */
plst->break_list = blst;
 
/* Clear new space */
memset(blst + len - BKPT_INCR, 0, BKPT_INCR * sizeof(xdr_break));
idx = len - BKPT_INCR; /* next available */
if (!idx) {
idx = 1; /* for normal cases */
}
}
return(normal ? idx : 0); /* return it */
}
 
/*
* BreakSet - set a breakpoint in process
*
* Returns the number or -1/errno.
*/
 
#ifdef DDEBUG
static const char* BreakTypes[] = {
"NONE", "INSTR", "READ", "WRITE",
"ACCESS", "EXEC", "OS_CALL", "OS_SWITCH",
"STEPEMUL"
};
 
#define BN_MAX (sizeof BreakTypes / sizeof BreakTypes[0])
#define BREAK_NAME(t) ((unsigned) (t) < BN_MAX ? BreakTypes[t] : "???")
#endif
 
int
BreakSet (PID_LIST* plst, int conn_idx, xdr_break* bkpt)
{
int pid = plst->pid;
int type = bkpt->type;
void* addr = (void *) bkpt->ee_loc;
int idx;
int data;
DPRINTF(("BreakSet: type %d (%s) at 0x%x th %d ee_type %d len %d "
"pass %d curr %d list %d %d %d %d\n", type, BREAK_NAME(type),
(int) addr,
bkpt->thread_spec, bkpt->ee_type, bkpt->length, bkpt->pass_count,
bkpt->curr_pass, bkpt->thread_list [0], bkpt->thread_list [1],
bkpt->thread_list [2], bkpt->thread_list [3]));
 
idx = BreakAlloc(plst, True); /* get entry */
if (idx < 0) { /* no memory */
setErrno(ENOMEM); /* set for safety */
return -1; /* return the error */
}
 
data = TgtPtrace(RPT_PEEKTEXT, pid, addr, 0, NULL); /* current */
if (getErrno()) {
return -1; /* failed, return the error */
}
if (IS_BREAK(data)) { /* There is already a break here */
DPRINTF(("BreakSet: already have soft bkpt at %x\n", addr));
if (type == BRKT_STEPEMUL) {
++BKPT0 (plst)->pad1;
return 1; /* Any non-error value is OK */
}
setErrno(EBUSY);
return -1;
}
 
TgtPtrace(RPT_POKETEXT, pid, addr, SET_BREAK(data), NULL);
 
if (getErrno()) {
return -1;
}
 
plst->break_list[idx] = *bkpt;
plst->break_list[idx].ee_type = data; /* saved data */
/* Inform other owners */
if (type != BRKT_STEPEMUL) {
TgtNotifyAll (plst - pid_list, BMSG_BREAK, 1 /*added*/, idx,
conn_idx, False);
} else {
++BKPT0 (plst)->pad1;
}
/* Return the number */
setErrno(0); /* Just in case */
return idx;
}
 
int
BreakSetAt (PID_LIST* plst, int conn_idx, unsigned long addr, break_type type)
{
xdr_break xb;
 
memset (&xb, 0, sizeof xb);
xb.type = type;
xb.ee_loc = addr;
return BreakSet (plst, conn_idx, &xb);
}
 
/*----- Find a breakpoint by address -----*/
 
int
BreakGetIndex(PID_LIST* plst, void* addr)
{
int idx;
int data = -1;
 
if (!plst->break_alloc) {
setErrno(EFAULT);
return -1;
}
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
if ((u_long) addr == plst->break_list [idx].ee_loc) {
data = idx;
break;
}
}
return data;
}
 
/*----- Getting information about breakpoint -----*/
 
/*
* If data > 0, fill "bkpt" with information about breakpoint
* and return the number of the next one.
* If data == 0, return the count of breakpoints.
*/
 
int
BreakGet (const PID_LIST* plst, int data, xdr_break* bkpt)
{
int idx;
 
if (!data) { /* just count them */
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
if (plst->break_list[idx].type != BRKT_NONE) {
data++;
}
}
return data; /* count */
}
if ((unsigned) data >= plst->break_alloc) {
/* out of range */
setErrno(EFAULT); /* closest match */
return -1;
}
/* get it and say which is next */
*bkpt = plst->break_list[data];
for (idx = (int)data+1; idx < (int)plst->break_alloc; idx++) {
if (plst->break_list[idx].type != BRKT_NONE) {
return idx;
}
}
return 0; /* otherwise returns 0 for no more */
}
 
/*----- Clearing bkpts -----*/
 
/*
* BreakClear - clear one (if data != 0) or all breakpoints
* (if data == 0). Return the number of bkpts cleared.
* If (data == -1), remove step-emulation breakpoints.
*/
 
int
BreakClear (PID_LIST* plst, int conn_idx, int data)
{
int pid_idx = plst - pid_list;
int idx;
int cleared = 0;
int clearStepEmul = 0;
int terminated = PROC_TERMINATED (plst);
int stepEmulCount = 0;
 
/* break handle in data */
if (!plst->break_alloc) { /* there are no breaks */
DPRINTF (("BreakClear: no bkpts defined.\n"));
setErrno(EFAULT); /* closest match */
return -1; /* return error */
}
if (!data) { /* clear all */
idx = 1;
data = plst->break_alloc-1;
 
/* Inform other owners */
DPRINTF (("BreakClear: clearing all bkpts.\n"));
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr*/, 0, conn_idx, False);
 
} else if (data == -1) { /* clear all step-emul bkpts */
DPRINTF(("BreakClear: removing %d step-emul bkpts\n",
BKPT0 (plst)->pad1));
 
stepEmulCount = BKPT0 (plst)->pad1;
BKPT0 (plst)->pad1 = 0;
 
clearStepEmul = 1;
idx = 1;
data = plst->break_alloc-1;
} else if ((unsigned) data >= plst->break_alloc
|| plst->break_list[data].type == BRKT_NONE) {
 
/* out of range */
DPRINTF (("BreakClear: invalid bkpt %d\n", data));
setErrno(EFAULT); /* closest match */
return -1; /* return error */
} else {
idx = data;
/* Inform other owners */
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr*/, idx, conn_idx, False);
DPRINTF (("BreakClear: clearing bkpt %d\n", data));
}
 
for (; idx <= data; idx++) { /* clear each one */
int type = plst->break_list[idx].type;
 
if (clearStepEmul && type != BRKT_STEPEMUL) continue;
 
if (type == BRKT_INSTR || (clearStepEmul && type == BRKT_STEPEMUL)) {
/* just patch back */
char* addr = (char *)plst->break_list[idx].ee_loc;
int val;
 
if (BKPT0 (plst)->clr_step && BKPT0 (plst)->last_break == idx) {
BKPT0 (plst)->clr_step = 0; /* not needed */
}
/* Neighboring bytes can have breakpoints too... */
if (! terminated) {
setErrno (0);
val = TgtPtrace(RPT_PEEKTEXT, plst->pid, addr, 0, NULL);
if (getErrno()) {
DPRINTF (("BreakClear: addr %x not readable!\n", addr));
setErrno (0); /* Forget bkpt */
} else {
assert (IS_BREAK (val));
val = ORG_BREAK (val, (int)plst->break_list[idx].ee_type);
TgtPtrace(RPT_POKETEXT, plst->pid, addr, val, NULL);
if (getErrno()) {
DPRINTF (("BreakClear: addr %x not writable!\n", addr));
setErrno (0);
}
}
}
++cleared; /* indicate cleared */
}
memset(&plst->break_list[idx], 0, sizeof(xdr_break));
}
assert (!clearStepEmul || cleared <= stepEmulCount);
if (stepEmulCount && cleared == 0) {
DPRINTF (("BreakClear: all STEPEMUL bkpts were shared\n"));
return 1;
}
return cleared;
}
 
/*----- Hiding of breakpoints -----*/
 
/*
* PatchBreak - patch original data from break into data buffer.
*
* Notes:
* - this routine patches the original data under a break into the data
* buffer from a ptrace read/peek.
*/
 
static void
PatchBreak (char* buff, UINT32 bstart, int bsize, UINT32 dstart, char* dvalue)
{
int size = BREAK_SIZE; /* default size */
 
/* Must deal with all sorts of unalignments
* (3 full overlaps, 3 unaligns)
*/
if (bsize < BREAK_SIZE) {
/* case where buffer is smaller than data */
memcpy(buff, dvalue+(bstart-dstart), bsize); /* copy over */
return;
}
/* buffer larger than data.
* we need to see where break fits in buffer and whether
* we have part of it off the end. We set bstart to be the
* buffer offset, dtart to be the break data offset, and
* size to be the amount to copy
*/
if (dstart < bstart) {
/* break before actual buffer */
dstart = bstart-dstart; /* offset in data */
size -= dstart; /* amount to copy */
bstart = 0; /* offset in buffer */
 
} else if (dstart + size > bstart + bsize) {
/* off end */
bstart += bsize; /* end of buffer */
size -= (dstart + size) - bstart;
bstart = bsize - size; /* come back into buffer enough */
dstart = 0; /* start of data */
 
} else { /* normal case */
bstart = dstart - bstart; /* offset in buffer */
dstart = 0;
}
memcpy(buff+bstart, dvalue+dstart, size);
}
 
void
BreakHide (const PID_LIST* plst, void* addr, int data, void* addr2)
{
int idx;
 
if (!plst->break_list) /* no breaks exist, so skip this */
return;
 
/* if breakpoints, replace */
 
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
int type = plst->break_list[idx].type;
 
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
continue;
}
/* break, see if overlaps */
if (BKPT_OVER (plst, idx, addr, data)) {
 
/* overlaps, patch in old value */
PatchBreak((char *)addr2, (UINT32)addr, data,
plst->break_list[idx].ee_loc,
(char *)&plst->break_list[idx].ee_type);
}
}
}
 
/*----- Checking of breakpoint overwrites -----*/
 
/*
* BreakOverwrite - check if memory write does not involve addresses
* having software breakpoints.
*/
 
int
BreakOverwrite (const PID_LIST* plst, const char* addr, unsigned int size)
{
int idx;
 
if (!plst->break_list) { /* No breaks exist */
return 0;
}
 
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
int type = plst->break_list[idx].type;
 
/* Consider only breakpoints involving modified memory */
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
continue;
}
if (BKPT_OVER (plst, idx, addr, size)) {
return -1; /* overlaps */
}
}
return 0;
}
 
/*----- Execution support -----*/
 
/*
* BreakStepRange - Start stepping in a range.
*
* Range is saved in breakpoint 0.
*/
 
int
BreakStepRange (PID_LIST* plst, void* addr, int len)
{
if (!plst->break_list) {
/* get list */
if (BreakAlloc (plst, False) == -1) { /* must not be any memory */
setErrno(ENOMEM); /* to be safe */
return -1; /* fails */
}
}
BKPT0 (plst)->range_start = (UINT32)addr;
BKPT0 (plst)->range_end = (UINT32)addr+(len-1);
return 0;
}
 
/*
* If the Program Counter is changed, consider that the
* current breakpoint has not been reached yet.
*/
 
void
BreakPcChanged (PID_LIST* plst)
{
if (plst->break_list) {
/* clear break stuff */
BKPT0 (plst)->clr_step = False;
}
}
 
/*
* BreakStepOff - prepare stepping off a breakpoint.
*/
 
int
BreakStepOff (const PID_LIST* plst, void** paddr2)
{
if (plst->break_list && BKPT0 (plst)->clr_step) {
 
/* need clear then step off break */
int last = BKPT0 (plst)->last_break;
 
/* clear break, step, then do exec */
 
*paddr2 = (void*) plst->break_list[last].ee_type;
 
/* Need to clr_step after TgtPtrace() when wait() returns */
return 1;
}
return 0;
}
 
/*
* BreakSteppedOff - check if just stepped off a breakpoint
* and re-insert it into the code.
*/
 
void
BreakSteppedOff (PID_LIST* plst)
{
if (plst->break_list && BKPT0 (plst)->clr_step) {
int idx = BKPT0 (plst)->last_break;
int data;
 
BKPT0 (plst)->clr_step = 0;
 
/*
* Re-insert the breakpoint.
*/
data = TgtPtrace (RPT_PEEKTEXT, plst->pid,
(char *)plst->break_list [idx].ee_loc, 0, NULL);
assert (! IS_BREAK (data));
TgtPtrace (RPT_POKETEXT, plst->pid,
(char *)plst->break_list[idx].ee_loc,
(int) SET_BREAK (data), NULL);
}
}
 
 
/*
* Returns whether a thread matches a breakpoint.
*/
 
static int
BreakThreadMatch (xdr_break* xb, int thread)
{
int slot;
 
if (thread < 0) return 1; /* Break existence check only */
 
if (xb->thread_list [0] == 0) return 1; /* Universal break */
 
for (slot = 0; slot < BKPT_SLOTS; ++slot) {
if (xb->thread_list [slot] == 0) return 0; /* End of list */
if (xb->thread_list [slot] == thread) return 1; /* Match */
}
return 0; /* No matches found */
}
 
 
int
BreakAdjustPC (PID_LIST* plst)
{
/*
* BREAK_ADJ is the value by which the Program Counter
* has to be decremented after a software breakpoint
* is hit. It must be defined and can be zero.
*/
#if BREAK_ADJ
/* subtract back if necessary */
plst->regs.REG_PC -= BREAK_ADJ; /* now write back */
TgtPtrace(RPT_SETREGS, plst->pid, (char *)&plst->regs, 0, NULL);
#else
(void) plst;
#endif
return 0;
}
 
 
/*
* Identify the current breakpoint. The process just stopped.
*/
 
int
BreakIdentify (PID_LIST* plst, int adjust, int thread)
{
int foreignBkpt = 0;
int bidx;
 
for (bidx = 1; bidx < (int) plst->break_alloc; bidx++) {
int type = plst->break_list[bidx].type;
 
if ((type == BRKT_INSTR || type == BRKT_STEPEMUL)
&& plst->regs.REG_PC - BREAK_ADJ
== plst->break_list[bidx].ee_loc) { /* found matching */
if (!BreakThreadMatch (&plst->break_list[bidx], thread)) {
if (foreignBkpt == 0) {
foreignBkpt = bidx;
}
continue;
}
if (adjust) {
BreakAdjustPC (plst);
}
return bidx;
}
}
if (foreignBkpt) {
if (adjust) {
BreakAdjustPC (plst);
}
return -foreignBkpt;
}
return 0;
}
/remdeb.x
0,0 → 1,546
/*
**********************************************************************
*
* Component: RDBG servers
* Module: remdeb.x
*
* Synopsis: XDR definitions for remote debug server RPC calls.
* XDR definitions for RPCGEN to build remote debug server.
*
* $Id: remdeb.x,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**********************************************************************
*/
 
#ifdef RPC_SVC
%/*HEADER_START*/
#endif
 
%#define RTEMS_PORT 2071
%#define RTEMS_BACK_PORT 2073
 
#ifdef RPC_HDR
%#ifndef REMDEB_H
%#define RPCGENSRVNAME(a) a
#endif
 
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25
};
 
 
const NET_SAFE = 1400; /* this is safe for UDP messages */
 
struct UDP_MSG
{ /* format of UDP messages (should be in .h) */
unsigned char type; /* type of message (BMSG_xx) */
unsigned char msg_num; /* ringed number for resend detect */
unsigned short spec; /* specific information for type */
long pid; /* process this affects */
unsigned long context; /* specific information to request */
};
 
/* First we support the overhead structures and types needed for RPC
requests. Then, we have all RPC routines input/output args. */
 
%/*
% * Sun request values for the remote ptrace system call
% */
%
enum ptracereq
{ /* these match PTRACE_xxx numbers */
RPT_TRACEME = 0, /* 0, by tracee to begin tracing */
RPT_CHILDDONE = 0, /* 0, tracee is done with his half */
RPT_PEEKTEXT, /* 1, read word from text segment */
RPT_PEEKDATA, /* 2, read word from data segment */
RPT_PEEKUSER, /* 3, read word from user struct */
RPT_POKETEXT, /* 4, write word into text segment */
RPT_POKEDATA, /* 5, write word into data segment */
RPT_POKEUSER, /* 6, write word into user struct */
RPT_CONT, /* 7, continue process */
RPT_KILL, /* 8, terminate process */
RPT_SINGLESTEP, /* 9, single step process */
RPT_ATTACH, /* 10, attach to an existing process (returns 2 if not primary)*/
RPT_DETACH, /* 11, detach from a process */
RPT_GETREGS, /* 12, get all registers */
RPT_SETREGS, /* 13, set all registers */
RPT_GETFPREGS, /* 14, get all floating point regs */
RPT_SETFPREGS, /* 15, set all floating point regs */
RPT_READDATA, /* 16, read data segment */
RPT_WRITEDATA, /* 17, write data segment */
RPT_READTEXT, /* 18, read text segment */
RPT_WRITETEXT, /* 19, write text segment */
RPT_GETFPAREGS, /* 20, get all fpa regs */
RPT_SETFPAREGS, /* 21, set all fpa regs */
RPT_22, /* 22, filler */
RPT_23, /* 23, filler */
RPT_SYSCALL, /* 24, trap next sys call */
RPT_DUMPCORE, /* 25, dump process core */
RPT_26, /* 26, filler */
RPT_27, /* 27, filler */
RPT_28, /* 28, filler */
RPT_GETUCODE, /* 29, get u.u_code */
/* Begin specific ptrace options */
RPT_GETTARGETTHREAD = 50, /* get PM target thread identifier */
RPT_SETTARGETTHREAD = 51, /* set PM target thread identifier */
RPT_THREADSUSPEND = 52, /* suspend a thread */
RPT_THREADRESUME = 53, /* resume a thread */
RPT_THREADLIST = 54, /* get list of process's threads */
RPT_GETTHREADNAME = 55, /* get the name of the thread */
RPT_SETTHREADNAME = 56, /* set the name of the thread */
RPT_SETTHREADREGS = 57, /* set all registers for a specific thread*/
RPT_GETTHREADREGS = 58, /* get all registers for a specific thread*/
/* Begin extended ptrace options for remote debug server */
RPT_STEPRANGE = 75, /* step while in range (addr=start, data=len) */
RPT_CONTTO = 76, /* cont from PC to temp break in addr */
RPT_SETBREAK = 77, /* set a breakpoint (addr=break) */
RPT_CLRBREAK = 78, /* clear a breakpoint (data=handle or 0 for all) */
RPT_GETBREAK = 79, /* get breakpoint (data=handle, addr=buffer to
fill). Returns next break. If data=0,
returns number of breaks. */
RPT_GETNAME = 80, /* get name of process (data 0=name, 1=path
as started, 2=fullpath). Return in addr
as mem) */
RPT_STOP = 81, /* (C-actors) Stop the C-actor */
RPT_PGETREGS = 82, /* portable version */
RPT_PSETREGS = 83, /* portable version */
RPT_PSETTHREADREGS = 84, /* portable version */
RPT_PGETTHREADREGS = 85 /* portable version */
};
 
#include FRONTEND
 
const MAXDEBUGGEE= 150;
const NAMEMAX = 17;
 
% /*
% * Memory data for read/write text or data. The size is in data. The target
% * addr is in the addr field.
% * Be careful before modifying because this value goes into internal
% * pipes and is allocated on stack too. Pipes and/or the stack could
% * become too small if this value gets incremented.
% */
 
const MEM_DATA_MAX = 256;
 
#ifndef RPC_XDR
 
struct xdr_mem {
u_long addr;
u_int dataNb;
unsigned char data[MEM_DATA_MAX];
};
 
#else
/* manually define best XDR function for this */
%bool_t xdr_xdr_mem(xdrs, objp)
% XDR *xdrs;
% struct xdr_mem *objp;
%{
% if (!xdr_u_long(xdrs, &objp->addr)) {
% return (FALSE);
% }
% if (!xdr_u_int(xdrs, &objp->dataNb)) {
% return(FALSE);
% }
% return (xdr_opaque(xdrs, objp->data, objp->dataNb));
%}
 
#endif
 
/* Breakpoint structure maps to same structure on host. Do not change one
without changing the other. */
 
enum break_type
{ /* types of breakpoints */
BRKT_NONE, /* unused entry */
BRKT_INSTR, /* general instruction break */
BRKT_READ, /* read break */
BRKT_WRITE, /* write breakpoint */
BRKT_ACCESS, /* read-or-write break */
BRKT_EXEC, /* execution HW breakpoint */
BRKT_OS_CALL, /* break on OS call, addr is call number */
BRKT_OS_SWITCH, /* dispatch breakpoint */
BRKT_STEPEMUL /* emulate hardware single-step */
};
const MAX_THRD_BRK = 4; /* enough for 128 threads per process */
struct xdr_break
{ /* one per process local breakpoint */
u_char type; /* BRKT_xxx type of break */
u_char thread_spec; /* 0=all, else count of threads it affects */
u_short handle; /* handle of breakpoint returned */
u_long ee_loc; /* address of start */
u_long ee_type; /* type/method of address */
u_short length; /* length of break if range, else 0 */
u_char pass_count; /* pass count to initialize to (0=none) */
u_char curr_pass; /* pass count current value */
u_long thread_list[MAX_THRD_BRK]; /* bit map for thread list */
}; /* 20 bytes+4 per thread_list (4x4=16) = 36 */
 
const UTHREAD_MAX = 64;
 
const THREADNAMEMAX = 16;
typedef string thread_name <THREADNAMEMAX>;
 
struct KernThread {
unsigned int threadLi;
};
 
#ifndef RPC_XDR
 
#ifdef RPC_HDR
%typedef KernThread *ptThreadList;
#endif
 
struct thread_list {
unsigned int nbThread;
ptThreadList threads;
};
 
#else /* RPC_XDR */
 
/* must write this function by hand */
 
%bool_t xdr_thread_list(xdrs, objp)
% XDR *xdrs;
% struct thread_list *objp;
%{
% return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
% UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
%}
 
#endif /* not RPC_XDR */
 
 
union ptrace_addr_data_in switch (ptracereq req) {
/*
* due to rpcgen poor features, we cannot put RPC_SETREGS
* AND RPC_SETTHREADREGS in the case list. So we use a hack (FIX rpcgen).
*/
#ifndef RPC_HDR
case RPT_SETTHREADREGS :
xdr_regs regs;
#endif
case RPT_SETREGS:
 
xdr_regs regs;
 
#ifndef RPC_HDR
case RPT_PSETTHREADREGS:
u_int pregs<>;
#endif
case RPT_PSETREGS:
u_int pregs<>;
 
#ifdef LATER
case RPT_SETFPREGS:
xdr_fp_status fpregs;
#endif
case RPT_SETTHREADNAME:
thread_name name;
#ifndef RPC_HDR
case RPT_WRITETEXT:
xdr_mem mem;
#endif
case RPT_WRITEDATA:
xdr_mem mem;
case RPT_SETBREAK:
xdr_break breakp;
default:
u_int address;
};
 
union ptrace_addr_data_out switch (ptracereq req) {
case RPT_GETREGS:
xdr_regs regs;
#ifndef RPC_HDR
case RPT_GETTHREADREGS:
xdr_regs regs;
#endif
 
case RPT_PGETREGS:
u_int pregs<>;
 
#ifndef RPC_HDR
case RPT_PGETTHREADREGS:
u_int pregs<>;
#endif
 
#ifdef LATER
case RPT_GETFPREGS:
xdr_fp_status fpregs;
#endif
case RPT_THREADLIST:
thread_list threads;
case RPT_GETTHREADNAME:
thread_name name;
#ifndef RPC_HDR
case RPT_READTEXT:
xdr_mem mem;
case RPT_GETNAME:
xdr_mem mem;
#endif
case RPT_READDATA:
xdr_mem mem;
case RPT_GETBREAK:
xdr_break breakp;
default:
u_int addr;
};
 
typedef opaque CHAR_DATA <NET_SAFE>; /* variable sized data */
 
const XRY_MAX_INST_BUFF = 128;
const XRY_MAX_INSTANCES = 16;
%#ifndef XRY_MAX_CMD_STR
const XRY_MAX_CMD_STR = 320; /* XRY_MAX_INST_BUFF+(XRY_MAX_INSTANCES*12) */
%#endif /* REMDEB_H */
 
 
struct xry_inst
{
unsigned char flags; /* value2 interp, etc. INFL_xxx */
unsigned char type; /* base type of data (str, val, etc) INST_xxx */
unsigned char sub_type; /* specific type (task, res, etc). This is
set and defined by the user defined instance
processor and not the auto-processor */
unsigned char res_type;
u_long value; /* pointer to value or value itself */
u_long value2; /* second value (optional - based on flags) */
};
 
struct instance
{
struct xry_inst instances[XRY_MAX_INSTANCES];
unsigned char buffer[XRY_MAX_INST_BUFF];
};
 
union instance_union switch (bool instances)
{
case TRUE:
instance inst;
case FALSE:
string buffer <XRY_MAX_CMD_STR>;
};
 
typedef string one_arg <NET_SAFE>;
 
const XRY_MAX_OBJ_NAME = 32; /* objname in some commands */
 
% /* now open_connex() routine which establishes a connection to server */
 
enum debug_type
{ /* type of connection requested */
DEBTYP_PROCESS = 0, /* process connection */
DEBTYP_C_ACTOR = 1, /* C-Actor connection */
DEBTYP_KERNEL = 2, /* kernel debug connection */
DEBTYP_OTHER = 3 /* other subsystem */
};
 
%#define DEBUGGER_IS_GDB 0x2 /* */
 
struct open_in
{ /* input args to open a connection */
u_char back_port[16]; /* opaque NET address format */
u_short debug_type; /* type of process DEBTYP_xxx */
u_short flags; /* connection information OPNFLG_xxx */
u_char destination[16];/* opaque address if to router */
one_arg user_name; /* name of user on host */
};
 
struct open_out
{ /* return from open_connex */
u_long port; /* connection number to server or -1 if error */
u_int pad[4]; /* Planned to be KnIpcDest. Never used */
u_int fp; /* True if floating point processor. If error,
set to errno for open error. */
u_char cmd_table_num; /* command table used */
u_char cmd_table_vers; /* version of command table */
u_short server_vers; /* version number of server itself */
};
 
% /* now close_connex() routine which detaches from server */
 
enum close_control
{ /* choice of how to handle owned processes */
CLOSE_IGNORE = 0, /* ignore all controlled pids on close */
CLOSE_KILL = 1, /* kill all controlled pids on close */
CLOSE_DETACH = 2 /* detach free running all controlled pids */
};
 
struct close_in
{ /* arg to close connection */
close_control control; /* shutdown of owned processes control */
};
 
% /* now send_signal() routine which sends signals to processes like kill(2) */
 
struct signal_in
{ /* input to send_signal */
int pid; /* process/actor to send signal to */
int sig; /* signal to send (from /usr/include/signal.h) */
};
 
struct signal_out
{ /* return from send_signal */
int kill_return; /* return code from kill(2) call */
int errNo; /* error code if failed */
};
 
 
% /* now wait_info() routine which returns results of polling the wait status
% of a process/actor. It may return 0 if running, else pid or -1 */
 
enum stop_code
{ /* stop code information */
STOP_ERROR = 0, /* error, errno set */
STOP_NONE = 1, /* not stopped */
STOP_UNKNOWN = 2, /* unknown stop reason */
STOP_BREAK = 3, /* stopped on breakpoint */
STOP_STEP = 4, /* stopped on step */
STOP_SIGNAL = 5, /* stopped on signal receieve */
STOP_TERM_EXIT = 6, /* terminated normally */
STOP_TERM_SIG = 7, /* terminated by signal */
STOP_DETACHED = 8, /* detached from server */
STOP_KILLED = 9, /* killed by ptrace KILL */
STOP_SPAWN_FAILED = 10 /* spawn failed in exec part, handle=errno */
};
 
struct wait_in
{ /* input arg to wait is process */
int pid; /* process/actor id */
};
 
struct wait_out
{ /* result of wait_info call */
int wait_return; /* -1=error,0=running,pid=stopped */
int errNo; /* error code if error */
int status; /* wait(2) status if stopped */
stop_code reason; /* reason in more abstracted terms */
int handle; /* handle of break if stopped on break,
or signal number or exit code */
u_long PC; /* program counter if stopped */
u_long SP; /* stack pointer if stopped */
u_long FP; /* frame pointer if stopped */
u_long thread; /* thread that stopped if applies (else -1) */
};
 
% /* now ptrace() routine. This matches the Sun UNIX ptrace as well as
% some additions */
 
const PTRFLG_FORCE = 1; /* when set and process running, forces process
to stop, make the request, then start again.
This is used for breakpoints and the like */
const PTRFLG_NON_OWNER = 2; /* do request even if not primary owner (will
notify all owners including caller if owns) */
const PTRFLG_FREE = 4; /* free pid_list after KILL/DETACH */
 
const PTRDET_UNOWN = 0x100; /* data value in RPT_DETACH just disconnects
caller as an owner of process. */
 
struct ptrace_in
{ /* input args matches ptrace but for XDR */
int pid; /* process to act on */
ptrace_addr_data_in addr; /* mappings for addr and addr2 */
u_int data; /* simple data arg of ptrace */
u_int flags; /* mask of PTRFLG_xxx flags. */
};
 
struct ptrace_out
{ /* return information from ptrace */
ptrace_addr_data_out addr; /* return through addr/addr2 */
int result; /* result of ptrace call (return value) */
int errNo; /* error code if error */
};
 
/* Data for GET_GLOBAL_SYMBOLS */
struct one_symbol { /* Must match common/src/lib/ctx/ctx.h */
string symbolName<>;
long symbolValue;
};
 
typedef one_symbol all_symbols<>;
 
struct get_global_symbols_out {
all_symbols symbols;
};
 
/* Data for GET_TEXT_DATA */
struct get_text_data_in {
int pid; /* process/actor id if non-zero */
string actorName<16>; /* actor name for system mode */
};
 
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
 
/* Data for GET_SIGNAL_NAMES */
struct one_signal {
u_int number;
string name<>;
};
 
typedef one_signal all_signals<>;
 
struct get_signal_names_out {
all_signals signals;
};
 
% /* now define the actual calls we support */
 
program REMOTEDEB {
version REMOTEVERS {
 
/* open a connection to server or router */
open_out
OPEN_CONNEX(open_in) = 1;
 
/* send a signal to a process */
signal_out
SEND_SIGNAL(signal_in) = 2;
 
/* all routines below require a connection first */
 
/* close the connection to the server */
void
CLOSE_CONNEX(close_in) = 10;
 
/* process ptrace request */
ptrace_out
PTRACE(ptrace_in) = 11;
/* poll for status of process */
wait_out
WAIT_INFO(wait_in) = 13;
 
get_signal_names_out
GET_SIGNAL_NAMES(void) = 17;
 
} = 2; /* now version 2 */
} = 0x20000fff;
 
#ifdef RPC_HDR
%#define REMDEB_H
%#endif
#endif
 
#ifdef RPC_SVC
 
%const char* names [] = {
% "NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
% "name4", "name5", "name6", "name7",
% "name8", "name9", "CLOSE_CONNEX", "PTRACE",
% "name12", "WAIT_INFO", "name14", "name15",
% "name16", "GET_SIGNAL_NAMES", "name18"
%};
%
 
%/*HEADER_END*/
#endif
/excep.c
0,0 → 1,136
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbgexcep.c
*
* $Id: excep.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
 
unsigned int NbExceptCtx;
volatile unsigned int NbSerializedCtx;
Exception_context *FirstCtx = NULL;
Exception_context *LastCtx = NULL;
 
CPU_Exception_frame SavedContext;
 
 
/********* Save an exception context at the end of a list *****/
 
int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) {
 
Exception_context *SaveCtx;
 
SaveCtx = (Exception_context *)malloc(sizeof(Exception_context));
if (SaveCtx == NULL)
rtems_panic("Can't allocate memory to save Exception context");
SaveCtx->id = Id;
SaveCtx->ctx = ctx;
SaveCtx->semaphoreId = semId;
SaveCtx->previous = NULL;
SaveCtx->next = NULL;
if (FirstCtx == NULL){ /* initialization */
FirstCtx = SaveCtx;
LastCtx = SaveCtx;
NbExceptCtx = 1;
}
else {
NbExceptCtx ++;
LastCtx->next = SaveCtx;
SaveCtx->previous = LastCtx;
LastCtx = SaveCtx;
}
return 0;
}
 
/********* Save an temporary exception context in a ******/
/********* global variable ******/
 
int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) {
 
memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame));
return 0;
}
 
 
/****** Remove the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
 
 
int PopExceptCtx ( Objects_Id Id ) {
 
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return -1;
if (Id == -1) {
ExtractCtx = LastCtx;
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
 
if (ExtractCtx == NULL)
return -1;
 
if ( ExtractCtx->previous != NULL)
(ExtractCtx->previous)->next = ExtractCtx->next;
 
if ( ExtractCtx->next != NULL)
(ExtractCtx->next)->previous = ExtractCtx->previous;
 
if (ExtractCtx == FirstCtx)
FirstCtx = FirstCtx->next;
else
if (ExtractCtx == LastCtx)
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
/****** Return the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
 
 
Exception_context *GetExceptCtx ( Objects_Id Id ) {
 
Exception_context *ExtractCtx;
 
if (FirstCtx == NULL) return NULL;
if (Id == -1) {
return LastCtx;
}
ExtractCtx = LastCtx;
 
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
 
if (ExtractCtx == NULL)
return NULL;
 
return ExtractCtx;
}
/servrpc.c
0,0 → 1,722
/*
**********************************************************************
*
* Component: RDBG
* Module: servrpc.c
*
* Synopsis: support routines for RPC dispatch for remote debug server.
* Main server dispatch routines from RPC to support remote debug.
*
* $Id: servrpc.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**********************************************************************
*/
 
#include <string.h>
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/remdeb.h>
#include <rdbg/servrpc.h>
 
/************************************************************************/
 
/* -----------------------------------------------------------------------
open_connex_2_svc - setup a new connection from a client.
 
Notes:
- this function creates a new connection to a client. It allocates
an entry in the connection structure and fills in the information
sent and implied by the message.
- a client connection entry is needed for all further messages to work
properly.
----------------------------------------------------------------------- */
 
open_out* RPCGENSRVNAME(open_connex_2_svc) (open_in *in, struct svc_req *rqstp)
{
static open_out out; /* output response. This could be heap local */
int idx;
static int one_time = 0; /* we do one-time setup on back port */
 
/* need to support in->debug_type, in->flags, and in->destination!!! */
 
if (!one_time)
{ /* only setup one backport socket */
/* now setup signals and the like for handling process changes */
setErrno(0);
TspInit(rqstp->rq_xprt->xp_sock); /* init transport system */
if (getErrno())
{ /* failed in setup */
out.port = (u_long)-1;
out.fp = getErrno(); /* error causing to fail */
return(&out); /* fail */
}
one_time = True; /* disable doing this again */
}
 
DPRINTF(("open_connex_2_svc: Opening connection from '%s'\n",
in->user_name));
 
/* now setup a validation of all other connections */
for (idx = 0; idx < conn_list_cnt; idx++)
if (conn_list[idx].in_use)
{ /* setup retry timer */
DPRINTF(("open_connex_2_svc: Still have connection %d with port %d\n",
idx, HL_W(*((UINT16*)&conn_list[idx].back_port.c[2]))));
}
 
idx = ConnCreate(rqstp, in); /* setup the connection */
out.port = idx; /* connection number */
if (idx == -1)
out.fp = getErrno(); /* error causing to fail */
else
out.fp = TARGET_PROC_TYPE;
 
out.server_vers = SERVER_VERS;
return(&out);
}
 
/* -----------------------------------------------------------------------
send_signal_2_svc - send a kill/signal to the specified process.
 
Notes:
- this function sends a signal to the process specified. This process
does not have to be under debug nor attached by this server. The kill
may be refused on other grounds though.
- kill(pid, 0) can be used to validate the process still exists if
needed.
----------------------------------------------------------------------- */
 
signal_out *RPCGENSRVNAME(send_signal_2_svc) (signal_in *in, struct svc_req *rqstp)
{
static signal_out out; /* return code from kill */
 
/* we do not care if connected */
setErrno(0);
out.kill_return = 0;
out.errNo = 0;
TotalReboot = 1;
return(&out);
}
 
/* -----------------------------------------------------------------------
close_connex_2_svc - close a connection from a client.
----------------------------------------------------------------------- */
 
void *RPCGENSRVNAME(close_connex_2_svc) (close_in *in, struct svc_req *rqstp)
{
int conn_idx = TspConnGetIndex(rqstp);
 
if (conn_idx != -1) /* found it, clear out */
ConnDelete(conn_idx, rqstp, in->control);
 
return (void*) ""; /* need to return something */
}
 
/* -----------------------------------------------------------------------
ptrace_2_svc - control process under debug.
----------------------------------------------------------------------- */
 
#define REG_COUNT \
(sizeof (xdr_regs) / sizeof (int))
 
ptrace_out *RPCGENSRVNAME(ptrace_2_svc) (ptrace_in *in, struct svc_req *rqstp)
{
int conn_idx = rqstp ? TspConnGetIndex(rqstp) : -1;
static ptrace_out out; /* outut response (error or data) */
void *addr, *addr2; /* used for actual ptrace call */
unsigned int data;
int req, pid, ret, pid_idx, idx;
static union
{ /* local buffer for returned data */
Objects_Id t_list[UTHREAD_MAX]; /* thread_list return */
char t_name[THREADNAMEMAX]; /* thread name return */
} local_buff; /* for return handling of strings and the like */
PID_LIST *plst = NULL; /* current pid_list entry */
 
DPRINTF (("ptrace_2_svc: entered (%s (%d), %d, XXXX, %d, XXXX)\n",
PtraceName (in->addr.req), in->addr.req, in->pid,
in->data));
 
out.addr.ptrace_addr_data_out_u.addr = 0;
 
/* validate the connection */
if (conn_idx == -1 && rqstp != NULL)
{ /* no connection, error */
DPRINTF(("ptrace_2_svc: msg from unknown debugger!\n"));
out.result = -1;
out.errNo = ECHILD; /* closest error */
out.addr.req = 0; /* to avoid copies that should not occur */
return(&out);
}
/* Consider that the last back-message is acknowledged */
if (conn_idx >= 0 && conn_list[conn_idx].retry) {
TspMessageReceive(conn_idx, in->pid);
}
 
req = in->addr.req;
out.addr.req = req; /* needed for RPC */
pid = in->pid;
addr = addr2 = NULL;
data = in->data;
setErrno(0); /* assume works */
out.result = 0; /* assume worked ok */
out.errNo = 0;
 
/* lookup process to make sure we have under control */
pid_idx = FindPidEntry (in->pid);
if (pid_idx >= 0) /* found it */
{
plst = &pid_list[pid_idx];
if (conn_idx < 0)
conn_idx = plst->primary_conn;
}
 
/* now we handle the special case of ATTACH to a pid we already control */
if (req == RPT_ATTACH)
{ /* look it up first */
if (plst)
{ /* we have controlled , so return ok+show conn */
ret = 2; /* normally secondary connection */
if (! PIDMAP_TEST (conn_idx, pid_idx))
{ /* mark as an owner if not already */
plst->owners++;
PIDMAP_SET (conn_idx, pid_idx); /* mask in */
}
else if (plst->primary_conn != NO_PRIMARY)
{ /* regrab makes primary */
/* Only if not primary already */
if (plst->primary_conn != conn_idx) {
TspSendWaitChange(plst->primary_conn, BMSG_NOT_PRIM,
conn_idx, plst->pid, 0, False); /* tell old owner */
}
plst->primary_conn = NO_PRIMARY;
}
 
if (plst->primary_conn == NO_PRIMARY)
{ /* none now, so take over */
plst->primary_conn = conn_idx; /* new primary */
ret = 1; /* primary */
}
out.result = ret; /* primary or secondary owner */
return(&out);
}
/* else attach process using target code */
setErrno(ESRCH); /* assume the worst */
if (!TgtAttach(conn_idx, pid))
{ /* failed */
out.errNo = getErrno();
out.result = 0;
}
return(&out);
}
else if (req == RPT_DETACH)
{ /* see which kind of detach */
if (data == PTRDET_UNOWN)
{ /* only want to disconnect from */
TgtDetachCon(conn_idx, pid_idx, True); /* remove from control */
return(&out); /* done */
}
}
else if (plst && (req == RPT_GETNAME || req == RPT_GETBREAK))
{
/* do nothing */
}
 
else if (plst && req == RPT_CLRBREAK) {
/* To be able to remove breakpoints from a "running" system */
DPRINTF (("ptrace_2_svc: allowing RPT_CLRBREAK %d\n", data));
/* do nothing */
}
 
else if (plst && plst->running)
{ /* error, process is running and not detach */
out.result = -1;
out.errNo = ETXTBSY; /* closest error */
DPRINTF (("ptrace_2_svc: failed, still running.\n"));
return(&out);
}
if (plst == NULL) {
out.result = -1;
out.errNo = ESRCH;
DPRINTF (("ptrace_2_svc: No such process.\n"));
return (&out);
}
 
/* now make sure secondary owner is not trying to modify */
if (!(in->flags & PTRFLG_NON_OWNER)) /* if not overriden */
if (conn_idx != plst->primary_conn
&& ( (req >= RPT_POKETEXT && req <= RPT_SINGLESTEP)
|| (req >= RPT_SETREGS && req <= RPT_SETFPAREGS && (req & 1))
|| (req >= RPT_SYSCALL && req <= RPT_DUMPCORE)
|| (req >= RPT_SETTARGETTHREAD && req <= RPT_THREADRESUME)
|| (req >= RPT_SETTHREADNAME && req <= RPT_SETTHREADREGS)
|| (req >= RPT_STEPRANGE && req <= RPT_CLRBREAK)
|| (req == RPT_STOP)
|| (req >= RPT_PSETREGS && req <= RPT_PSETTHREADREGS)))
{ /* not owner */
out.result = -1;
out.errNo = EPERM; /* cannot alter as not primary */
DPRINTF (("ptrace_2_svc: refused, not owner, flags %d conn_idx %d primary_conn %d\n", in->flags, conn_idx,
plst->primary_conn));
return(&out);
}
 
addr = (void *)in->addr.ptrace_addr_data_in_u.address; /* default */
/* now setup normal ptrace request by unpacking. May execute here. */
switch (req)
{ /* handle unpacking or setup for real call */
/* first the ones where addr points to input data */
case RPT_SETREGS:
case RPT_SETTHREADREGS:
addr = (void *)&in->addr.ptrace_addr_data_in_u.regs; /* reg list */
break;
 
case RPT_PSETREGS:
case RPT_PSETTHREADREGS:
if (in->addr.ptrace_addr_data_in_u.pregs.pregs_len != REG_COUNT) {
DPRINTF(("ptrace_2_svc: pid %d got %d expected %d\n", pid,
in->addr.ptrace_addr_data_in_u.pregs.pregs_len, REG_COUNT));
setErrno(EINVAL);
break;
}
req = req == RPT_PSETREGS ? RPT_SETREGS : RPT_SETTHREADREGS;
addr = (void *) in->addr.ptrace_addr_data_in_u.pregs.pregs_val;
break;
 
case RPT_SETTHREADNAME:
addr = (void *)in->addr.ptrace_addr_data_in_u.name;
break;
case RPT_WRITETEXT:
case RPT_WRITEDATA:
if ((int) data < 0) {
setErrno(EINVAL);
break;
}
addr = (void *)in->addr.ptrace_addr_data_in_u.mem.addr; /* targ addr */
addr2 = (void *)in->addr.ptrace_addr_data_in_u.mem.data; /* buff */
 
/* Forbid writing over breakpoints */
if (BreakOverwrite (plst, addr, data)) {
setErrno(EBUSY);
}
break;
 
case RPT_POKETEXT:
case RPT_POKEDATA:
/* Forbid writing over breakpoints */
if (BreakOverwrite (plst, addr, sizeof (int))) {
setErrno(EBUSY);
}
break;
 
/* now ones where we handle locally */
case RPT_GETTARGETTHREAD:
out.result = plst->thread;
req = 0; /* force exit */
break;
 
case RPT_PGETREGS: /* return from our buffer */
out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;
out.addr.ptrace_addr_data_out_u.pregs.pregs_val = (u_int*) &plst->regs;
req = 0; /* force exit */
break;
 
case RPT_GETREGS:
/* return directly from our buffer */
/* this buffer is refreshed when changing target thread */
out.addr.ptrace_addr_data_out_u.regs = plst->regs;
req = 0; /* force exit */
break;
 
case RPT_SETBREAK:
idx = BreakSet (plst, conn_idx, &in->addr.ptrace_addr_data_in_u.breakp);
if (idx < 0) break;
req = 0; /* force exit */
out.result = idx; /* return break index (>0) */
break;
case RPT_CLRBREAK:
if (conn_list[conn_idx].flags & DEBUGGER_IS_GDB) {
data = BreakGetIndex (plst, addr);
}
out.result = BreakClear (plst, conn_idx, data);
/* if errored, errno will still be set */
req = 0;
break;
 
case RPT_GETBREAK:
/* data=handle, addr=in_buffer, returns next break. Data=0, returns cnt */
out.result = BreakGet (plst, data, &out.addr.
ptrace_addr_data_out_u.breakp);
req = 0; /* handle locally */
break;
 
case RPT_GETNAME: /* get the name of the process */
if (!plst->name)
out.addr.ptrace_addr_data_out_u.mem.dataNb = 0;
else
{
int maxLen = sizeof out.addr.ptrace_addr_data_out_u.mem.data - 1;
data = strlen(plst->name);
if (data > maxLen)
data = maxLen;
out.addr.ptrace_addr_data_out_u.mem.dataNb = data+1;
memcpy(out.addr.ptrace_addr_data_out_u.mem.data, plst->name, data+1);
out.addr.ptrace_addr_data_out_u.mem.data [maxLen] = '\0';
}
req = 0;
break;
 
case RPT_CONTTO:
if (BreakSetAt (plst, conn_idx, (u_long) addr, BRKT_STEPEMUL) < 0)
{
DPRINTF(("ptrace_2_svc: BreakSet failed at %x", addr));
break;
}
req = RPT_CONT;
/* data can contain a signal number, addr2 is unused */
goto case_RPT_CONT;
 
case RPT_STEPRANGE:
/* convert to step */
if (!data)
data = 1; /* should we give an error?? */
BreakStepRange (plst, addr, data);
if (getErrno()) break;
 
req = RPT_SINGLESTEP; /* do by stepping */
addr = (void*) 1; /* start from current PC */
data = -2; /* want non-atomic stepping */
/* fall through to other exec cases */
 
case RPT_CONT:
case_RPT_CONT:
case RPT_SINGLESTEP:
 
if (BreakStepOff (plst, &addr2))
{ /* need clear then step off break */
/* clear break, step, then do exec */
if (addr == (void*) 1)
addr = (void*) plst->regs.REG_PC;/* need for patch */
 
/* data is always 0, so atomic single-step */
} else if (req == RPT_SINGLESTEP) {
data = -2; /* want non-atomic stepping */
}
break;
 
/* now ones where addr points to an output area */
case RPT_PGETTHREADREGS:
addr = (void*) out.addr.ptrace_addr_data_out_u.mem.data;
if (sizeof out.addr.ptrace_addr_data_out_u.mem.data <
REG_COUNT * sizeof(int)) {
setErrno(EINVAL);
break;
}
if (data == plst->thread) {
out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;
out.addr.ptrace_addr_data_out_u.pregs.pregs_val = (u_int*) &plst->regs;
req = 0; /* force exit */
break;
}
req = RPT_GETTHREADREGS;
break;
 
case RPT_GETTHREADREGS:
addr = (void*) &out.addr.ptrace_addr_data_out_u.regs;
break;
case RPT_GETTHREADNAME:
out.addr.ptrace_addr_data_out_u.name = local_buff.t_name;
addr = (void*) out.addr.ptrace_addr_data_out_u.name;
break;
case RPT_THREADLIST:
out.addr.ptrace_addr_data_out_u.threads.threads =(ptThreadList) local_buff.t_list;
addr = (void*) out.addr.ptrace_addr_data_out_u.threads.threads;
break;
case RPT_READTEXT:
case RPT_READDATA:
if ((int) data < 0) {
setErrno(EINVAL);
break;
}
addr = (void *)in->addr.ptrace_addr_data_in_u.address;
addr2 = (void *)out.addr.ptrace_addr_data_out_u.mem.data;
out.addr.ptrace_addr_data_out_u.mem.dataNb = data;
break;
case RPT_DETACH:
/* Do not allow detaching if breakpoints still there */
if (BreakGet (plst, 0, NULL))
{ /* some bkpts still set */
setErrno(EINVAL); /* cannot detach safely */
break;
}
/* fall through */
case RPT_KILL:
/* in the event they are trying to detach or kill a terminated process,
we just delete the entry. */
if (PROC_TERMINATED (plst))
{
TgtDelete(plst, -1, BMSG_KILLED); /* just blow off */
req = 0; /* now exit */
}
break;
}
 
if (getErrno())
{ /* failed in code above */
out.result = -1;
out.errNo = getErrno();
DPRINTF(("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));
return(&out);
}
else if (!req)
{ /* bail out now */
DPRINTF(("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));
return(&out);
}
 
/* OK, make the call */
out.result = TgtPtrace(req, pid, addr, data, addr2);
out.errNo = getErrno();
 
/* if no error, cleanup afterwards */
if (getErrno())
{
/* Remove step-emul breakpoints if any */
if (req == RPT_SINGLESTEP || req == RPT_CONT) {
BreakClear (plst, -1, -1);
}
DPRINTF(("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));
return(&out); /* return error */
}
 
switch (in->addr.req)
{ /* handle some special calls that affect state */
case RPT_CONT:
case RPT_STEPRANGE:
/* change to running */
if (in->addr.req == RPT_STEPRANGE)
plst->last_start = LAST_RANGE; /* so range steps */
else if (addr2)
plst->last_start = LAST_STEPOFF; /* now continue after wait */
else
plst->last_start = LAST_CONT;
plst->running = 1; /* mark as running */
if (!rqstp) /* Called internally to restart bkpt, no msg to anybody */
break;
TgtNotifyAll(pid_idx, BMSG_WAIT, 0, 0, (in->flags & PTRFLG_NON_OWNER)
? -1 : conn_idx, True);
break;
case RPT_SINGLESTEP:
/* mark as step */
plst->last_start = LAST_STEP; /* so we know how started */
plst->running = 1; /* mark as running (wait should catch fast) */
break;
case RPT_DETACH: /* mark as disconnected */
case RPT_KILL: /* mark as killed */
if (in->flags & PTRFLG_FREE) /* notify and delete entry */
TgtDelete(plst, -1, (in->addr.req==RPT_KILL) ? BMSG_KILLED : BMSG_DETACH);
else
{ /* notify and mark */
plst->last_start = (in->addr.req==RPT_KILL) ?
LAST_KILLED : LAST_DETACHED;
plst->state = -1;
plst->running = False;
TgtNotifyAll(pid_idx, (in->addr.req==RPT_KILL) ?
BMSG_KILLED : BMSG_DETACH, 0, 0, -1, True);
}
break;
case RPT_SETTHREADREGS:
case RPT_PSETTHREADREGS:
if (data != plst->thread)
break;
DPRINTF(("ptrace_2_svc: pid %d target thread regs changed!\n", pid));
 
case RPT_SETREGS:
case RPT_PSETREGS:
/* change our buffer as well */
if (plst->regs.REG_PC != ((xdr_regs*)addr)->REG_PC)
BreakPcChanged (plst);
plst->regs = *(xdr_regs*) addr; /* copy in */
break;
 
/* case RPT_PGETREGS has been handled locally above */
case RPT_PGETTHREADREGS:
/* We need to update pointer so that XDR works on return */
out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;
out.addr.ptrace_addr_data_out_u.pregs.pregs_val =
(void*) out.addr.ptrace_addr_data_out_u.mem.data;
break;
 
case RPT_PEEKTEXT:
case RPT_PEEKDATA:
case RPT_READDATA:
case RPT_READTEXT:
if (req < RPT_READDATA)
{ /* peek */
/* addr is start */
data = sizeof(int);
addr2 = &out.result; /* data buffer */
/* Like read: addr is start, data is length, addr2 is buffer */
}
BreakHide (plst, addr, data, addr2);
break;
 
case RPT_SETTARGETTHREAD:
DPRINTF(("ptrace_2_svc: pid %d new target thread %d\n", pid, data));
TgtPtrace (RPT_GETREGS, pid, (char*) &plst->regs, 0, NULL);
plst->thread = data;
if (plst->break_list) { /* Forget we had to step off breakpoint */
BASE_BREAK* base = (BASE_BREAK*) plst->break_list;
DPRINTF(("ptrace_2_svc: clr_step %d last_break %d\n", base->clr_step,
base->last_break));
base->clr_step = 0; /* Not stopped on break */
base->last_break = 0;
}
break;
 
case RPT_THREADLIST:
out.addr.ptrace_addr_data_out_u.threads.nbThread = out.result;
break;
 
default:
break;
} /* end switch */
DPRINTF(("ptrace_2_svc 2: result %d errNo %d\n", out.result, out.errNo));
return(&out);
}
 
/* -----------------------------------------------------------------------
wait_info_2_svc - non-blocking wait request to check status.
----------------------------------------------------------------------- */
 
wait_out *RPCGENSRVNAME(wait_info_2_svc) (in, rqstp)
wait_in *in;
struct svc_req *rqstp; /* server info */
{
int conn_idx = TspConnGetIndex(rqstp);
static wait_out out; /* output of pid and status */
int idx;
PID_LIST *plst;
 
memset(&out, 0, sizeof(out)); /* zero for safety */
out.reason = STOP_ERROR; /* assume the worst */
 
if (conn_idx == -1)
{ /* no connection, error */
DPRINTF(("wait_info_2_svc: msg from unknown debugger!\n"));
out.wait_return = -1;
out.errNo = ECHILD; /* closest error */
return(&out);
}
else
{ /* see if confirming message received */
if (conn_list[conn_idx].retry)
TspMessageReceive(conn_idx, in->pid);
}
 
if (!in->pid)
{ /* warm test verify only */
/* this call (pid==0) is made to confirm that that connection is still
active. */
/* we let it fall through as an error since any use other than connection
reset would be an error (there is no pid0). */
}
else
{ /* normal request */
idx = FindPidEntry (in->pid);
if (idx >= 0)
{ /* found process they requested on */
plst = &pid_list[idx];
out.wait_return = plst->running ? 0 : in->pid;
/* return: 0 is running, pid is stopped/term */
out.errNo = 0;
out.status = plst->state; /* last stopped reason if stopped */
out.thread = plst->thread;/* current thread (or -1 if none) from stop */
if (!out.wait_return)
out.reason = STOP_NONE; /* running, no action */
else if (STS_SIGNALLED (out.status))
{ /* stopped on signal */
out.handle = STS_GETSIG (out.status); /* signal number */
if (out.handle == SIGTRAP)
if (plst->is_step)
{ /* single step with hitting a break */
out.reason = STOP_STEP;
out.handle = 0; /* no information */
}
else
{ /* stopped on break */
out.reason = STOP_BREAK;
if (plst->break_list)
out.handle = ((BASE_BREAK*)plst->break_list)->last_break;
else
out.handle = 0; /* no break */
}
else
out.reason = STOP_SIGNAL;
out.PC = plst->regs.REG_PC; /* copy standard regs */
out.SP = plst->regs.REG_SP;
out.FP = plst->regs.REG_FP;
}
else
{ /* terminated, so lower use count */
if (plst->last_start == LAST_KILLED)
out.reason = STOP_KILLED;
else if (plst->last_start == LAST_DETACHED)
out.reason = STOP_DETACHED;
else if (plst->last_start == LAST_START)
{ /* failed in exec */
out.reason = STOP_SPAWN_FAILED;
out.handle = STS_GETCODE (out.status); /* errno reason */
}
else if (STS_TERMONSIG (out.status))
{ /* terminated on signal */
out.reason = STOP_TERM_SIG;
/* mask off the core-dumped bit 7 */
out.handle = (int)(unsigned)(u_char) STS_TERMGETSIG (out.status);
}
else
{ /* exit(2)ed */
out.reason = STOP_TERM_EXIT;
out.handle = STS_GETCODE (out.status); /* code */
}
}
DPRINTF(("wait_info_2_svc: pid %d return %d status %x errNo %d"
" reason %d handle %d pc %x sp %x fp %x thread %d\n",
in->pid, out.wait_return, out.status, out.errNo, out.reason,
out.handle, out.PC, out.SP, out.FP, out.thread));
return(&out);
}
}
/* if not found in list, we return error: no such process */
out.wait_return = -1;
out.errNo = ESRCH; /* no process */
out.status = 0;
return(&out);
}
 
/* -----------------------------------------------------------------------
get_signal_names_2_svc - return names for signals
----------------------------------------------------------------------- */
 
static one_signal SignalNames[] = {
{SIGILL, "SIGILL/EVT_ILL"},
{SIGTRAP, "SIGTRAP/EVT_BKPT"},
{SIGFPE, "SIGFPE/EVT_FPE"},
{SIGKILL, "SIGKILL/EVT_AKILL"},
{SIGSEGV, "SIGSEGV/EVT_SEGV"},
{17, "SIGSTOP"},
{23, "SIGSTOP"}
};
 
get_signal_names_out* RPCGENSRVNAME(get_signal_names_2_svc) (in, rqstp)
void* in;
struct svc_req *rqstp; /* server info */
{
static get_signal_names_out out;
 
out.signals.all_signals_len = sizeof SignalNames / sizeof SignalNames[0];
out.signals.all_signals_val = SignalNames;
 
return(&out);
}
/servtsp.c
0,0 → 1,331
/*
**************************************************************************
*
* Component: RDBG
* Module: servtsp.c
*
* Synopsis: Transport management for remote debug server.
*
* $Id: servtsp.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <signal.h>
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <netinet/in.h>
#include <sys/socket.h>
 
static int out_sock;
static int warm_test;
 
static void TimeTestHandler();
 
/*
* TspInit - Initialize the transport system.
*
*/
 
void
TspInit (int id)
{
struct sigaction sa;
 
/* setup a socket to send event messages back through */
out_sock = socket (PF_INET, SOCK_DGRAM, 0);
if (out_sock < 0) {
DPRINTF (("TspInit: socket() failed %d errno %d\n",
out_sock, getErrno()));
return; /* failed to open socket, let caller deal with */
}
{
struct sockaddr_in addr;
 
bzero ((void *)(&addr), sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = htons (BackPort);
if (bind (out_sock, (struct sockaddr*) &addr, sizeof addr) < 0) {
DPRINTF (("TspInit: bind() failed\n"));
}
}
/* setup alarm timer for warm testing */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = TimeTestHandler;
sigaction (SIGALRM, &sa, 0);
}
 
/*
* TspTranslateRpcAddr - translate from an RPC handle to an
* opaque address.
*
* Converts the sender's address into the opaque data structure
* used for network addresses. This is used to look up the sender
* on each call.
*/
 
Boolean
TspTranslateRpcAddr (struct svc_req* rqstp, NET_OPAQUE* opaque)
{
struct sockaddr_in* addr; /* used as template to extract net info */
unsigned char* up;
 
memset (opaque, 0, sizeof (NET_OPAQUE));
/*
* We interpret the remote address as a standard netbuf name.
* The format is 2 bytes of address family (normally AF_INET)
* and then a length (5) and then the IP address.
*/
if (rqstp->rq_xprt->xp_addrlen != 16)
{
DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));
setErrno (EPROTONOSUPPORT);
return False; /* invalid, so fails */
}
/* addr = &rqstp->rq_xprt->xp_raddr; */
addr = svc_getcaller (rqstp->rq_xprt);
/* verify it is AF_INET */
if (addr->sin_family != AF_INET) { /* no, error */
DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));
setErrno (EAFNOSUPPORT);/* invalid addr family */
return False;
}
/* good address type */
up = (unsigned char *) &addr->sin_addr.s_addr;
DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",
up[0], up[1], up[2], up[3], htons (addr->sin_port)));
memcpy (opaque, addr, sizeof (struct sockaddr_in));
return True;
}
 
/*
* TspValidateAddr - validate a passed in opaque address.
*
* Checks that the passed in address is in the format
* expected.
*/
 
Boolean
TspValidateAddr (NET_OPAQUE* opaque, NET_OPAQUE* sender)
{
struct sockaddr_in* addr; /* used as template to extract net info */
 
addr = (struct sockaddr_in*) opaque;
/* Verify it is AF_INET. Should check against sender IP address too */
if (addr->sin_family != AF_INET) {
DPRINTF (("TspValidateAddr: Back port invalid: %d\n",
htons (addr->sin_port)));
return False; /* not valid */
}
/* otherwise, we copy in the IP address, since client may not know it */
addr->sin_addr.s_addr = ((struct sockaddr_in*) sender)->sin_addr.s_addr;
DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));
return True;
}
 
/*
* TspConnGetIndex - lookup an rpc caller's address as a connection entry.
*
* Looks up an ip address of a caller to locate the
* connection index in our connection array.
*/
 
int
TspConnGetIndex (struct svc_req* rqstp)
{
int conn;
/* &rqstp->rq_xprt->xp_raddr; */
struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);
 
for (conn = 0; conn < conn_list_cnt; conn++) {
if (!conn_list[conn].in_use)
continue; /* not used */
 
if (addr->sin_addr.s_addr == ((struct sockaddr_in *)
&conn_list [conn].sender)->sin_addr.s_addr
&& addr->sin_port == ((struct sockaddr_in *)
&conn_list[conn].sender)->sin_port) {
return conn;
}
}
return -1;
}
 
 
/*
* TspSendWaitChange - send wait-change message to clients to
* notify change.
*/
 
void
TspSendWaitChange(
int conn, /* connection to send to */
BACK_MSG msg, /* BMSG type */
UINT16 spec, /* special information */
PID pid, /* pid it refers to */
UINT32 context, /* additional context for message */
Boolean force) /* force into being only message */
{
int idx;
struct SEND_LIST* snd_ptr;
 
if (force) {
/* force to top, which means others gone */
idx = 0;
conn_list [conn].send_idx = 1;
conn_list[conn].retry = 0;
} else {
for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {
if (conn_list[conn].send_list[idx].send_type == msg
&& conn_list[conn].send_list[idx].pid == pid)
return; /* already pended for this pid */
}
idx = conn_list[conn].send_idx;
if (idx+1 > MAX_SEND)
return; /* we lose it, what should we do??? */
conn_list[conn].send_idx++;
}
snd_ptr = &conn_list[conn].send_list[idx];
snd_ptr->send_type = msg; /* message to send */
snd_ptr->retry = TSP_RETRIES; /* about 1 minute of retries */
snd_ptr->spec = htons ((u_short) spec);
snd_ptr->pid = htonl (pid);
snd_ptr->context = htonl (context);
TspSendMessage (conn, False); /* now do the send */
}
 
/*
* TspSendMessage - send message at top of send list for connection.
*/
 
void
TspSendMessage( int conn, Boolean resend)
{
struct sockaddr_in addr;
struct UDP_MSG msg;
int cnt;
 
if (!resend && conn_list[conn].retry)
return; /* already waiting for reply */
 
/*
* Note on above: if no back port we can't remove unless
* someone blows off.
*/
if (!resend) {
/* first time, setup. Set retry count: */
conn_list[conn].retry = conn_list[conn].send_list[0].retry;
conn_list[conn].last_msg_num++; /* new sequence number */
if (!warm_test++) { /* starting, so enable timer */
alarm (2); /* resend every 2 seconds as needed */
}
}
 
msg.type = conn_list[conn].send_list[0].send_type;
msg.msg_num = conn_list[conn].last_msg_num;
msg.spec = conn_list[conn].send_list[0].spec;
msg.pid = conn_list[conn].send_list[0].pid;
msg.context = conn_list[conn].send_list[0].context;
 
memset (&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = ((struct sockaddr_in*)&conn_list[conn].back_port)->sin_port;
addr.sin_addr.s_addr =
((struct sockaddr_in*)&conn_list[conn].back_port)->sin_addr.s_addr;
 
DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",
msg.type, BmsgNames [msg.type], HL_W (addr.sin_port)));
 
cnt = sendto (out_sock, &msg, sizeof msg, 0, (struct sockaddr*) &addr,
sizeof addr);
if (cnt != sizeof msg) { /* failed on send */
printf ("%s: Failed to send msg %d to conn %d (%d vs. %d)\n",
ActName, msg.type, conn, cnt, sizeof msg);
}
}
 
/*
* TspMessageReceive - confirmation received, now send next if any.
*
* - since UDP is connectionless, we batch up the sends and use
* one at a time until we get a message indicating ready for
* next (from ack).
*/
 
void
TspMessageReceive (int conn, PID pid)
{
/* We remove the send list entry and use next if any */
conn_list[conn].retry = 0; /* reset */
if (!warm_test || !--warm_test) {
alarm (0); /* reset timer if not used */
}
#ifdef DDEBUG
if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {
DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));
}
#endif
/* Move up by one if needed */
if (!--conn_list[conn].send_idx)
return; /* no more to do */
 
memcpy (conn_list[conn].send_list, conn_list[conn].send_list+1,
conn_list[conn].send_idx * sizeof(struct SEND_LIST)); /* copy down */
TspSendMessage (conn, 0);
}
 
/*
* TspGetHostName - return client's host name.
*
* - this routine returns the name of the client's host or the net
* number of unknown.
*/
 
char*
TspGetHostName (conn_idx)
int conn_idx; /* client connection number */
{
static char buff [30]; /* largest net num */
unsigned char* cp;
 
cp = conn_list[conn_idx].sender.c+4;
sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);
return buff;
}
 
/*
* TimeTestHandler - alarm timer handler to resend warm/wait test.
*/
 
static void
TimeTestHandler()
{
int conn;
 
if (!warm_test)
return; /* no longer enabled */
 
for (conn = 0; conn < conn_list_cnt; conn++) {
/* locate all that are using this */
if (!conn_list[conn].in_use)
continue; /* not used */
 
if (!conn_list[conn].retry) continue;
/* found one that we are testing */
if (!--conn_list[conn].retry) {
/*
* Counted down the retries: blow off.
* Need to have connection flag to indicate not blowing
* off for cases where client is stopped due to being
* debugged.
*/
ConnDelete (conn, NULL, CLOSE_IGNORE);
continue;
}
TspSendMessage (conn, True); /* send another message */
}
alarm (2); /* setup for 2 seconds from now */
}
/Makefile.am
0,0 → 1,13
##
## $Id: Makefile.am,v 1.2 2001-09-27 12:02:01 chris Exp $
##
 
AUTOMAKE_OPTIONS = foreign 1.4
 
SUBDIRS = $(RTEMS_CPU)
 
EXTRA_DIST = _servtgt.c awk.svc excep.c ptrace.c rdbg.c remdeb.x servbkpt.c \
servcon.c servrpc.c servtgt.c servtsp.c servutil.c
 
include $(top_srcdir)/../../../automake/subdirs.am
include $(top_srcdir)/../../../automake/local.am
/i386/rdbg_f.c
0,0 → 1,155
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/i386/rdbg_f.c
*
* $Id: rdbg_f.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
 
 
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
{
regs->tabreg [GS] = 0;
regs->tabreg [FS] = 0;
regs->tabreg [ES] = 0;
regs->tabreg [DS] = 0;
regs->tabreg [EDI] = ctx->edi;
regs->tabreg [ESI] = ctx->esi;
regs->tabreg [EBP] = ctx->ebp;
regs->tabreg [ESP] = ctx->esp0;
regs->tabreg [EBX] = ctx->ebx;
regs->tabreg [EDX] = ctx->edx;
regs->tabreg [ECX] = ctx->ecx;
regs->tabreg [EAX] = ctx->eax;
regs->tabreg [TRAPNO] = ctx->idtIndex;
regs->tabreg [ERR] = ctx->faultCode;
regs->tabreg [EIP] = ctx->eip;
regs->tabreg [CS] = ctx->cs & 0xFFFF;
regs->tabreg [EFL] = ctx->eflags;
}
 
 
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
{
ctx->edi = regs->tabreg [EDI];
ctx->esi = regs->tabreg [ESI];
ctx->ebp = regs->tabreg [EBP];
ctx->esp0 = regs->tabreg [ESP];
ctx->ebx = regs->tabreg [EBX];
ctx->edx = regs->tabreg [EDX];
ctx->ecx = regs->tabreg [ECX];
ctx->eax = regs->tabreg [EAX];
ctx->idtIndex = regs->tabreg [TRAPNO];
ctx->faultCode = regs->tabreg [ERR];
ctx->eip = regs->tabreg [EIP];
ctx->cs = regs->tabreg [CS];
ctx->eflags = regs->tabreg [EFL];
}
 
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
ctx->edi = thread->Registers.edi;
ctx->esi = thread->Registers.esi;
ctx->ebp = (unsigned32)(thread->Registers.ebp);
ctx->esp0 = (unsigned32)(thread->Registers.esp);
ctx->ebx = thread->Registers.ebx;
ctx->edx = 0;
ctx->ecx = 0;
ctx->eax = 0;
ctx->idtIndex = 0;
ctx->faultCode = 0;
ctx->eip = *(unsigned int*)(thread->Registers.esp);
ctx->cs = 0;
ctx->eflags = thread->Registers.eflags;
}
 
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
thread->Registers.edi = ctx->edi;
thread->Registers.esi = ctx->esi;
thread->Registers.ebp = (void*)(ctx->ebp);
thread->Registers.esp = (void*)(ctx->esp0);
thread->Registers.ebx = ctx->ebx;
thread->Registers.eflags = ctx->eflags;
}
 
 
int
Single_Step(CPU_Exception_frame* ctx)
{
/* Check if not already set */
if ((ctx->eflags & EFLAGS_TF) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
assert ((ctx->eflags & EFLAGS_TF) != 0);
assert (ExitForSingleStep != 0);
return 0;
}
ctx->eflags |= EFLAGS_TF; /* eflags */
++ExitForSingleStep;
return 0;
}
 
int
CheckForSingleStep (CPU_Exception_frame* ctx)
{
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
 
void
CancelSingleStep (CPU_Exception_frame* ctx)
{
/* Cancel scheduled SS */
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
}
 
cpuExcHandlerType old_currentExcHandler;
extern void rtems_exception_prologue_50();
 
void connect_rdbg_exception()
{
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
 
/*
* Connect the Exception used to debug
*/
i386_get_info_from_IDTR (&currentIdtEntry, &limit);
_CPU_ISR_Disable(level);
create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
_CPU_ISR_Enable(level);
 
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl ;
 
}
/i386/rdbg_cpu_asm.S
0,0 → 1,72
/* cpu_asm.s
*
* This file contains all assembly code for the Intel i386 implementation
* of RDBG.
*
* $Id: rdbg_cpu_asm.S,v 1.2 2001-09-27 12:02:01 chris Exp $
*
*/
 
#include <asm.h>
 
BEGIN_CODE
 
/*
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
*
* This routine performs a copy of the data cache
* and invalidate the instruction cache
*/
 
.p2align 1
PUBLIC (copyback_data_cache_and_invalidate_instr_cache)
 
SYM (copyback_data_cache_and_invalidate_instr_cache):
wbinvd
ret
 
 
/*
* void enterRdbg(void)
*
* This function perform a call to the exception 19
* It is used :
* 1 - in the user code, to simulate a Breakpoint.
* (with justSaveContext = 0)
* 2 - in the RDBG code, to push a ctx in the list.
* (with justSaveContext = 1)
*
* In most of case, it will be use as described in 1.
* The 2nd possibility will be used by RDBG to obtain
* its own ctx
*/
 
PUBLIC (enterRdbg)
 
SYM (enterRdbg):
int $50
ret
 
 
/*
* void rtems_exception_prologue_50(void)
*
* Exception 50 is used to enter Rdbg
*
*/
.p2align 4
PUBLIC (rtems_exception_prologue_50)
PUBLIC (_Exception_Handler)
 
SYM (rtems_exception_prologue_50):
pushl $ 0
pushl $ 50
jmp SYM(_Exception_Handler) ;
 
 
END_CODE
 
END
/i386/any/remdeb.h
0,0 → 1,559
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
 
#ifndef _REMDEB_H_RPCGEN
#define _REMDEB_H_RPCGEN
 
#include <rpc/rpc.h>
 
 
#ifdef __cplusplus
extern "C" {
#endif
 
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
#ifndef REMDEB_H
#define RPCGENSRVNAME(a) a
 
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25,
};
typedef enum rpc_type rpc_type;
#define NET_SAFE 1400
 
struct UDP_MSG {
u_char type;
u_char msg_num;
u_short spec;
long pid;
u_long context;
};
typedef struct UDP_MSG UDP_MSG;
/*
* Sun request values for the remote ptrace system call
*/
 
 
enum ptracereq {
RPT_TRACEME = 0,
RPT_CHILDDONE = 0,
RPT_PEEKTEXT = 0 + 1,
RPT_PEEKDATA = 0 + 2,
RPT_PEEKUSER = 0 + 3,
RPT_POKETEXT = 0 + 4,
RPT_POKEDATA = 0 + 5,
RPT_POKEUSER = 0 + 6,
RPT_CONT = 0 + 7,
RPT_KILL = 0 + 8,
RPT_SINGLESTEP = 0 + 9,
RPT_ATTACH = 0 + 10,
RPT_DETACH = 0 + 11,
RPT_GETREGS = 0 + 12,
RPT_SETREGS = 0 + 13,
RPT_GETFPREGS = 0 + 14,
RPT_SETFPREGS = 0 + 15,
RPT_READDATA = 0 + 16,
RPT_WRITEDATA = 0 + 17,
RPT_READTEXT = 0 + 18,
RPT_WRITETEXT = 0 + 19,
RPT_GETFPAREGS = 0 + 20,
RPT_SETFPAREGS = 0 + 21,
RPT_22 = 0 + 22,
RPT_23 = 0 + 23,
RPT_SYSCALL = 0 + 24,
RPT_DUMPCORE = 0 + 25,
RPT_26 = 0 + 26,
RPT_27 = 0 + 27,
RPT_28 = 0 + 28,
RPT_GETUCODE = 0 + 29,
RPT_GETTARGETTHREAD = 50,
RPT_SETTARGETTHREAD = 51,
RPT_THREADSUSPEND = 52,
RPT_THREADRESUME = 53,
RPT_THREADLIST = 54,
RPT_GETTHREADNAME = 55,
RPT_SETTHREADNAME = 56,
RPT_SETTHREADREGS = 57,
RPT_GETTHREADREGS = 58,
RPT_STEPRANGE = 75,
RPT_CONTTO = 76,
RPT_SETBREAK = 77,
RPT_CLRBREAK = 78,
RPT_GETBREAK = 79,
RPT_GETNAME = 80,
RPT_STOP = 81,
RPT_PGETREGS = 82,
RPT_PSETREGS = 83,
RPT_PSETTHREADREGS = 84,
RPT_PGETTHREADREGS = 85,
};
typedef enum ptracereq ptracereq;
 
struct xdr_regs {
u_int tabreg[19];
};
typedef struct xdr_regs xdr_regs;
/* now define register macros to apply to xdr_reg struct */
 
#define GS 0
#define FS 1
#define ES 2
#define DS 3
#define EDI 4
#define ESI 5
#define EBP 6
#define ESP 7
#define EBX 8
#define EDX 9
#define ECX 10
#define EAX 11
#define TRAPNO 12
#define ERR 13
#define EIP 14
#define CS 15
#define EFL 16
#define UESP 17
#define SS 18
 
#define REG_PC tabreg[EIP] /* PC (eip) register offset */
#define REG_SP tabreg[UESP] /* SP (uesp) register offset */
#define REG_FP tabreg[EBP] /* FP (ebp) register offset */
/* now define the BREAKPOINT mask technique to a long word */
#define SET_BREAK(l) ((l&0xFFFFFF00) | 0xCC)
#define IS_BREAK(l) (((l) & 0xFF) == 0xCC)
#define ORG_BREAK(c,p) (((c) & 0xFFFFFF00) | ((p) & 0xFF))
#define IS_STEP(regs) (regs.tabreg[TRAPNO] == 1) /* was step and not break */
#define BREAK_ADJ 1 /* must subtract one from address after bp */
#define BREAK_SIZE 1 /* Breakpoint occupies one byte */
#define TARGET_PROC_TYPE 0
#define MAXDEBUGGEE 150
#define NAMEMAX 17
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
#define MEM_DATA_MAX 256
 
struct xdr_mem {
u_long addr;
u_int dataNb;
u_char data[MEM_DATA_MAX];
};
typedef struct xdr_mem xdr_mem;
 
enum break_type {
BRKT_NONE = 0,
BRKT_INSTR = 1,
BRKT_READ = 2,
BRKT_WRITE = 3,
BRKT_ACCESS = 4,
BRKT_EXEC = 5,
BRKT_OS_CALL = 6,
BRKT_OS_SWITCH = 7,
BRKT_STEPEMUL = 8,
};
typedef enum break_type break_type;
#define MAX_THRD_BRK 4
 
struct xdr_break {
u_char type;
u_char thread_spec;
u_short handle;
u_long ee_loc;
u_long ee_type;
u_short length;
u_char pass_count;
u_char curr_pass;
u_long thread_list[MAX_THRD_BRK];
};
typedef struct xdr_break xdr_break;
#define UTHREAD_MAX 64
#define THREADNAMEMAX 16
 
typedef char *thread_name;
 
struct KernThread {
u_int threadLi;
};
typedef struct KernThread KernThread;
typedef KernThread *ptThreadList;
 
struct thread_list {
u_int nbThread;
ptThreadList threads;
};
typedef struct thread_list thread_list;
 
struct ptrace_addr_data_in {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int address;
} ptrace_addr_data_in_u;
};
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
 
struct ptrace_addr_data_out {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_list threads;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int addr;
} ptrace_addr_data_out_u;
};
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
 
typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
#define XRY_MAX_INST_BUFF 128
#define XRY_MAX_INSTANCES 16
#ifndef XRY_MAX_CMD_STR
#define XRY_MAX_CMD_STR 320
#endif /* REMDEB_H */
 
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
 
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
 
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
 
typedef char *one_arg;
#define XRY_MAX_OBJ_NAME 32
/* now open_connex() routine which establishes a connection to server */
 
enum debug_type {
DEBTYP_PROCESS = 0,
DEBTYP_C_ACTOR = 1,
DEBTYP_KERNEL = 2,
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
 
struct open_in {
u_char back_port[16];
u_short debug_type;
u_short flags;
u_char destination[16];
one_arg user_name;
};
typedef struct open_in open_in;
 
struct open_out {
u_long port;
u_int pad[4];
u_int fp;
u_char cmd_table_num;
u_char cmd_table_vers;
u_short server_vers;
};
typedef struct open_out open_out;
/* now close_connex() routine which detaches from server */
 
enum close_control {
CLOSE_IGNORE = 0,
CLOSE_KILL = 1,
CLOSE_DETACH = 2,
};
typedef enum close_control close_control;
 
struct close_in {
close_control control;
};
typedef struct close_in close_in;
/* now send_signal() routine which sends signals to processes like kill(2) */
 
struct signal_in {
int pid;
int sig;
};
typedef struct signal_in signal_in;
 
struct signal_out {
int kill_return;
int errNo;
};
typedef struct signal_out signal_out;
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
 
enum stop_code {
STOP_ERROR = 0,
STOP_NONE = 1,
STOP_UNKNOWN = 2,
STOP_BREAK = 3,
STOP_STEP = 4,
STOP_SIGNAL = 5,
STOP_TERM_EXIT = 6,
STOP_TERM_SIG = 7,
STOP_DETACHED = 8,
STOP_KILLED = 9,
STOP_SPAWN_FAILED = 10,
};
typedef enum stop_code stop_code;
 
struct wait_in {
int pid;
};
typedef struct wait_in wait_in;
 
struct wait_out {
int wait_return;
int errNo;
int status;
stop_code reason;
int handle;
u_long PC;
u_long SP;
u_long FP;
u_long thread;
};
typedef struct wait_out wait_out;
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
#define PTRFLG_FORCE 1
#define PTRFLG_NON_OWNER 2
#define PTRFLG_FREE 4
#define PTRDET_UNOWN 0x100
 
struct ptrace_in {
int pid;
ptrace_addr_data_in addr;
u_int data;
u_int flags;
};
typedef struct ptrace_in ptrace_in;
 
struct ptrace_out {
ptrace_addr_data_out addr;
int result;
int errNo;
};
typedef struct ptrace_out ptrace_out;
 
struct one_symbol {
char *symbolName;
long symbolValue;
};
typedef struct one_symbol one_symbol;
 
typedef struct {
u_int all_symbols_len;
one_symbol *all_symbols_val;
} all_symbols;
 
struct get_global_symbols_out {
all_symbols symbols;
};
typedef struct get_global_symbols_out get_global_symbols_out;
 
struct get_text_data_in {
int pid;
char *actorName;
};
typedef struct get_text_data_in get_text_data_in;
 
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
typedef struct get_text_data_out get_text_data_out;
 
struct one_signal {
u_int number;
char *name;
};
typedef struct one_signal one_signal;
 
typedef struct {
u_int all_signals_len;
one_signal *all_signals_val;
} all_signals;
 
struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/* now define the actual calls we support */
#define REMDEB_H
#endif
 
#define REMOTEDEB 0x20000fff
#define REMOTEVERS 2
 
#if defined(__STDC__) || defined(__cplusplus)
#define OPEN_CONNEX 1
extern open_out * open_connex_2(open_in *, CLIENT *);
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
#define SEND_SIGNAL 2
extern signal_out * send_signal_2(signal_in *, CLIENT *);
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
#define CLOSE_CONNEX 10
extern void * close_connex_2(close_in *, CLIENT *);
extern void * close_connex_2_svc(close_in *, struct svc_req *);
#define PTRACE 11
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
#define WAIT_INFO 13
extern wait_out * wait_info_2(wait_in *, CLIENT *);
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
 
#else /* K&R C */
#define OPEN_CONNEX 1
extern open_out * open_connex_2();
extern open_out * open_connex_2_svc();
#define SEND_SIGNAL 2
extern signal_out * send_signal_2();
extern signal_out * send_signal_2_svc();
#define CLOSE_CONNEX 10
extern void * close_connex_2();
extern void * close_connex_2_svc();
#define PTRACE 11
extern ptrace_out * ptrace_2();
extern ptrace_out * ptrace_2_svc();
#define WAIT_INFO 13
extern wait_out * wait_info_2();
extern wait_out * wait_info_2_svc();
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2();
extern get_signal_names_out * get_signal_names_2_svc();
extern int remotedeb_2_freeresult ();
#endif /* K&R C */
 
/* the xdr functions */
 
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
extern bool_t xdr_break_type (XDR *, break_type*);
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
extern bool_t xdr_thread_name (XDR *, thread_name*);
extern bool_t xdr_KernThread (XDR *, KernThread*);
extern bool_t xdr_thread_list (XDR *, thread_list*);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
extern bool_t xdr_xry_inst (XDR *, xry_inst*);
extern bool_t xdr_instance (XDR *, instance*);
extern bool_t xdr_instance_union (XDR *, instance_union*);
extern bool_t xdr_one_arg (XDR *, one_arg*);
extern bool_t xdr_debug_type (XDR *, debug_type*);
extern bool_t xdr_open_in (XDR *, open_in*);
extern bool_t xdr_open_out (XDR *, open_out*);
extern bool_t xdr_close_control (XDR *, close_control*);
extern bool_t xdr_close_in (XDR *, close_in*);
extern bool_t xdr_signal_in (XDR *, signal_in*);
extern bool_t xdr_signal_out (XDR *, signal_out*);
extern bool_t xdr_stop_code (XDR *, stop_code*);
extern bool_t xdr_wait_in (XDR *, wait_in*);
extern bool_t xdr_wait_out (XDR *, wait_out*);
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
extern bool_t xdr_one_signal (XDR *, one_signal*);
extern bool_t xdr_all_signals (XDR *, all_signals*);
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
 
#else /* K&R C */
extern bool_t xdr_rpc_type ();
extern bool_t xdr_UDP_MSG ();
extern bool_t xdr_ptracereq ();
extern bool_t xdr_xdr_regs ();
extern bool_t xdr_xdr_mem ();
extern bool_t xdr_break_type ();
extern bool_t xdr_xdr_break ();
extern bool_t xdr_thread_name ();
extern bool_t xdr_KernThread ();
extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();
extern bool_t xdr_open_out ();
extern bool_t xdr_close_control ();
extern bool_t xdr_close_in ();
extern bool_t xdr_signal_in ();
extern bool_t xdr_signal_out ();
extern bool_t xdr_stop_code ();
extern bool_t xdr_wait_in ();
extern bool_t xdr_wait_out ();
extern bool_t xdr_ptrace_in ();
extern bool_t xdr_ptrace_out ();
extern bool_t xdr_one_symbol ();
extern bool_t xdr_all_symbols ();
extern bool_t xdr_get_global_symbols_out ();
extern bool_t xdr_get_text_data_in ();
extern bool_t xdr_get_text_data_out ();
extern bool_t xdr_one_signal ();
extern bool_t xdr_all_signals ();
extern bool_t xdr_get_signal_names_out ();
 
#endif /* K&R C */
 
#ifdef __cplusplus
}
#endif
 
#endif /* !_REMDEB_H_RPCGEN */
/i386/any/Makefile.am
0,0 → 1,90
##
## $Id: Makefile.am,v 1.2 2001-09-27 12:02:01 chris Exp $
##
 
AUTOMAKE_OPTIONS = foreign 1.4
 
VPATH = @srcdir@:@srcdir@/..:@srcdir@/../..
 
LIBNAME = librdbg
LIB = ${ARCH}/${LIBNAME}.a
 
# C and C++ source names
C_FILES = rdbg.c servcon.c servbkpt.c servrpc.c excep.c excep_f.c servtgt.c \
servtsp.c servutil.c _servtgt.c rdbg_f.c ptrace.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
 
# Asm source names
S_FILES = rdbg_cpu_asm.S
S_O_FILES = $(S_FILES:%.S=${ARCH}/%.o)
 
# Generated C source names
GEN_C_FILES = remdeb_xdr.c remdeb_svc.c
GEN_C_O_FILES = $(GEN_C_FILES:%.c=${ARCH}/%.o)
 
# H source names
H_FILES = remdeb.h
 
# X source names
X_FILES = remdeb.x remdeb_f.x
 
OBJS = $(GEN_C_O_FILES) $(C_O_FILES) $(S_O_FILES)
 
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/lib.am
 
#
# Add local stuff here using +=
#
 
MAINTAINERCLEANFILES += $(H_FILES) $(GEN_C_FILES)
 
FRONTEND = \"$(RTEMS_CPU)/any/remdeb_f.x\"
 
$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB)
$(INSTALL_DATA) $< $@
 
$(LIB): ${OBJS}
$(make-library)
 
$(srcdir)/remdeb.h: $(X_FILES)
if RPCTOOLS
@rm -f $@
( cd $(top_srcdir)/src; \
$(RPCGEN) -h -DFRONTEND=$(FRONTEND) \
-o i386/any/remdeb.h remdeb.x )
endif
$(srcdir)/remdeb_xdr.c: $(X_FILES)
if RPCTOOLS
@rm -f $@
( cd $(top_srcdir)/src; \
$(RPCGEN) -c -DFRONTEND=$(FRONTEND) \
-o i386/any/remdeb_xdr.c remdeb.x )
endif
 
$(srcdir)/remdeb_svc.c: $(X_FILES)
if RPCTOOLS
@rm -f $@ tmpSvc.c
( cd $(top_srcdir)/src; \
$(RPCGEN) -m -DFRONTEND=$(FRONTEND) \
-o i386/any/tmpSvc.c remdeb.x; \
$(AWK) -f ./awk.svc THEPROG="remdeb.h" i386/any/tmpSvc.c \
> i386/any/remdeb_svc.c; \
rm -f i386/any/tmpSvc.c )
endif
 
$(PROJECT_INCLUDE)/rdbg/remdeb.h: $(srcdir)/remdeb.h
$(INSTALL_DATA) $< $@
 
$(PROJECT_INCLUDE)/rdbg:
@$(mkinstalldirs) $@
 
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg $(PROJECT_INCLUDE)/rdbg/remdeb.h
 
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a
 
all-local: ${ARCH} $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
 
EXTRA_DIST = remdeb_f.x $(GEN_C_FILES)
 
include $(top_srcdir)/../../../automake/local.am
/i386/any/remdeb_f.x
0,0 → 1,59
/*
**************************************************************************
*
* Component = rdblib
*
* Synopsis = remdeb_f.x
*
* $Id: remdeb_f.x,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
struct xdr_regs
{
unsigned int tabreg[19];
};
 
#ifdef RPC_HDR
 
%/* now define register macros to apply to xdr_reg struct */
%
%#define GS 0
%#define FS 1
%#define ES 2
%#define DS 3
%#define EDI 4
%#define ESI 5
%#define EBP 6
%#define ESP 7
%#define EBX 8
%#define EDX 9
%#define ECX 10
%#define EAX 11
%#define TRAPNO 12
%#define ERR 13
%#define EIP 14
%#define CS 15
%#define EFL 16
%#define UESP 17
%#define SS 18
%
%#define REG_PC tabreg[EIP] /* PC (eip) register offset */
%#define REG_SP tabreg[UESP] /* SP (uesp) register offset */
%#define REG_FP tabreg[EBP] /* FP (ebp) register offset */
 
%/* now define the BREAKPOINT mask technique to a long word */
%#define SET_BREAK(l) ((l&0xFFFFFF00) | 0xCC)
%#define IS_BREAK(l) (((l) & 0xFF) == 0xCC)
%#define ORG_BREAK(c,p) (((c) & 0xFFFFFF00) | ((p) & 0xFF))
%#define IS_STEP(regs) (regs.tabreg[TRAPNO] == 1) /* was step and not break */
%#define BREAK_ADJ 1 /* must subtract one from address after bp */
%#define BREAK_SIZE 1 /* Breakpoint occupies one byte */
 
%#define TARGET_PROC_TYPE 0
 
#endif
 
 
 
/i386/any/remdeb_svc.c
0,0 → 1,122
#include <rpc/types.h>
#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bsp.h>
#include <rdbg/servrpc.h>
#include <rdbg/remdeb.h>
#define fprintf(a,b) printf(b)
/*HEADER_START*/
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
/*
* Sun request values for the remote ptrace system call
*/
 
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
/* now open_connex() routine which establishes a connection to server */
#define DEBUGGER_IS_GDB 0x2 /* */
/* now close_connex() routine which detaches from server */
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now define the actual calls we support */
const char* names [] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
};
 
void
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
open_in open_connex_2_arg;
signal_in send_signal_2_arg;
close_in close_connex_2_arg;
ptrace_in ptrace_2_arg;
wait_in wait_info_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
 
DPRINTF (("remotedeb_2: %s (%d)\n",
(unsigned) rqstp->rq_proc <
(unsigned) (sizeof names / sizeof names[0]) ?
names [rqstp->rq_proc] : "???",
(int) rqstp->rq_proc));
 
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
 
case OPEN_CONNEX:
_xdr_argument = (xdrproc_t) xdr_open_in;
_xdr_result = (xdrproc_t) xdr_open_out;
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
break;
 
case SEND_SIGNAL:
_xdr_argument = (xdrproc_t) xdr_signal_in;
_xdr_result = (xdrproc_t) xdr_signal_out;
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
break;
 
case CLOSE_CONNEX:
_xdr_argument = (xdrproc_t) xdr_close_in;
_xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
break;
 
case PTRACE:
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
_xdr_result = (xdrproc_t) xdr_ptrace_out;
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
break;
 
case WAIT_INFO:
_xdr_argument = (xdrproc_t) xdr_wait_in;
_xdr_result = (xdrproc_t) xdr_wait_out;
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
break;
 
case GET_SIGNAL_NAMES:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
break;
 
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
return;
}
/i386/any/remdeb_xdr.c
0,0 → 1,928
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
 
#include "remdeb.h"
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
 
bool_t
xdr_rpc_type (XDR *xdrs, rpc_type *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_UDP_MSG (XDR *xdrs, UDP_MSG *objp)
{
register int32_t *buf;
 
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->msg_num))
return FALSE;
if (!xdr_u_short (xdrs, &objp->spec))
return FALSE;
if (!xdr_long (xdrs, &objp->pid))
return FALSE;
if (!xdr_u_long (xdrs, &objp->context))
return FALSE;
return TRUE;
}
/*
* Sun request values for the remote ptrace system call
*/
 
 
bool_t
xdr_ptracereq (XDR *xdrs, ptracereq *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
{
register int32_t *buf;
 
int i;
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE(xdrs, 19 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->tabreg, 19,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
} else {
{
register u_int *genp;
 
for (i = 0, genp = objp->tabreg;
i < 19; ++i) {
IXDR_PUT_U_LONG(buf, *genp++);
}
}
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs, 19 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->tabreg, 19,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
} else {
{
register u_int *genp;
 
for (i = 0, genp = objp->tabreg;
i < 19; ++i) {
*genp++ = IXDR_GET_U_LONG(buf);
}
}
}
return TRUE;
}
 
if (!xdr_vector (xdrs, (char *)objp->tabreg, 19,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
return TRUE;
}
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
bool_t xdr_xdr_mem(xdrs, objp)
XDR *xdrs;
struct xdr_mem *objp;
{
if (!xdr_u_long(xdrs, &objp->addr)) {
return (FALSE);
}
if (!xdr_u_int(xdrs, &objp->dataNb)) {
return(FALSE);
}
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
}
 
bool_t
xdr_break_type (XDR *xdrs, break_type *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_xdr_break (XDR *xdrs, xdr_break *objp)
{
register int32_t *buf;
 
int i;
 
if (xdrs->x_op == XDR_ENCODE) {
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->thread_spec))
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_short (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_loc))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->length))
return FALSE;
 
} else {
IXDR_PUT_U_SHORT(buf, objp->handle);
IXDR_PUT_U_LONG(buf, objp->ee_loc);
IXDR_PUT_U_LONG(buf, objp->ee_type);
IXDR_PUT_U_SHORT(buf, objp->length);
}
if (!xdr_u_char (xdrs, &objp->pass_count))
return FALSE;
if (!xdr_u_char (xdrs, &objp->curr_pass))
return FALSE;
buf = XDR_INLINE(xdrs, MAX_THRD_BRK * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
sizeof (u_long), (xdrproc_t) xdr_u_long))
return FALSE;
} else {
{
register u_long *genp;
 
for (i = 0, genp = objp->thread_list;
i < MAX_THRD_BRK; ++i) {
IXDR_PUT_U_LONG(buf, *genp++);
}
}
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->thread_spec))
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_short (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_loc))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->length))
return FALSE;
 
} else {
objp->handle = IXDR_GET_U_SHORT(buf);
objp->ee_loc = IXDR_GET_U_LONG(buf);
objp->ee_type = IXDR_GET_U_LONG(buf);
objp->length = IXDR_GET_U_SHORT(buf);
}
if (!xdr_u_char (xdrs, &objp->pass_count))
return FALSE;
if (!xdr_u_char (xdrs, &objp->curr_pass))
return FALSE;
buf = XDR_INLINE(xdrs, MAX_THRD_BRK * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
sizeof (u_long), (xdrproc_t) xdr_u_long))
return FALSE;
} else {
{
register u_long *genp;
 
for (i = 0, genp = objp->thread_list;
i < MAX_THRD_BRK; ++i) {
*genp++ = IXDR_GET_U_LONG(buf);
}
}
}
return TRUE;
}
 
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->thread_spec))
return FALSE;
if (!xdr_u_short (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_loc))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ee_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->length))
return FALSE;
if (!xdr_u_char (xdrs, &objp->pass_count))
return FALSE;
if (!xdr_u_char (xdrs, &objp->curr_pass))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
sizeof (u_long), (xdrproc_t) xdr_u_long))
return FALSE;
return TRUE;
}
 
bool_t
xdr_thread_name (XDR *xdrs, thread_name *objp)
{
register int32_t *buf;
 
if (!xdr_string (xdrs, objp, THREADNAMEMAX))
return FALSE;
return TRUE;
}
 
bool_t
xdr_KernThread (XDR *xdrs, KernThread *objp)
{
register int32_t *buf;
 
if (!xdr_u_int (xdrs, &objp->threadLi))
return FALSE;
return TRUE;
}
bool_t xdr_thread_list(xdrs, objp)
XDR *xdrs;
struct thread_list *objp;
{
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
}
 
bool_t
xdr_ptrace_addr_data_in (XDR *xdrs, ptrace_addr_data_in *objp)
{
register int32_t *buf;
 
if (!xdr_ptracereq (xdrs, &objp->req))
return FALSE;
switch (objp->req) {
case RPT_SETTHREADREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
return FALSE;
break;
case RPT_SETREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
return FALSE;
break;
case RPT_PSETTHREADREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_PSETREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_SETTHREADNAME:
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_in_u.name))
return FALSE;
break;
case RPT_WRITETEXT:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
return FALSE;
break;
case RPT_WRITEDATA:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
return FALSE;
break;
case RPT_SETBREAK:
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_in_u.breakp))
return FALSE;
break;
default:
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_in_u.address))
return FALSE;
break;
}
return TRUE;
}
 
bool_t
xdr_ptrace_addr_data_out (XDR *xdrs, ptrace_addr_data_out *objp)
{
register int32_t *buf;
 
if (!xdr_ptracereq (xdrs, &objp->req))
return FALSE;
switch (objp->req) {
case RPT_GETREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
return FALSE;
break;
case RPT_GETTHREADREGS:
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
return FALSE;
break;
case RPT_PGETREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_PGETTHREADREGS:
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
break;
case RPT_THREADLIST:
if (!xdr_thread_list (xdrs, &objp->ptrace_addr_data_out_u.threads))
return FALSE;
break;
case RPT_GETTHREADNAME:
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_out_u.name))
return FALSE;
break;
case RPT_READTEXT:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
return FALSE;
break;
case RPT_GETNAME:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
return FALSE;
break;
case RPT_READDATA:
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
return FALSE;
break;
case RPT_GETBREAK:
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_out_u.breakp))
return FALSE;
break;
default:
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_out_u.addr))
return FALSE;
break;
}
return TRUE;
}
 
bool_t
xdr_CHAR_DATA (XDR *xdrs, CHAR_DATA *objp)
{
register int32_t *buf;
 
if (!xdr_bytes (xdrs, (char **)&objp->CHAR_DATA_val, (u_int *) &objp->CHAR_DATA_len, NET_SAFE))
return FALSE;
return TRUE;
}
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
 
bool_t
xdr_xry_inst (XDR *xdrs, xry_inst *objp)
{
register int32_t *buf;
 
if (!xdr_u_char (xdrs, &objp->flags))
return FALSE;
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->sub_type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->res_type))
return FALSE;
if (!xdr_u_long (xdrs, &objp->value))
return FALSE;
if (!xdr_u_long (xdrs, &objp->value2))
return FALSE;
return TRUE;
}
 
bool_t
xdr_instance (XDR *xdrs, instance *objp)
{
register int32_t *buf;
 
int i;
if (!xdr_vector (xdrs, (char *)objp->instances, XRY_MAX_INSTANCES,
sizeof (xry_inst), (xdrproc_t) xdr_xry_inst))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->buffer, XRY_MAX_INST_BUFF,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
return TRUE;
}
 
bool_t
xdr_instance_union (XDR *xdrs, instance_union *objp)
{
register int32_t *buf;
 
if (!xdr_bool (xdrs, &objp->instances))
return FALSE;
switch (objp->instances) {
case TRUE:
if (!xdr_instance (xdrs, &objp->instance_union_u.inst))
return FALSE;
break;
case FALSE:
if (!xdr_string (xdrs, &objp->instance_union_u.buffer, XRY_MAX_CMD_STR))
return FALSE;
break;
default:
return FALSE;
}
return TRUE;
}
 
bool_t
xdr_one_arg (XDR *xdrs, one_arg *objp)
{
register int32_t *buf;
 
if (!xdr_string (xdrs, objp, NET_SAFE))
return FALSE;
return TRUE;
}
/* now open_connex() routine which establishes a connection to server */
 
bool_t
xdr_debug_type (XDR *xdrs, debug_type *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
#define DEBUGGER_IS_GDB 0x2 /* */
 
bool_t
xdr_open_in (XDR *xdrs, open_in *objp)
{
register int32_t *buf;
 
int i;
if (!xdr_vector (xdrs, (char *)objp->back_port, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
if (!xdr_u_short (xdrs, &objp->debug_type))
return FALSE;
if (!xdr_u_short (xdrs, &objp->flags))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->destination, 16,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
if (!xdr_one_arg (xdrs, &objp->user_name))
return FALSE;
return TRUE;
}
 
bool_t
xdr_open_out (XDR *xdrs, open_out *objp)
{
register int32_t *buf;
 
int i;
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE(xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_long (xdrs, &objp->port))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
if (!xdr_u_int (xdrs, &objp->fp))
return FALSE;
 
} else {
IXDR_PUT_U_LONG(buf, objp->port);
{
register u_int *genp;
 
for (i = 0, genp = objp->pad;
i < 4; ++i) {
IXDR_PUT_U_LONG(buf, *genp++);
}
}
IXDR_PUT_U_LONG(buf, objp->fp);
}
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
return FALSE;
if (!xdr_u_short (xdrs, &objp->server_vers))
return FALSE;
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_u_long (xdrs, &objp->port))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
if (!xdr_u_int (xdrs, &objp->fp))
return FALSE;
 
} else {
objp->port = IXDR_GET_U_LONG(buf);
{
register u_int *genp;
 
for (i = 0, genp = objp->pad;
i < 4; ++i) {
*genp++ = IXDR_GET_U_LONG(buf);
}
}
objp->fp = IXDR_GET_U_LONG(buf);
}
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
return FALSE;
if (!xdr_u_short (xdrs, &objp->server_vers))
return FALSE;
return TRUE;
}
 
if (!xdr_u_long (xdrs, &objp->port))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return FALSE;
if (!xdr_u_int (xdrs, &objp->fp))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
return FALSE;
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
return FALSE;
if (!xdr_u_short (xdrs, &objp->server_vers))
return FALSE;
return TRUE;
}
/* now close_connex() routine which detaches from server */
 
bool_t
xdr_close_control (XDR *xdrs, close_control *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_close_in (XDR *xdrs, close_in *objp)
{
register int32_t *buf;
 
if (!xdr_close_control (xdrs, &objp->control))
return FALSE;
return TRUE;
}
/* now send_signal() routine which sends signals to processes like kill(2) */
 
bool_t
xdr_signal_in (XDR *xdrs, signal_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
if (!xdr_int (xdrs, &objp->sig))
return FALSE;
return TRUE;
}
 
bool_t
xdr_signal_out (XDR *xdrs, signal_out *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->kill_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
return TRUE;
}
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
 
bool_t
xdr_stop_code (XDR *xdrs, stop_code *objp)
{
register int32_t *buf;
 
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
 
bool_t
xdr_wait_in (XDR *xdrs, wait_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
return TRUE;
}
 
bool_t
xdr_wait_out (XDR *xdrs, wait_out *objp)
{
register int32_t *buf;
 
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->wait_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_int (xdrs, &objp->status))
return FALSE;
 
} else {
IXDR_PUT_LONG(buf, objp->wait_return);
IXDR_PUT_LONG(buf, objp->errNo);
IXDR_PUT_LONG(buf, objp->status);
}
if (!xdr_stop_code (xdrs, &objp->reason))
return FALSE;
buf = XDR_INLINE(xdrs,5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->PC))
return FALSE;
if (!xdr_u_long (xdrs, &objp->SP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->FP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->thread))
return FALSE;
} else {
IXDR_PUT_LONG(buf, objp->handle);
IXDR_PUT_U_LONG(buf, objp->PC);
IXDR_PUT_U_LONG(buf, objp->SP);
IXDR_PUT_U_LONG(buf, objp->FP);
IXDR_PUT_U_LONG(buf, objp->thread);
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->wait_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_int (xdrs, &objp->status))
return FALSE;
 
} else {
objp->wait_return = IXDR_GET_LONG(buf);
objp->errNo = IXDR_GET_LONG(buf);
objp->status = IXDR_GET_LONG(buf);
}
if (!xdr_stop_code (xdrs, &objp->reason))
return FALSE;
buf = XDR_INLINE(xdrs,5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->PC))
return FALSE;
if (!xdr_u_long (xdrs, &objp->SP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->FP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->thread))
return FALSE;
} else {
objp->handle = IXDR_GET_LONG(buf);
objp->PC = IXDR_GET_U_LONG(buf);
objp->SP = IXDR_GET_U_LONG(buf);
objp->FP = IXDR_GET_U_LONG(buf);
objp->thread = IXDR_GET_U_LONG(buf);
}
return TRUE;
}
 
if (!xdr_int (xdrs, &objp->wait_return))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_int (xdrs, &objp->status))
return FALSE;
if (!xdr_stop_code (xdrs, &objp->reason))
return FALSE;
if (!xdr_int (xdrs, &objp->handle))
return FALSE;
if (!xdr_u_long (xdrs, &objp->PC))
return FALSE;
if (!xdr_u_long (xdrs, &objp->SP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->FP))
return FALSE;
if (!xdr_u_long (xdrs, &objp->thread))
return FALSE;
return TRUE;
}
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
 
bool_t
xdr_ptrace_in (XDR *xdrs, ptrace_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
if (!xdr_ptrace_addr_data_in (xdrs, &objp->addr))
return FALSE;
if (!xdr_u_int (xdrs, &objp->data))
return FALSE;
if (!xdr_u_int (xdrs, &objp->flags))
return FALSE;
return TRUE;
}
 
bool_t
xdr_ptrace_out (XDR *xdrs, ptrace_out *objp)
{
register int32_t *buf;
 
if (!xdr_ptrace_addr_data_out (xdrs, &objp->addr))
return FALSE;
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
return TRUE;
}
 
bool_t
xdr_one_symbol (XDR *xdrs, one_symbol *objp)
{
register int32_t *buf;
 
if (!xdr_string (xdrs, &objp->symbolName, ~0))
return FALSE;
if (!xdr_long (xdrs, &objp->symbolValue))
return FALSE;
return TRUE;
}
 
bool_t
xdr_all_symbols (XDR *xdrs, all_symbols *objp)
{
register int32_t *buf;
 
if (!xdr_array (xdrs, (char **)&objp->all_symbols_val, (u_int *) &objp->all_symbols_len, ~0,
sizeof (one_symbol), (xdrproc_t) xdr_one_symbol))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_global_symbols_out (XDR *xdrs, get_global_symbols_out *objp)
{
register int32_t *buf;
 
if (!xdr_all_symbols (xdrs, &objp->symbols))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_text_data_in (XDR *xdrs, get_text_data_in *objp)
{
register int32_t *buf;
 
if (!xdr_int (xdrs, &objp->pid))
return FALSE;
if (!xdr_string (xdrs, &objp->actorName, 16))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_text_data_out (XDR *xdrs, get_text_data_out *objp)
{
register int32_t *buf;
 
 
if (xdrs->x_op == XDR_ENCODE) {
buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textSize))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataSize))
return FALSE;
} else {
IXDR_PUT_LONG(buf, objp->result);
IXDR_PUT_LONG(buf, objp->errNo);
IXDR_PUT_U_LONG(buf, objp->textStart);
IXDR_PUT_U_LONG(buf, objp->textSize);
IXDR_PUT_U_LONG(buf, objp->dataStart);
IXDR_PUT_U_LONG(buf, objp->dataSize);
}
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textSize))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataSize))
return FALSE;
} else {
objp->result = IXDR_GET_LONG(buf);
objp->errNo = IXDR_GET_LONG(buf);
objp->textStart = IXDR_GET_U_LONG(buf);
objp->textSize = IXDR_GET_U_LONG(buf);
objp->dataStart = IXDR_GET_U_LONG(buf);
objp->dataSize = IXDR_GET_U_LONG(buf);
}
return TRUE;
}
 
if (!xdr_int (xdrs, &objp->result))
return FALSE;
if (!xdr_int (xdrs, &objp->errNo))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->textSize))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataStart))
return FALSE;
if (!xdr_u_long (xdrs, &objp->dataSize))
return FALSE;
return TRUE;
}
 
bool_t
xdr_one_signal (XDR *xdrs, one_signal *objp)
{
register int32_t *buf;
 
if (!xdr_u_int (xdrs, &objp->number))
return FALSE;
if (!xdr_string (xdrs, &objp->name, ~0))
return FALSE;
return TRUE;
}
 
bool_t
xdr_all_signals (XDR *xdrs, all_signals *objp)
{
register int32_t *buf;
 
if (!xdr_array (xdrs, (char **)&objp->all_signals_val, (u_int *) &objp->all_signals_len, ~0,
sizeof (one_signal), (xdrproc_t) xdr_one_signal))
return FALSE;
return TRUE;
}
 
bool_t
xdr_get_signal_names_out (XDR *xdrs, get_signal_names_out *objp)
{
register int32_t *buf;
 
if (!xdr_all_signals (xdrs, &objp->signals))
return FALSE;
return TRUE;
}
/* now define the actual calls we support */
/i386/Makefile.am
0,0 → 1,12
##
## $Id: Makefile.am,v 1.2 2001-09-27 12:02:01 chris Exp $
##
 
AUTOMAKE_OPTIONS = foreign 1.4
 
SUBDIRS = any
 
EXTRA_DIST = excep_f.c rdbg_cpu_asm.S rdbg_f.c
 
include $(top_srcdir)/../../../automake/subdirs.am
include $(top_srcdir)/../../../automake/local.am
/i386/excep_f.c
0,0 → 1,153
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/i386/excep.c
*
* $Id: excep_f.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**************************************************************************
*/
 
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
 
/* -----------------------------------------------------------------
Maping of hardware exceptions into Unix-like signal numbers.
It is identical to the one used by the PM and the AM.
----------------------------------------------------------------- */
 
int
ExcepToSig (Exception_context *ctx)
{
int excep = getExcNum (ctx);
 
switch (excep) {
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
 
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
 
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
 
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
 
default:
break;
}
return SIGKILL;
}
 
/*----- Breakpoint Exception management -----*/
 
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
 
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
 
if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
 
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
ctx->eip,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n\n");
#endif
 
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
 
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->idtIndex){
case I386_EXCEPTION_DEBUG:
DPRINTF((" DEBUG EXCEPTION !!!\n"));
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
 
case I386_EXCEPTION_BREAKPOINT:
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
 
case I386_EXCEPTION_ENTER_RDBG:
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
 
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
 
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}
 
 
 
/awk.svc
0,0 → 1,65
#########################################################################
#
# Component: RDBG
# Module: awk.svc
#
# Synopsis: AWK script which transforms the server skeleton produced
# by rpcgen(1) into something suitable for RDB servers.
#
#########################################################################
#
# $Id: awk.svc,v 1.2 2001-09-27 12:02:01 chris Exp $
#
BEGIN {
headerstarted = 0
withinproc = 0
brack = 0
}
 
$1 ~ /^\/\*HEADER_START\*\/$/ {
headerstarted = 1
printf("#include <rpc/types.h>\n");
printf("#include <rpc/rpc.h>\n");
printf("#include <stdio.h>\n");
printf("#include <stdlib.h>\n");
printf("#include <string.h>\n");
printf("#include <bsp.h>\n");
printf("#include <rdbg/servrpc.h>\n");
printf("#include <rdbg/%s>\n", THEPROG);
printf("#define fprintf(a,b) printf(b)\n");
}
 
$1 ~ /^\/\*HEADER_END\*\/$/ {
headerstarted = 0
}
 
{
if (headerstarted == 1) {
print $0
} else if ($1 ~ /.*_2.*/) {
withinproc = 1
printf("void\n");
print $0
} else if (withinproc == 1) {
if ($1 == "switch") {
print "\tDPRINTF ((\"remotedeb_2: %s (%d)\\n\", "
print "\t\t(unsigned) rqstp->rq_proc < "
print "\t\t(unsigned) (sizeof names / sizeof names[0]) ?"
print "\t\tnames [rqstp->rq_proc] : \"???\", "
print "\t\t(int) rqstp->rq_proc));\n"
}
for (i = 1; i <= NF; i++) {
if ($i == "{") {
brack++;
} else if ($i == "}") {
brack--;
if (brack == 0) {
withinproc = 0;
}
}
}
if ($1 != "_rpcsvcdirty" ) {
print $0
}
}
}
/_servtgt.c
0,0 → 1,305
/*
============================================================================
_SERVTGT
$Id: _servtgt.c,v 1.2 2001-09-27 12:02:01 chris Exp $
============================================================================
*/
 
 
#include <string.h>
#include <rtems.h>
#include <rtems/error.h>
 
#include <rdbg/rdbg.h>
#include <rdbg/rdbg_f.h>
#include <rdbg/servrpc.h>
#include <errno.h>
#include <sys/socket.h>
#include <assert.h>
#include <rtems/score/cpu.h>
 
#ifdef DDEBUG
#define Ptrace TgtDbgPtrace
#else
#define Ptrace TgtRealPtrace
#endif
 
extern int errno;
 
rtems_id eventTaskId;
rtems_id serializeSemId;
rtems_id wakeupEventSemId;
 
CPU_Exception_frame Idle_frame;
 
/* -----------------------------------------------------------------
TgtRealPtrace - lowest level ptrace() wrapper
----------------------------------------------------------------- */
 
int
TgtRealPtrace(int req, PID aid, char* addr, int d, void* addr2)
{
return ptrace(req, aid, addr, d, addr2);
}
 
 
 
/* -----------------------------------------------------------------------
TgtChange() is called when the system stops.
It informs the generic layers must be informed of
that fact.
----------------------------------------------------------------------- */
 
static int
TgtChange (PID pid, CPU_Exception_frame* ctx, int status)
{
 
if (TgtHandleChildChange (pid, &status, NULL, ctx)) {
TgtNotifyWaitChange (pid, status, -1);
}
 
return 0;
}
 
/* -----------------------------------------------------------------------
eventTask
----------------------------------------------------------------------- */
 
rtems_task eventTask( rtems_task_argument pid)
{
Exception_context *ctx;
 
DPRINTF (("event task: pid %d\n", pid));
 
/*
* we spend all our time waiting for a semaphore.
* If wait change, we send info
*/
for (;;){
DPRINTF (("Event Task: wait event\n"));
rtems_semaphore_obtain(wakeupEventSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
DPRINTF (("Event Task: wake up !!!!!!!!!!!!!\n"));
errno = 0;
ctx = GetExceptCtx(currentTargetThread);
 
CheckForSingleStep(ctx->ctx);
 
TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx)));
}
}
 
/* -------------------------------------------------------------------
MyThreadIdle -
 
This task is used to initiate the exception mechanism:
It calls the enterDebug function with justSaveContext=1
only to push a first valid context in the list
---------------------------------------------------------------------*/
 
rtems_task MyThreadIdle(rtems_task_argument argument)
{
enterRdbg();
rtems_task_delete( RTEMS_SELF );
}
 
/* -----------------------------------------------------------------------
TgtAttach - attach to a process that is running without control.
 
Notes:
- this function performs a ptrace ATTACH equivalent (attaching to a
process that we do not control now).
----------------------------------------------------------------------- */
 
Boolean TgtAttach(
int conn_idx, /* client that is requesting */
PID pid) /* process to attach to */
{
rtems_name task_name;
rtems_status_code status;
rtems_id debugId;
errno = 0;
 
DPRINTF (("TgtAttach pid=%d\n",pid));
Ptrace(RPT_ATTACH, pid, NULL, 0, NULL);
if (errno)
return(False); /* failed */
 
TgtCreateNew(pid, conn_idx, 0, NULL, False);
 
 
connect_rdbg_exception();
/*
* Create the attach debuger task
*/
task_name = rtems_build_name( 'E', 'v', 'n', 't' );
if ((status = rtems_task_create( task_name, 10, 24576,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES | RTEMS_SYSTEM_TASK,
&eventTaskId ))
!= RTEMS_SUCCESSFUL){
printf("status = %d\n",status);
rtems_panic ("Can't create task.\n");
}
status = rtems_task_start(eventTaskId, eventTask, pid);
 
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 's'),
1,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&serializeSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create serialize semaphore: `%s'\n",rtems_status_text(status));
 
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'w'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&wakeupEventSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create wakeup semaphore: `%s'\n",rtems_status_text(status));
 
/*
* Create the MyThreadIdle task to init Exception mechanism
*/
task_name = rtems_build_name( 'R', 'i', 'n', 'i' );
if ((status = rtems_task_create( task_name, 10, 24576,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&debugId ))
!= RTEMS_SUCCESSFUL){
printf("status = %d\n",status);
rtems_panic ("Can't create task.\n");
}
 
status = rtems_task_start(debugId, MyThreadIdle, pid);
 
return(True);
}
 
/* -----------------------------------------------------------------------
TgtPtrace - handle ptrace requests for server.
----------------------------------------------------------------------- */
 
int TgtPtrace(
int req,
PID pid,
char *addr,
int data,
void *addr2)
{
if ((req == RPT_SINGLESTEP || req == RPT_CONT)
&& addr2) /* clear then step */
{ /* addr2 is the old value */
int ret;
 
errno = 0;
TgtBreakRestoreOrig (pid, addr, addr2);
ret = Ptrace(RPT_SINGLESTEP, pid, addr, data, NULL); /* step over */
if (ret) /* error, cannot single-step */
{
int pid_idx = FindPidEntry (pid);
TgtBreakCancelStep (&pid_list [pid_idx]);
}
return(ret); /* failed or done */
}
else
return(Ptrace(req, pid, addr, data, addr2)); /* normal call */
}
 
/* -----------------------------------------------------------------
TgtGetThreadName - get thread name
--------------------------------------------------------------- */
 
int TgtGetThreadName (
PID_LIST *plst, /* Process entry */
unsigned Id, /* Thread ID */
char *ThrName) /* Thread name */
{
int index;
unsigned name;
if ( Id <_Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
 
index = Id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
name = *(unsigned*)(_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index]->name);
ThrName[0] = (char)((name >> 24) & 0xFF );
ThrName[1] = (char)((name >> 16) & 0xFF );
ThrName[2] = (char)((name >> 8) & 0xFF );
ThrName[3] = (char)( name & 0xFF );
ThrName[4] = 0x0;
return 0;
}
if ( Id <_Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
 
index = Id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
name = *(unsigned*)(_Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index]->name);
ThrName[0] = (char)((name >> 24) & 0xFF );
ThrName[1] = (char)((name >> 16) & 0xFF );
ThrName[2] = (char)((name >> 8) & 0xFF );
ThrName[3] = (char)( name & 0xFF );
ThrName[4] = 0x0;
return 0;
}
return -1;
 
}
 
/* -----------------------------------------------------------------
TgtThreadList - return all the threads in the system
----------------------------------------------------------------- */
 
int
TgtThreadList (
PID_LIST* plst, /* Process entry */
unsigned* threads, /* Output buffer */
unsigned size) /* Output buffer size */
{
int curr = 0;
Objects_Id id;
unsigned index;
 
id = _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
 
while (id < _Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id){
index = id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index] != NULL){
threads[curr] = (unsigned) id;
curr++;
}
id ++;
}
id = _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
 
while (id < _Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id){
index = id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index] != NULL){
threads[curr] = (unsigned) id;
curr++;
}
id ++;
}
return curr;
}
/servutil.c
0,0 → 1,132
/*
**********************************************************************
*
* Component: RDB
* Module: servutil.c
*
* Synopsis: Various utility routines
*
* $Id: servutil.c,v 1.2 2001-09-27 12:02:01 chris Exp $
*
**********************************************************************
*/
 
#include <string.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
 
/*----- Management of per-process list ----*/
 
/*
* ListAlloc - build up list entry.
*
* Notes:
* - this is a generic routine to build up entries in the per-connection
* list. The fields list, list_sz and list_alloc are affected.
*/
 
Boolean
ListAlloc(buff, clst)
char *buff;
CONN_LIST *clst; /* place to copy it */
{
int tmp;
char* name;
int new_len;
int len;
 
tmp = strlen(buff);
new_len = (int)clst->list_sz + 1 + tmp;
if (clst->list_alloc < (unsigned)new_len) {
/* need more space */
name = (char *)Realloc(clst->list, len = new_len + MAX_FILENAME);
if (name == NULL) {
return(False); /* failed, no space */
}
clst->list_alloc = len;
clst->list = name;
}
strcpy(clst->list + clst->list_sz, buff);
clst->list_sz += tmp;
return(True);
}
 
/*----- Management of processes -----*/
 
/*
* FindPidEntry - locate pid_list entry from pid
*/
 
int
FindPidEntry (pid)
int pid; /* process identifier */
{
int idx;
 
/* pid 0 is invalid, and signals a free slot */
if (pid_list == NULL || pid == 0) {
return -1;
}
for (idx = 0; idx < pid_list_cnt; idx++) {
if (pid_list [idx].pid == pid )
return idx;
}
return -1;
}
 
/*----- Debug suport -----*/
 
#ifdef DDEBUG
 
/*
* Names of debug primitives
*/
 
const char* PtraceNames [] = {
 
"RPT_TRACEME", "RPT_PEEKTEXT", "RPT_PEEKDATA", "RPT_PEEKUSER",
"RPT_POKETEXT", "RPT_POKEDATA", "RPT_POKEUSER", "RPT_CONT",
"RPT_KILL", "RPT_SINGLESTEP", "RPT_ATTACH", "RPT_DETACH",
"RPT_GETREGS", "RPT_SETREGS", "RPT_GETFPREGS", "RPT_SETFPREGS",
"RPT_READDATA", "RPT_WRITEDATA", "RPT_READTEXT", "RPT_WRITETEXT",
"RPT_GETFPAREGS", "RPT_SETFPAREGS", "RPT_22", "RPT_23",
"RPT_SYSCALL", "RPT_DUMPCORE", "RPT_26", "RPT_27",
"RPT_28", "RPT_GETUCODE", "RPT_30", "RPT_31",
"RPT_32", "RPT_33", "RPT_34", "RPT_35",
"RPT_36", "RPT_37", "RPT_38", "RPT_39",
"RPT_40", "RPT_41", "RPT_42", "RPT_43",
"RPT_44", "RPT_45", "RPT_46", "RPT_47",
"RPT_48", "RPT_49", "RPT_GETTARGETTHREAD", "RPT_SETTARGETTHREAD",
"RPT_THREADSUSPEND", "RPT_THREADRESUME", "RPT_THREADLIST", "RPT_GETTHREADNAME",
"RPT_SETTHREADNAME", "RPT_SETTHREADREGS", "RPT_GETTHREADREGS",
"RPT_59",
"RPT_60", "RPT_61", "RPT_62", "RPT_63",
"RPT_64", "RPT_65", "RPT_66", "RPT_67",
"RPT_68", "RPT_69", "RPT_70", "RPT_71",
"RPT_72", "RPT_73", "RPT_74", "RPT_STEPRANGE",
"RPT_CONTTO", "RPT_SETBREAK", "RPT_CLRBREAK", "RPT_GETBREAK",
"RPT_GETNAME", "RPT_STOP",
"RPT_PGETREGS", "RPT_PSETREGS",
"RPT_PSETTHREADREGS", "RPT_PGETTHREADREGS"
};
 
const char*
PtraceName(req)
int req;
{
static char bufret[40];
 
if ((req < 0) || (req >= sizeof(PtraceNames)/sizeof(char*))) {
sprintf(bufret, "BAD_REQ_%d", req);
return bufret;
}
return PtraceNames[req];
}
 
const char* BmsgNames [] = {
"?", "WARM", "WAIT", "BREAK",
"EXEC_FAIL", "DETACH", "KILLED", "NOT_PRIM",
"NEW_PID"
};
 
#endif /* DDEBUG */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.