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/gnu-old/gdb-6.8/gdb/testsuite/gdb.trace
    from Rev 827 to Rev 840
    Reverse comparison

Rev 827 → Rev 840

/Makefile.in
0,0 → 1,14
VPATH = @srcdir@
srcdir = @srcdir@
 
.PHONY: all clean mostlyclean distclean realclean
 
all info install-info dvi install uninstall installcheck check:
@echo "Nothing to be done for $@..."
 
clean mostlyclean:
-rm -f actions circ collection limits
-rm -f *.o *.diff *~ *.bad core sh3 hppa mn10300
 
distclean maintainer-clean realclean: clean
-rm -f Makefile config.status config.log
/gdb_c_test.c
0,0 → 1,3791
/*
******************************************************************************
******************************************************************************
*
* COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
* DESCRIPTION: This module has been provided for the purpose of testing GDB.
*
* NOTES:
*
******************************************************************************
*****************************************************************************/
 
/*=============================================================================
* INCLUDE FILES
*===========================================================================*/
 
 
#ifdef DO_IT_BY_THE_BOOK
 
 
#include "symtypes_defs.h"
#include "printp.h"
 
#include "adbg_expression.h"
#include "common_hw_ds.h"
#include "common_hw_defs.h"
#include "evnttrac.h"
#include "sym_scratch_ds.h"
#include "symglob_ds.h"
#include "sym_protglob_ds.h"
 
#include "ether.h"
 
#include <ctype.h>
 
 
#else
 
#include "adbg_dtc.h"
 
#define YES 1
#define NO 0
 
#define TRUE 1
#define FALSE 0
 
#define ENABLED 1
#define DISABLED 0
 
#define CONTROL_C 3 /* ASCII 'ETX' */
 
 
/*
* Faked after ctype.h
*/
 
#define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
((X) >= 'A' && (X) <= 'F') || \
((X) >= 'a' && (X) <= 'f'))
/*
* Borrowed from string.h
*/
 
extern unsigned int strlen ( const char * );
 
/*
* Extracted from symtypes.h:
*/
 
typedef char BOOL; /* 8 Bits */
typedef unsigned char UCHAR; /* 8 Bits */
typedef unsigned short USHORT; /* 16 Bits */
typedef unsigned long ULONG; /* 32 Bits */
 
/*
* for struct t_expr_tag and
* decl of build_and_add_expression
*/
#include "adbg_expression.h"
#define NULL 0
 
/*
* Extracted from printp.h:
*/
 
extern void printp ( const char * fptr, ... );
extern void sprintp ( const char * fptr, ... );
 
/*
* Extracted from ether.h:
*/
 
extern long eth_to_gdb ( UCHAR *buf, long length );
 
 
/*
* Derived from hwequs.s:
*/
 
#define CS_CODE_START 0x100000
#define CS_CODE_SIZE 0x200000
#define LAST_CS_WORD (CS_CODE_START + CS_CODE_SIZE - 2)
 
#define sh_genstat1 (*((volatile ULONG *) 0xFFFFFE54))
 
#define rs232_mode1 0 /* rs-232 mode 1 reg. */
#define rs232_mode2 rs232_mode1 /* rs-232 mode 2 reg. */
#define rs232_stat 4 /* rs-232 status reg. */
#define rs232_clk rs232_stat /* rs-232 clock select reg. */
#define rs232_cmd 8 /* rs-232 command reg */
#define rs232_transmit 12 /* rs-232 transmit reg. */
#define rs232_receive rs232_transmit /* rs-232 transmit reg. */
#define rs232_aux 16 /* rs-232 aux control reg. */
#define rs232_isr 20 /* rs-232 interrupt status reg. */
#define rs232_imr rs232_isr /* rs-232 interrupt mask reg. */
#define rs232_tc_high 24 /* rs-232 timer/counter high reg. */
#define rs232_tc_low 28 /* rs-232 timer/counter low reg. */
 
 
#endif
 
 
/*============================================================================
* MODULE DEFINES
*===========================================================================*/
 
#define P_RST_LAN_UART_REG ((volatile UCHAR *) 0xFFFFFE45)
#define M_RST_LAN_UART 0x80 /* Bit 7 */
 
#define P_LAN0TR_REG P_RST_LAN_UART_REG
#define M_LAN0TR 0x20 /* Bit 5 */
 
#define M_SH_GENCON_LAN0TR 0x00200000 /* Bit 21 */
 
#define MAX_RS232_CHARS 512
 
#define LAN_Q_MOD(X) ((X) % MAX_RS232_CHARS)
 
/*---------------------------------------*
* LAN UART Registers *
*---------------------------------------*/
 
#define LAN_UART_BASE ((ULONG) 0xfffffc22)
 
/* Write-Read */
 
#define P_LAN_MR1 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1 )))
#define P_LAN_MR2 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2 )))
 
/* Write-Only */
 
#define P_LAN_ACR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux )))
#define P_LAN_CR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd )))
#define P_LAN_CSR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk )))
#define P_LAN_CTLR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low )))
#define P_LAN_CTUR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high )))
#define P_LAN_IMR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr )))
 
/* Read-Only */
 
#define P_LAN_SR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat )))
#define P_LAN_ISR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr )))
#define P_LAN_XMT ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
#define P_LAN_RCV ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
 
/*
* Bit Values for Write-Read and Write-Only Registers
*/
 
#define DEFAULT_LAN_MR1 ((UCHAR) 0x13)
#define DEFAULT_LAN_MR2 ((UCHAR) 0x07)
#define DEFAULT_LAN_CSR ((UCHAR) 0xcc)
#define DEFAULT_LAN_ACR ((UCHAR) 0x38)
#define DEFAULT_LAN_CTUR ((UCHAR) 0xff)
#define DEFAULT_LAN_CTLR ((UCHAR) 0xff)
 
#define LAN_ACR_SELECT_BRG_0 DEFAULT_LAN_ACR
#define LAN_ACR_SELECT_BRG_1 (DEFAULT_LAN_ACR | 0x80)
 
#define UART_CR_RESET_MR_PTR ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */
#define UART_CR_RESET_RVCR ((UCHAR) 0x20) /* Reset receiver (disabled). */
#define UART_CR_RESET_XMTR ((UCHAR) 0x30) /* Reset transmitter (disabled). */
#define UART_CR_RESET_ERROR_STATUS ((UCHAR) 0x40) /* Reset error status. */
#define UART_CR_RESET_BRK_CHG_INT ((UCHAR) 0x50) /* Reset break change interrupt. */
#define UART_CR_START_CNTR_TIMER ((UCHAR) 0x80) /* Start counter/timer. */
#define UART_CR_STOP_CNTR ((UCHAR) 0x90) /* Stop counter. */
 
#define UART_CR_DISABLE_XMTR ((UCHAR) 0x08) /* Disable transmitter. */
#define UART_CR_ENABLE_XMTR ((UCHAR) 0x04) /* Enable transmitter. */
#define UART_CR_DISABLE_RCVR ((UCHAR) 0x02) /* Disable receiver. */
#define UART_CR_ENABLE_RCVR ((UCHAR) 0x01) /* Enable receiver. */
 
#define UART_CSR_BR_4800 ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */
#define UART_CSR_BR_9600 ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */
#define UART_CSR_BR_19200 ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */
#define UART_CSR_BR_38400 ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */
 
#define UART_IMR_RxRDY ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */
#define UART_IMR_TxEMT ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */
#define UART_IMR_TxRDY ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */
 
/*
* Bit Masks for Read-Only Registers
*/
 
#define M_UART_SR_RCVD_BRK 0x80 /* Bit 7 */
#define M_UART_SR_FE 0x40 /* Bit 6 */
#define M_UART_SR_PE 0x20 /* Bit 5 */
#define M_UART_SR_OE 0x10 /* Bit 4 */
#define M_UART_SR_TxEMT 0x08 /* Bit 3 */
#define M_UART_SR_TxRDY 0x04 /* Bit 2 */
#define M_UART_SR_FFULL 0x02 /* Bit 1 */
#define M_UART_SR_RxRDY 0x01 /* Bit 0 */
 
#define M_UART_ISR_RxRDY 0x04 /* Bit 2 */
#define M_UART_ISR_TxEMT 0x02 /* Bit 1 */
#define M_UART_ISR_TxRDY 0x01 /* Bit 0 */
 
/*---------------------------------------*
* Support for 'Utility 83'. *
*---------------------------------------*/
 
#define LAN_UTIL_CODE 0x83
 
#define LAN_INIT ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
#define LAN_BAUD ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
#define LAN_INTR ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
#define LAN_XMT ((ULONG) (('X' << 16) | ('M' << 8) | 'T'))
#define LAN_ECHO ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
#define LAN_STAT ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
#define LAN_IN ((ULONG) (('I' << 8) | 'N'))
#define LAN_OUT ((ULONG) (('O' << 16) | ('U' << 8) | 'T'))
 
#define LAN_PUTC ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
#define LAN_WPM ((ULONG) (('W' << 16) | ('P' << 8) | 'M'))
 
#define STATUS(X) ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
 
#define XMT_VIA_BP_ENABLED() ( *P_LAN0TR_REG & M_LAN0TR ? 1 : 0 )
 
#define TRAP_1_INST 0x4E41
 
/*
* Bit #13 of shared genstat 1 indicates
* which processor we are as follows.
*
* 0 => X (side A)
* 1 => Y (side B)
*/
 
#define M_PROC_ID 0x00002000
 
#define IS_SIDE_A() ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
#define IS_SIDE_B() ( (sh_genstat1) & M_PROC_ID )
 
 
#ifdef STANDALONE /* Compile this module stand-alone for debugging */
#define LAN_PUT_CHAR(X) printf("%c", X)
#else
#define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
#endif
 
 
 
 
#define VIA_RS232 0
#define VIA_ETHERNET 1
 
#define MAX_IO_BUF_SIZE 400
 
#define MAX_BYTE_CODES 200 /* maximum length for bytecode string */
 
 
static ULONG gdb_host_comm;
 
static ULONG gdb_cat_ack;
 
static char eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
 
 
#ifdef STANDALONE
 
#define ACK_PKT() LAN_PUT_CHAR( '+' )
#define NACK_PKT() LAN_PUT_CHAR( '-' )
 
#else
 
#define ACK_PKT() { \
if ( VIA_ETHERNET == gdb_host_comm ) \
{ \
gdb_cat_ack = YES; \
} \
else \
{ \
LAN_PUT_CHAR( '+' ); \
} \
}
 
 
 
#define NACK_PKT() { \
if ( VIA_ETHERNET == gdb_host_comm ) \
{ \
eth_outbuffer[ 0 ] = '-'; \
eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
} \
else \
{ \
LAN_PUT_CHAR( '-' ); \
} \
}
 
#endif
 
 
 
 
/*============================================================================
* MODULE TYPEDEFS
*===========================================================================*/
 
typedef struct rs232_queue {
 
long head_index;
 
long tail_index;
 
ULONG overflows;
 
long gdb_packet_start;
long gdb_packet_end;
long gdb_packet_csum1;
long gdb_packet_csum2;
 
UCHAR buf[ MAX_RS232_CHARS ];
 
} T_RS232_QUEUE;
 
 
 
 
/*=============================================================================
* EXTERNAL GLOBAL VARIABLES
*===========================================================================*/
 
extern volatile UCHAR sss_trace_flag;
 
 
/*=============================================================================
* STATIC MODULE DECLARATIONS
*===========================================================================*/
 
static T_RS232_QUEUE lan_input_queue,
lan_output_queue;
 
static BOOL test_echo;
 
#if 0
/* The stub no longer seems to use this. */
static BOOL write_access_enabled;
#endif
 
static int baud_rate_idx;
 
static ULONG tx_by_intr,
tx_by_poll;
 
static UCHAR lan_shadow_imr;
 
 
/*=============================================================================
* EXTERNAL FUNCTION PROTOTYPES
*===========================================================================*/
 
extern long write_to_protected_mem( void *address, unsigned short value );
 
 
/*=============================================================================
* MODULE GLOBAL FUNCTIONS PROTOTYPES
*===========================================================================*/
 
ULONG gdb_c_test( ULONG *parm );
 
 
void lan_init( void );
 
void lan_isr( void );
 
long lan_get_char( void );
 
long lan_put_char( UCHAR c );
 
ULONG lan_util( ULONG *parm );
 
 
/*=============================================================================
* MODULE LOCAL FUNCTION PROTOTYPES
*===========================================================================*/
 
static void lan_reset( void );
 
static void lan_configure( void );
 
static void lan_init_queue( T_RS232_QUEUE *p_queue );
 
static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
 
static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
 
static void lan_util_menu( void );
 
static long get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
 
 
/*=============================================================================
* GDB STUB FUNCTION PROTOTYPES
*===========================================================================*/
 
void gdb_trap_1_handler( void );
void gdb_trace_handler ( void );
 
void gdb_get_eth_input( unsigned char *buf, long length );
 
static void getpacket ( void );
static void putpacket ( char * );
static void discard_packet ( void );
 
#ifdef STANDALONE /* Compile this module stand-alone for debugging */
#include <stdio.h>
#define printp printf /* easier than declaring a local varargs stub func. */
#endif /* STANDALONE */
 
 
/*=============================================================================
* MODULE BODY
*===========================================================================*/
 
/* ------------------- Things that belong in a header file --------------- */
extern char *memset (char *, int, int);
 
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
* *
* Global Module Functions *
* *
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
static char gdb_char_test;
static short gdb_short_test;
static long gdb_long_test;
static char gdb_arr_test[25];
static struct GDB_STRUCT_TEST
{
char c;
short s;
long l;
int bfield : 11; /* collect bitfield */
char arr[25];
struct GDB_STRUCT_TEST *next;
} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
 
static union GDB_UNION_TEST
{
char c;
short s;
long l;
int bfield : 11; /* collect bitfield */
char arr[4];
union GDB_UNION_TEST *next;
} gdb_union1_test;
 
void gdb_recursion_test (int, int, int, int, int, int, int);
 
void gdb_recursion_test (int depth,
int q1,
int q2,
int q3,
int q4,
int q5,
int q6)
{ /* gdb_recursion_test line 0 */
int q = q1; /* gdbtestline 1 */
 
q1 = q2; /* gdbtestline 2 */
q2 = q3; /* gdbtestline 3 */
q3 = q4; /* gdbtestline 4 */
q4 = q5; /* gdbtestline 5 */
q5 = q6; /* gdbtestline 6 */
q6 = q; /* gdbtestline 7 */
if (depth--) /* gdbtestline 8 */
gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
}
 
 
ULONG gdb_c_test( ULONG *parm )
 
{
char *p = "gdb_c_test";
char *ridiculously_long_variable_name_with_equally_long_string_assignment;
register long local_reg = 7;
static unsigned long local_static, local_static_sizeof;
long local_long;
unsigned long *stack_ptr;
unsigned long end_of_stack;
 
ridiculously_long_variable_name_with_equally_long_string_assignment =
"ridiculously long variable name with equally long string assignment";
local_static = 9;
local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
local_long = local_reg + 1;
stack_ptr = (unsigned long *) &local_long;
end_of_stack =
(unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
 
printp ("\n$Id$\n");
 
printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] );
 
gdb_char_test = gdb_struct1_test.c = (char) ((long) parm[1] & 0xff);
gdb_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff);
gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff);
gdb_union1_test.l = (long) parm[4];
gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
gdb_struct1_test.bfield = 144;
gdb_struct1_test.next = &gdb_struct2_test;
gdb_structp_test = &gdb_struct1_test;
gdb_structpp_test = &gdb_structp_test;
 
gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
(long) parm[4], (long) parm[5], (long) parm[6]);
 
gdb_char_test = gdb_short_test = gdb_long_test = 0;
gdb_structp_test = (void *) 0;
gdb_structpp_test = (void *) 0;
memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
local_static_sizeof = 0;
local_static = 0;
return ( (ULONG) 0 );
}
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_init
*
*
* DESCRIPTION:
*
*
* RETURN VALUE:
*
*
* USED GLOBAL VARIABLES:
*
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
*
* NOTES:
*
*
*
*---------------------------------------------------------------------------*/
 
void lan_init( void )
 
{
 
if ( IS_SIDE_A( ) )
{
 
lan_reset( );
 
lan_init_queue( &lan_input_queue );
 
lan_init_queue( &lan_output_queue );
 
lan_configure( );
}
 
return;
}
/* end of 'lan_init'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_isr
*
*
* DESCRIPTION:
*
*
* RETURN VALUE: None.
*
*
* USED GLOBAL VARIABLES:
*
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
*
* NOTES:
*
*
*---------------------------------------------------------------------------*/
 
void lan_isr( void )
 
{
UCHAR c;
 
 
lan_shadow_imr = 0; /* Disable all UART interrupts. */
*P_LAN_IMR = lan_shadow_imr;
 
 
if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
{
 
gdb_host_comm = VIA_RS232;
 
c = *P_LAN_RCV;
 
if ( test_echo )
{
/* ????? */
}
 
if ( c == CONTROL_C )
{
/* can't stop the target, but we can tell gdb to stop waiting... */
discard_packet( );
putpacket( "S03" ); /* send back SIGINT to the debugger */
}
 
else
{
lan_add_to_queue( (long) c, &lan_input_queue );
get_gdb_input( (long) c, &lan_input_queue );
}
 
}
 
if ( XMT_VIA_BP_ENABLED( ) )
{
 
c = 0;
 
while ( (*P_LAN_ISR & M_UART_ISR_TxRDY) && (c = lan_next_queue_char( &lan_output_queue )) )
{
*P_LAN_XMT = c;
++tx_by_intr;
}
 
if ( c )
{
lan_shadow_imr |= UART_IMR_TxRDY; /* (Re-)Enable 'TxRDY' interrupt from UART. */
}
 
}
 
 
lan_shadow_imr |= UART_IMR_RxRDY; /* Re-Enable 'RxRDY' interrupt from UART. */
*P_LAN_IMR = lan_shadow_imr;
 
 
 
return;
}
/* end of 'lan_isr'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_get_char
*
*
* DESCRIPTION: Fetches a character from the UART.
*
*
* RETURN VALUE: 0 on success, -1 on failure.
*
*
* USED GLOBAL VARIABLES:
*
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
*
* NOTES:
*
*
*---------------------------------------------------------------------------*/
 
long lan_get_char( void )
 
{
long status = -2; /* AGD: nothing found in rcv buffer */
 
if ( *P_LAN_SR & M_UART_SR_RxRDY )
{
char c = (char) *P_LAN_RCV;
 
if ( test_echo )
{
LAN_PUT_CHAR ( c );
}
 
if ( c == CONTROL_C )
{
/* can't stop the target, but we can tell gdb to stop waiting... */
discard_packet( );
putpacket( "S03" ); /* send back SIGINT to the debugger */
status = 0; /* success */
}
 
else
{
lan_add_to_queue( (long) c, &lan_input_queue );
status = get_gdb_input( (long) c, &lan_input_queue );
}
 
}
 
return( status );
}
/* end of 'lan_get_char'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_put_char
*
* DESCRIPTION: Puts a character out via the UART.
*
* RETURN VALUE: 0 on success, -1 on failure.
*
* USED GLOBAL VARIABLES: none.
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
* NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! !!
* !! If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY. !!
* !! This prevents anyone infinite-looping on this function. !!
* !! !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
*---------------------------------------------------------------------------*/
 
long lan_put_char( UCHAR c )
 
{
long status = -1;
 
if ( XMT_VIA_BP_ENABLED( ) )
{
 
if ( *P_LAN_SR & M_UART_SR_TxRDY )
{
lan_add_to_queue( (long) c, &lan_output_queue );
 
c = lan_next_queue_char( &lan_output_queue );
 
*P_LAN_XMT = c;
++tx_by_poll;
status = 0;
}
#if 0
else
{
status = 0;
lan_shadow_imr |= UART_IMR_TxRDY; /* Enable 'TxRDY' interrupt from UART. */
*P_LAN_IMR = lan_shadow_imr;
}
#endif
}
 
else
{
status = 0; /* You lose: input character goes to the bit bucket. */
}
 
return( status );
}
/* end of 'lan_put_char'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_util
*
* DESCRIPTION:
*
* RETURN VALUE:
*
* USED GLOBAL VARIABLES:
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
* NOTES:
*
*---------------------------------------------------------------------------*/
 
ULONG lan_util( ULONG *parm )
 
{
 
 
static const struct {
 
ULONG rate_code;
UCHAR acr_setting;
UCHAR csr_setting;
 
} baud_rate_setting [] = {
 
{ 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
{ 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
{ 0x9600, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600 },
{ 0x4800, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800 }
};
 
 
#define BOGUS_P1 0xE1
#define BOGUS_P2 0xE2
 
ULONG not_done_code;
 
 
ULONG opcode;
ULONG parm_1;
ULONG parm_2;
 
int i;
UCHAR c;
 
 
not_done_code = 0;
 
opcode = parm[ 1 ];
parm_1 = parm[ 2 ];
parm_2 = parm[ 3 ];
 
 
switch ( opcode )
{
 
case LAN_INIT:
{
 
lan_init( );
printp( "\n\n Interface (Re)Initialized ...\n\n" );
 
break;
}
 
 
case LAN_BAUD:
{
 
for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
{
if ( baud_rate_setting[i].rate_code == parm_1 )
{
baud_rate_idx = i;
*P_LAN_ACR = baud_rate_setting[i].acr_setting;
*P_LAN_CSR = baud_rate_setting[i].csr_setting;
printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
return( not_done_code );
}
}
 
printp( "\n\n *** SYNTAX Error - Invalid baudrate (P2)\n\n" );
not_done_code = BOGUS_P2;
 
break;
}
 
 
case LAN_INTR:
{
 
switch ( parm_1 )
{
 
case 0x0D: /* Disable 'RxRDY' Interrupts */
{
lan_shadow_imr &= ~UART_IMR_RxRDY;
*P_LAN_IMR = lan_shadow_imr;
printp( "\n\n Receive Ready Interrupts DISABLED ...\n\n" );
break;
}
 
case 0x0E: /* Enable 'RxRDY' Interrupts */
{
lan_shadow_imr |= UART_IMR_RxRDY;
*P_LAN_IMR = lan_shadow_imr;
printp( "\n\n Receive Ready Interrupts ENABLED ...\n\n" );
break;
}
 
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
not_done_code = BOGUS_P2;
}
}
 
break;
}
 
 
case LAN_XMT:
{
 
switch ( parm_1 )
{
 
case 0x0E: /* Enable Transmission-via-Backplane */
{
if ( !(*P_LAN0TR_REG & M_LAN0TR) )
{
*P_LAN0TR_REG |= M_LAN0TR; /* 0 -> 1 */
}
 
printp( "\n\n Transmit-via-Backplane ENABLED ...\n\n" );
break;
}
 
case 0x0D: /* Disable Transmission-via-Backplane */
{
if ( *P_LAN0TR_REG & M_LAN0TR )
{
*P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
}
 
printp( "\n\n Transmit-via-Backplane DISABLED ...\n\n" );
break;
}
 
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
not_done_code = BOGUS_P2;
lan_util_menu( );
}
}
 
break;
}
 
 
case LAN_STAT:
{
 
printp( "\n -- Status --\n\n" );
 
printp( " Baud Rate: %X *\n", baud_rate_setting[ baud_rate_idx ].rate_code );
printp( " Xmt-via-BP: %s *\n", STATUS( XMT_VIA_BP_ENABLED( ) ) );
printp( " RxRdy Intr: %s *\n", STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
/*** printp( " TxRdy Intr: %s\n", STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/
printp( " Echo: %s *\n\n", STATUS( test_echo ) );
 
printp( " IMR: %02X\n", (ULONG) lan_shadow_imr );
printp( " ISR: %02X\n", (ULONG) *P_LAN_ISR );
printp( " SR: %02X\n\n", (ULONG) *P_LAN_SR );
 
printp( " Input Overflows: %d\n\n", lan_input_queue.overflows );
 
printp( " Tx by Intr: %d\n", tx_by_intr );
printp( " Tx by Poll: %d\n\n", tx_by_poll );
 
printp( " * Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
 
break;
}
 
 
case LAN_IN:
{
 
switch ( parm_1 )
{
 
case 0x0C: /* Clear and Reset Queue */
{
lan_init_queue( &lan_input_queue );
printp( "\n\n Queue CLEARED/RESET ...\n\n" );
break;
}
 
case 0x0D: /* Display Queue */
{
printp( "\n -- Input Queue --\n" );
printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
(ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
 
for ( i = 0; i < MAX_RS232_CHARS; ++i )
{
printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
 
if ( 15 == (i % 16) )
{
int j;
 
printp ( " " );
for ( j = i - 15; j <= i; j++ )
{
if ( lan_input_queue.buf[ j ] >= ' ' &&
lan_input_queue.buf[ j ] < 127 )
printp ( "%c", lan_input_queue.buf[ j ] );
else
printp ( "." );
}
printp( "\n " );
}
 
else if ( 7 == (i % 8) )
{
printp( " " );
}
 
}
 
printp( "\n" );
 
break;
}
 
case 0x0F: /* Fetch next character in Queue */
{
c = lan_next_queue_char( &lan_input_queue );
 
if ( c )
{
printp( "\n\n Next Character: " );
if ( 0x21 <= c && c <= 0x7F )
{
printp( "%c\n\n", (ULONG) c );
}
 
else if ( 0x20 == ((UCHAR) c) )
{
printp( "<space>\n\n" );
}
 
else
{
printp( "%02X\n\n", (ULONG) c );
}
}
 
else
{
printp( "\n\n Input Queue EMPTY ...\n\n" );
}
 
break;
}
 
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
not_done_code = BOGUS_P2;
break;
}
}
 
break;
}
 
 
case LAN_OUT:
{
 
switch ( parm_1 )
{
 
case 0x0C: /* Clear and Reset Queue */
{
lan_init_queue( &lan_output_queue );
printp( "\n\n Queue CLEARED/RESET ...\n\n" );
break;
}
 
case 0x0D: /* Display Queue */
{
printp( "\n -- Output Queue --\n" );
printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
(ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
 
for ( i = 0; i < MAX_RS232_CHARS; ++i )
{
printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
 
if ( 15 == (i % 16) )
{
int j;
 
printp ( " " );
for ( j = i - 15; j <= i; j++ )
{
if ( lan_output_queue.buf[ j ] >= ' ' &&
lan_output_queue.buf[ j ] < 127 )
printp ( "%c", lan_output_queue.buf[ j ] );
else
printp ( "." );
}
printp( "\n " );
}
 
else if ( 7 == (i % 8) )
{
printp( " " );
}
 
}
 
printp( "\n" );
 
break;
}
 
case 0x0F: /* Fetch next character in Queue */
{
c = lan_next_queue_char( &lan_output_queue );
 
if ( c )
{
printp( "\n\n Next Character: " );
if ( 0x21 <= c && c <= 0x7F )
{
printp( "%c\n\n", (ULONG) c );
}
 
else if ( 0x20 == c )
{
printp( "<space>\n\n" );
}
 
else
{
printp( "%02X\n\n", (ULONG) c );
}
}
 
else
{
printp( "\n\n Input Queue EMPTY ...\n\n" );
}
 
break;
}
 
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
not_done_code = BOGUS_P2;
break;
}
}
 
break;
}
 
 
case LAN_ECHO:
{
 
switch ( parm_1 )
{
 
case 0x0E:
{
test_echo = ENABLED;
printp( "\n\n Test echo ENABLED ...\n\n" );
break;
}
 
case 0x0D:
{
test_echo = DISABLED;
printp( "\n\n Test echo DISABLED ...\n\n" );
break;
}
 
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
not_done_code = BOGUS_P2;
break;
}
}
 
break;
}
 
 
case LAN_PUTC:
{
 
if ( 0x20 < parm_1 && parm_1 < 0x7F )
{
if ( lan_put_char( (UCHAR) parm_1 ) )
{
printp( "\n\n *** 'lan_put_char' Error ...\n" );
}
 
else
{
printp( "\n\n O.K. ...\n" );
}
 
}
 
else
{
printp( "\n\n *** Error - character must be in the 0x21-0x7E range ...\n" );
not_done_code = BOGUS_P2;
}
 
break;
}
 
/***
case LAN_WPM:
{
 
if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
{
printp( "\n Write to protected memory FAILED ...\n" );
}
 
break;
}
***/
 
case 0: /* no argument -- print menu */
{
lan_util_menu( );
break;
}
 
 
default:
{
parm_2 = 0; /* to supress compiler warning with 'LAN_WPM' case disabled */
 
printp( "\n\n *** SYNTAX Error - Invalid P1 ...\n\n" );
not_done_code = BOGUS_P1;
break;
}
 
 
} /* End of 'switch ( opcode )'. */
 
 
return( not_done_code );
}
/* end of 'lan_util'
*===========================================================================*/
 
 
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
* *
* Local Module Functions *
* *
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_reset
*
* DESCRIPTION: Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
* Shared Control 1 area.
*
* 1 _| ______
* | | |
* Bit | | |
* | | |
* 0 _|______| |______
* |---------------------> t
*
* RETURN VALUE: None.
*
* USED GLOBAL VARIABLES:
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
* NOTES: H/W configuration requires that a byte in the shared
* control 1 area must be read before being written.
*
*---------------------------------------------------------------------------*/
 
static void lan_reset( void )
 
{
 
while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
{
*P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */
}
 
while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
{
*P_RST_LAN_UART_REG |= M_RST_LAN_UART; /* 1 */
}
 
while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
{
*P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */
}
 
}
/* end of 'lan_reset'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_configure
*
*
* DESCRIPTION:
*
*
* RETURN VALUE:
*
*
* USED GLOBAL VARIABLES:
*
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
*
* NOTES:
*
*
*
*---------------------------------------------------------------------------*/
 
static void lan_configure( void )
 
{
 
*P_LAN_CR = UART_CR_RESET_MR_PTR; /* Points to MR1. */
*P_LAN_CR = UART_CR_RESET_RVCR; /* Receiver disabled. */
*P_LAN_CR = UART_CR_RESET_XMTR; /* Transmitter disabled. */
*P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
*P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
 
*P_LAN_MR1 = DEFAULT_LAN_MR1;
*P_LAN_MR2 = DEFAULT_LAN_MR2;
 
*P_LAN_ACR = DEFAULT_LAN_ACR;
 
*P_LAN_CSR = UART_CSR_BR_9600;
baud_rate_idx = 2;
 
*P_LAN_CTUR = DEFAULT_LAN_CTUR;
*P_LAN_CTLR = DEFAULT_LAN_CTLR;
 
*P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
 
lan_shadow_imr = UART_IMR_RxRDY; /* Enable only 'RxRDY' interrupt from UART. */
*P_LAN_IMR = lan_shadow_imr;
 
tx_by_intr = 0;
tx_by_poll = 0;
 
return;
}
/* end of 'lan_configure'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_init_queue
*
* DESCRIPTION:
*
* RETURN VALUE: None.
*
* USED GLOBAL VARIABLES:
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
* NOTES:
*
*---------------------------------------------------------------------------*/
 
static void lan_init_queue( T_RS232_QUEUE *p_queue )
 
{
long i;
 
/*
* We set "head" equal to "tail" implying the queue is empty,
* BUT the "head" and "tail" should each point to valid queue
* positions.
*/
 
p_queue->head_index = 0;
p_queue->tail_index = 0;
 
p_queue->overflows = 0;
 
p_queue->gdb_packet_start = -1;
p_queue->gdb_packet_end = -1;
 
p_queue->gdb_packet_csum1 = -1;
p_queue->gdb_packet_csum2 = -1;
 
for ( i = 0; i < MAX_RS232_CHARS; ++i )
{
p_queue->buf[ i ] = 0;
}
 
return;
}
/* end of 'lan_init_queue'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_add_to_queue
*
*
* DESCRIPTION: Adds the specified character to the tail of the
* specified queue. Observes "oldest thrown on floor"
* rule (i.e. the queue is allowed to "wrap" and the
* input character is unconditionally placed at the
* tail of the queue.
*
*
* RETURN VALUE: None.
*
*
* USED GLOBAL VARIABLES:
*
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
*
* NOTES:
*
*
*---------------------------------------------------------------------------*/
 
static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
 
{
 
if ( p_queue ) /* Sanity check. */
{
 
if ( c & 0x000000FF ) /* We don't allow NULL characters to be added to a queue. */
{
/* Insert the new character at the tail of the queue. */
 
p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
 
/* Increment the tail index. */
 
if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
{
p_queue->tail_index = 0;
}
 
/* Check for wrapping (i.e. overflow). */
 
if ( p_queue->head_index == p_queue->tail_index )
{
/* If the tail has caught up to the head record the overflow . . . */
 
++(p_queue->overflows);
 
/* . . . then increment the head index. */
 
if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
{
p_queue->head_index = 0;
}
 
}
 
} /* End of 'if ( c & 0x000000FF )'. */
 
} /* End of 'if ( p_queue )'. */
 
 
return;
}
/* end of 'lan_add_to_queue'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_next_queue_char
*
* DESCRIPTION:
*
* RETURN VALUE:
*
* USED GLOBAL VARIABLES:
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
* NOTES:
*
*---------------------------------------------------------------------------*/
 
static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue )
 
{
UCHAR c;
 
 
c = 0;
 
if ( p_queue )
{
 
if ( p_queue->head_index != p_queue->tail_index )
{
/* Return the 'oldest' character in the queue. */
 
c = p_queue->buf[ p_queue->head_index ];
 
/* Increment the head index. */
 
if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
{
p_queue->head_index = 0;
}
 
}
 
} /* End of 'if ( p_queue )'. */
 
 
return( c );
}
 
/* end of 'lan_next_queue_char'
*===========================================================================*/
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: lan_util_menu
*
* DESCRIPTION: Prints out a brief help on the LAN UART control utility.
*
* RETURN VALUE: None.
*
* USED GLOBAL VARIABLES: None.
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
*
* NOTES: None.
*
*---------------------------------------------------------------------------*/
 
static void lan_util_menu( void )
 
{
 
/*
* Multiply calling printp() below is made due to the limitations
* of printp(), incapable of handling long formatting constants:
*/
 
printp( "\n -- Options --\n\n" );
 
printp( " %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE );
printp( " %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE );
 
printp( " %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
 
/***
printp( " %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
***/
 
printp( " <rate>: 4800 <mode>: E - enable <action>: C - clear/reset\n" );
printp( " 9600 D - disable D - display\n" );
printp( " 19200 F - fetch next char\n" );
printp( " 38400\n" );
}
/* end of 'lan_util_menu'
*===========================================================================*/
 
 
/* Thu Feb 5 17:14:41 EST 1998 CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
 
 
static long get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
 
{
 
/* Now to detect when we've got a gdb packet... */
 
if ( '$' == c ) { /* char marks beginning of a packet */
 
if ( -1 != p_input_q->gdb_packet_start ||
-1 != p_input_q->gdb_packet_end ||
-1 != p_input_q->gdb_packet_csum1 ||
-1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
 
/* NEW: Actually, this probably means that we muffed a packet,
and GDB has already resent it. The thing to do now is to
throw away the one we WERE working on, but immediately start
accepting the new one. Don't NAK, or GDB will have to try
and send it yet a third time! */
 
/*NACK_PKT( );*/ /*<ETHERNET>*/
discard_packet( ); /* throw away old packet */
lan_add_to_queue ('$', p_input_q); /* put the new "$" back in */
return 0;
} else { /* match new "$" */
p_input_q->gdb_packet_start = p_input_q->tail_index;
p_input_q->gdb_packet_end =
p_input_q->gdb_packet_csum1 =
p_input_q->gdb_packet_csum2 = -1;
}
} else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
 
if ( -1 == p_input_q->gdb_packet_start ||
-1 != p_input_q->gdb_packet_end ||
-1 != p_input_q->gdb_packet_csum1 ||
-1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
 
/* Garbled packet. Discard, but do not NAK. */
 
/*NACK_PKT( );*/ /*<ETHERNET>*/
discard_packet( );
return -1;
}
p_input_q->gdb_packet_end = p_input_q->tail_index;
p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
 
} else if ( -1 != p_input_q->gdb_packet_start &&
-1 != p_input_q->gdb_packet_end) {
 
if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
 
if ( -1 == p_input_q->gdb_packet_csum1 &&
LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
p_input_q->tail_index ) {
 
/* first checksum digit */
 
p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
p_input_q->gdb_packet_csum2 = -1;
 
} else if ( -1 == p_input_q->gdb_packet_csum2 &&
LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
p_input_q->tail_index ) {
 
/* second checksum digit: packet is complete! */
 
p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
getpacket(); /* got a packet -- extract it */
 
} else { /* probably can't happen (um... three hex digits?) */
 
/* PROTOCOL ERROR */
/* Not sure how this can happen, but ...
discard it, but do not NAK it. */
/*NACK_PKT( );*/ /*<ETHERNET>*/
discard_packet( );
return -1;
}
 
} else { /* '#' followed by non-hex char */
 
/* PROTOCOL ERROR */
/* Bad packet -- discard but do not NAK */
/*NACK_PKT( );*/ /*<ETHERNET>*/
discard_packet( );
return -1;
}
}
 
return 0;
}
 
 
 
 
#ifdef STANDALONE
 
/* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone
stand-alone stand-alone
stand-alone Enable stand-alone build, for ease of debugging stand-alone
stand-alone stand-alone
stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */
 
long write_to_protected_mem (addr, word)
void *addr;
unsigned short word;
{
return 0;
}
 
 
char dummy_memory[0x4000];
 
int main ( void )
{
long c;
 
lan_init_queue( &lan_input_queue );
printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
while ( (c = getc( stdin ) ) != EOF )
{
if ( c == '\\' ) /* escape char */
break;
 
lan_add_to_queue( c, &lan_input_queue );
get_gdb_input (c, &lan_input_queue);
fflush( stdout );
}
 
printf( "Goodbye!\n" );
exit( 0 );
}
 
#define SRAM_START ((void *) (&dummy_memory[0] + 0x00000000))
#define SRAM_END ((void *) (&dummy_memory[0] + 0x00000400))
 
#define RO_AREA_START ((void *) (&dummy_memory[0] + 0x00000100))
#define RO_AREA_END ((void *) (&dummy_memory[0] + 0x00000300))
 
#define NVD_START ((void *) (&dummy_memory[0] + 0x00003000))
#define NVD_END ((void *) (&dummy_memory[0] + 0x00003100))
 
#else /* normal stub (not stand-alone) */
 
#define SRAM_START ((void *) 0x00000000)
#define SRAM_END ((void *) 0x00400000)
 
#define RO_AREA_START ((void *) 0x00100000)
#define RO_AREA_END ((void *) 0x00300000)
 
#define NVD_START ((void *) 0x03000000)
#define NVD_END ((void *) 0x03100000)
 
#endif /* STANDALONE */
 
 
 
 
/* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb
gdb gdb
gdb Here begins the gdb stub section. gdb
gdb The following functions were added by Cygnus, gdb
gdb to make this thing act like a gdb stub. gdb
gdb gdb
gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */
 
 
/* ------------------- global defines and data decl's -------------------- */
 
#define hexchars "0123456789abcdef"
 
/* there are 180 bytes of registers on a 68020 w/68881 */
/* many of the fpa registers are 12 byte (96 bit) registers */
#define NUMREGBYTES 180
#define NUMREGS 29
#define REGISTER_BYTE(regno) regno
 
enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
A0, A1, A2, A3, A4, A5, A6, A7,
PS, PC,
FP0, FP1,
FP2, FP3,
FP4, FP5,
FP6, FP7,
FPCONTROL, FPSTATUS, FPIADDR
};
 
unsigned long registers[NUMREGBYTES/4];
 
static long remote_debug;
 
#define BUFMAX MAX_IO_BUF_SIZE
static char inbuffer[BUFMAX], outbuffer[BUFMAX];
static char spare_buffer[BUFMAX];
 
 
struct stub_trace_frame
{
int valid;
unsigned long frame_id;
unsigned long tdp_id;
FRAME_DEF *frame_data;
COLLECTION_FORMAT_DEF *format;
unsigned long traceregs[NUMREGBYTES/4];
unsigned char *stack_data;
unsigned char *memrange_data;
} curframe;
 
/* ------------------- function prototypes -------------------- */
 
void handle_request ( char * );
 
/* ------------------- Implementation -------------------- */
 
static void
discard_packet( void )
{
lan_input_queue.head_index = lan_input_queue.tail_index;
 
lan_input_queue.gdb_packet_start =
lan_input_queue.gdb_packet_end =
lan_input_queue.gdb_packet_csum1 =
lan_input_queue.gdb_packet_csum2 = -1;
}
 
/* Utility function: convert an ASCII isxdigit to a hex nybble */
 
static long
hex( char ch )
{
if ( (ch >= 'A') && (ch <= 'F') )
return ch - 'A' + 10;
if ( (ch >= 'a') && (ch <= 'f') )
return ch - 'a' + 10;
if ( (ch >= '0') && (ch <= '9') )
return ch - '0';
return -1;
}
 
static void
getpacket( void )
{
unsigned char our_checksum, their_checksum;
char *copy = inbuffer;
unsigned char c;
 
our_checksum = 0;
 
/* first find the '$' */
while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
if (c == 0) /* ??? Protocol error? (paranoia) */
{
/* PROTOCOL ERROR (missing '$') */
/*NACK_PKT( );*/ /*<ETHERNET>*/
return;
}
 
/* Now copy the message (up to the '#') */
for (c = lan_next_queue_char ( &lan_input_queue ); /* skip the '$' */
c != 0 && c != '#'; /* stop at the '#' */
c = lan_next_queue_char ( &lan_input_queue ))
{
*copy++ = c;
our_checksum += c;
}
*copy++ = '\0'; /* terminate the copy */
 
if (c == 0) /* ??? Protocol error? (paranoia) */
{
/* PROTOCOL ERROR (missing '#') */
/*NACK_PKT( );*/ /*<ETHERNET>*/
return;
}
their_checksum = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
 
/* Now reset the queue packet-recognition bits */
discard_packet( );
 
if ( remote_debug ||
our_checksum == their_checksum )
{
ACK_PKT( ); /* good packet */
/* Parse and process the packet */
handle_request( inbuffer );
}
else
/* PROTOCOL ERROR (bad check sum) */
NACK_PKT( );
}
 
/* EMC will provide a better implementation
(perhaps just of LAN_PUT_CHAR) that does not block.
For now, this works. */
 
 
static void
putpacket( char *str )
{
unsigned char checksum;
 
/* '$'<packet>'#'<checksum> */
 
if ( VIA_ETHERNET == gdb_host_comm )
{
char *p_out;
long length;
 
p_out = eth_outbuffer;
length = 0;
 
 
if ( YES == gdb_cat_ack )
{
*p_out++ = '+';
++length;
}
 
gdb_cat_ack = NO;
 
 
*p_out++ = '$';
++length;
 
checksum = 0;
 
while ( *str )
{
*p_out++ = *str;
++length;
checksum += *str++;
}
 
*p_out++ = '#';
*p_out++ = hexchars[checksum >> 4];
*p_out = hexchars[checksum % 16];
length += 3;
 
eth_to_gdb( (UCHAR *) eth_outbuffer, length );
}
 
else
{
 
/* via RS-232 */
do {
LAN_PUT_CHAR( '$' );
checksum = 0;
 
while ( *str )
{
LAN_PUT_CHAR( *str );
checksum += *str++;
}
 
LAN_PUT_CHAR( '#' );
LAN_PUT_CHAR( hexchars[checksum >> 4] );
LAN_PUT_CHAR( hexchars[checksum % 16] );
} while ( 0 /* get_debug_char( ) != '+' */ );
/* XXX FIXME: not waiting for the ack. */
 
}
 
}
 
 
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: gdb_get_eth_input
*
*
* DESCRIPTION:
*
*
* RETURN VALUE: None.
*
*
* USED GLOBAL VARIABLES:
*
*
* AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
*
*
* NOTES:
*
*
*---------------------------------------------------------------------------*/
 
void gdb_get_eth_input( unsigned char *buf, long length )
 
{
 
gdb_host_comm = VIA_ETHERNET;
 
for ( ; 0 < length; ++buf, --length)
{
 
if ( *buf == CONTROL_C )
{
/* can't stop the target, but we can tell gdb to stop waiting... */
discard_packet( );
putpacket( "S03" ); /* send back SIGINT to the debugger */
}
 
else
{
lan_add_to_queue( (long) *buf, &lan_input_queue );
get_gdb_input( (long) *buf, &lan_input_queue );
}
 
}
 
 
return;
}
/* end of 'gdb_get_eth_input'
*===========================================================================*/
 
 
 
 
/* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT
Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
 
Dear reader:
This code is based on the premise that if GDB receives a packet
from the stub that begins with the character CAPITAL-OH, GDB will
echo the rest of the packet to GDB's console / stdout. This gives
the stub a way to send a message directly to the user. In practice,
(as currently implemented), GDB will only accept such a packet when
it believes the target to be running (ie. when you say STEP or
CONTINUE); at other times it does not expect it. This will probably
change as a side effect of the "asynchronous" behavior.
 
Functions: gdb_putchar(char ch)
gdb_write(char *str, int len)
gdb_puts(char *str)
gdb_error(char *format, char *parm)
*/
 
#if 0 /* avoid compiler warning while this is not used */
 
/* Function: gdb_putchar(int)
Make gdb write a char to stdout.
Returns: the char */
 
static int
gdb_putchar( long ch )
{
char buf[4];
 
buf[0] = 'O';
buf[1] = hexchars[ch >> 4];
buf[2] = hexchars[ch & 0x0F];
buf[3] = 0;
putpacket( buf );
return ch;
}
#endif
 
/* Function: gdb_write(char *, int)
Make gdb write n bytes to stdout (not assumed to be null-terminated).
Returns: number of bytes written */
 
static int
gdb_write( char *data, long len )
{
char *buf, *cpy;
long i;
 
buf = outbuffer;
buf[0] = 'O';
i = 0;
while ( i < len )
{
for ( cpy = buf+1;
i < len && cpy < buf + BUFMAX - 3;
i++ )
{
*cpy++ = hexchars[data[i] >> 4];
*cpy++ = hexchars[data[i] & 0x0F];
}
*cpy = 0;
putpacket( buf );
}
return len;
}
 
/* Function: gdb_puts(char *)
Make gdb write a null-terminated string to stdout.
Returns: the length of the string */
 
static int
gdb_puts( char *str )
{
return gdb_write( str, strlen( str ) );
}
 
/* Function: gdb_error(char *, char *)
Send an error message to gdb's stdout.
First string may have 1 (one) optional "%s" in it, which
will cause the optional second string to be inserted. */
 
#if 0
static void
gdb_error( char *format, char *parm )
{
static char buf[400];
char *cpy;
long len;
 
if ( remote_debug )
{
if ( format && *format )
len = strlen( format );
else
return; /* empty input */
 
if ( parm && *parm )
len += strlen( parm );
 
for ( cpy = buf; *format; )
{
if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
{
format += 2; /* advance two chars instead of just one */
while ( parm && *parm )
*cpy++ = *parm++;
}
else
*cpy++ = *format++;
}
*cpy = '\0';
gdb_puts( buf );
}
}
#endif
 
static void gdb_note (char *, int);
static int error_ret (int, char *, int);
 
static unsigned long
elinum_to_index (unsigned long elinum)
{
if ((elinum & 0xf0) == 0xd0)
return (elinum & 0x0f);
else if ((elinum & 0xf0) == 0xa0)
return (elinum & 0x0f) + 8;
else
return -1;
}
 
static long
index_to_elinum (unsigned long index)
{
if (index <= 7)
return index + 0xd0;
else if (index <= 15)
return (index - 8) + 0xa0;
else
return -1;
}
 
 
/*
READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
 
The following code pertains to reading memory from the target.
Some sort of exception handling should be added to make it safe.
 
READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
 
Safe Memory Access:
 
All reads and writes into the application's memory will pass thru
get_uchar() or set_uchar(), which check whether accessing their
argument is legal before actual access (thus avoiding a bus error).
 
*/
 
enum { SUCCESS = 0, FAIL = -1 };
 
#if 0
static long get_uchar ( const unsigned char * );
#endif
static long set_uchar ( unsigned char *, unsigned char );
static long read_access_violation ( const void * );
static long write_access_violation ( const void * );
static long read_access_range(const void *, long);
static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
 
static int
dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
{
if (src)
sprintp (spare_buffer,
"'%s' returned DTC error '%s'.\n", src, get_err_text (code));
else
sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
 
gdb_puts (spare_buffer);
return ret;
}
 
 
#if 0
/* I think this function is unnecessary since the introduction of
adbg_find_memory_addr_in_frame. */
 
/* Return the number of expressions in the format associated with a
given trace frame. */
static int
count_frame_exprs (FRAME_DEF *frame)
{
CFD *format;
T_EXPR *expr;
int num_exprs;
 
/* Get the format from the frame. */
get_frame_format_pointer (frame, &format);
 
/* Walk the linked list of expressions, and count the number of
expressions we find there. */
num_exprs = 0;
for (expr = format->p_cfd_expr; expr; expr = expr->next)
num_exprs++;
 
return num_exprs;
}
#endif
 
#if 0
/* Function: get_frame_addr
*
* Description: If the input memory address was collected in the
* current trace frame, then lookup and return the address
* from within the trace buffer from which the collected byte
* may be retrieved. Else return -1. */
 
unsigned char *
get_frame_addr ( const unsigned char *addr )
{
unsigned char *base, *regs, *stack, *mem;
CFD *dummy;
DTC_RESPONSE ret;
 
/* first, see if addr is on the saved piece of stack for curframe */
if (curframe.format->stack_size > 0 &&
(base = (unsigned char *) curframe.traceregs[A7]) <= addr &&
addr < base + curframe.format->stack_size)
{
gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n");
if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data,
&dummy,
(void *) &regs,
(void *) &stack,
(void *) &mem))
!= OK_TARGET_RESPONSE)
return (void *) dtc_error_ret (-1,
"get_addr_to_frame_regs_stack_mem",
ret);
else
return stack + (addr - base);
}
 
/* Next, try to find addr in the current frame's expression-
collected memory blocks. I'm sure this is at least quadradic in
time. */
{
int num_exprs = count_frame_exprs (curframe.frame_data);
int expr, block;
 
/* Try each expression in turn. */
for (expr = 0; expr < num_exprs; expr++)
{
for (block = 0; ; block++)
{
T_EXPR_DATA *data;
if (adbg_get_expr_data (curframe.frame_data,
'x', expr, block,
&data)
!= OK_TARGET_RESPONSE)
break;
else if ((unsigned char *) data->address <= addr
&& addr < ((unsigned char *) data->address + data->size))
{
/* We have found the right block; is it valid data?
Upper-case stamps mean bad data. */
if ('A' <= data->stamp && data->stamp <= 'Z')
{
gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
return (unsigned char *) -1;
}
else
{
if (remote_debug > 1)
{
sprintp(spare_buffer,
"STUB: get_frame_addr: got it [%x,%x)\n",
data->address, data->address + data->size);
gdb_puts(spare_buffer);
}
 
return (((unsigned char *) &data->data)
+ (addr - (unsigned char *) data->address));
}
}
}
}
}
 
/* not found, return error */
return (unsigned char *) -1;
}
 
/*============================================================*/
 
static long get_uchar ( const unsigned char * addr )
{
unsigned char *frame_addr;
 
if ( read_access_violation ( addr ) )
return ( -1 ); /* Access error */
 
if (curframe.valid) /* if debugging a trace frame? */
{
/* If the requested address was collected in the current frame,
* then fetch and return the data from the trace buffer.
*/
if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
return ( *frame_addr );
/* If the requested address is in the Code Section,
* let's be magnanimous and read it anyway (else we shall
* not be able to disassemble, find function prologues, etc.)
*/
else if (CS_CODE_START <= (unsigned long) addr &&
(unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
return (*addr);
else
return ( -1 ); /* "Access error" (the data was not collected) */
}
else
/* Not debugging a trace frame, read the data from live memory. */
return ( *addr ); /* Meaningful result >= 0 */
}
#endif
 
/*============================================================*/
 
static long set_uchar ( unsigned char * addr, unsigned char val )
{
long check_result = write_access_violation ( addr );
 
if ( check_result != 0L )
return ( check_result ); /* Access error */
 
return ( *addr = val ); /* Successful writing */
}
 
/*============================================================*/
 
/*
* Function read_access_violation() below returns TRUE if dereferencing
* its argument for reading would cause a bus error - and FALSE otherwise:
*/
 
static long read_access_violation ( const void * addr )
{
return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
( ( addr < NVD_START ) || ( addr >= NVD_END ) ) );
}
 
/*============================================================*/
 
/*
* Function write_access_violation() below returns zero if dereferencing
* its argument for writing is safe, -1 on a soft error (the argument
* falls into the write-protected area), -2 on a hard error (the argument
* points to a non-existent memory location). In other words, it returns
* FALSE when no bus error is expected - and an error code otherwise:
*/
 
static long write_access_violation ( const void * addr )
{
/*
* The boundaries of the write-protected area have to be received via
* an API provided in the Symmetrix core code. For now, these limits
* are hard-coded:
*/
 
if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
return ( -1 ); /* soft error */
 
if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
( ( addr < NVD_START ) || ( addr >= NVD_END ) ) )
return ( -2 ); /* hard error */
 
return ( 0 );
}
 
 
/* read_access_range is like read_access_violation,
but returns the number of bytes we can read w/o faulting.
that is, it checks an address range and tells us what portion
(if any) of the prefix is safe to read without a bus error */
static long
read_access_range(const void *addr, long count)
{
if ((addr >= SRAM_START) && (addr < SRAM_END))
{
if ((char *)addr + count < (char *)SRAM_END)
return (count);
else
return ((char *)SRAM_END - (char *)addr);
}
else if (((char *)addr >= (char *)NVD_START) &&
((char *)addr < (char *)NVD_END))
{
if ((char *)addr + count < (char *)NVD_END)
return (count);
else
return ((char *)NVD_END - (char *)addr);
}
else
return (0);
}
 
/* Convert the memory pointed to by mem into hex, placing result in buf.
Return SUCCESS or FAIL.
If MAY_FAULT is non-zero, then we should return FAIL in response to
a fault; if zero treat a fault like any other fault in the stub. */
 
static long
mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
{
long ndx;
long ndx2;
long ch;
long incr;
unsigned char *location;
DTC_RESPONSE status;
 
if (may_fault)
{
for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
{
status = find_memory(mem, count - ndx, &location, &incr);
 
if (status == OK_TARGET_RESPONSE)
{
if (incr > 0)
{
for (ndx2 = 0; ndx2 < incr; ndx2++)
{
ch = *location++;
*buf++ = hexchars[ch >> 4];
*buf++ = hexchars[ch & 0xf];
}
mem += incr;
}
else if (incr <= 0) /* should never happen */
{
*buf = 0;
return (0);
}
}
else if (status == NOT_FOUND_TARGET_RESPONSE)
{
*buf = 0;
return (ndx); /* return amount copied */
}
else
{
*buf = 0;
return (0); /* XXX: how do we tell the user the status? */
}
}
*buf = 0;
return (count);
}
else
{
for (ndx = 0; ndx < count; ndx++)
{
ch = *mem++;
*buf++ = hexchars[ch >> 4];
*buf++ = hexchars[ch & 0xf];
}
*buf = 0;
return (count); /* we copied everything */
}
}
 
static DTC_RESPONSE
find_memory(unsigned char *mem, long count,
unsigned char **location, long *incr)
{
DTC_RESPONSE retval;
long length;
 
/* figure out how much of the memory range we can read w/o faulting */
count = read_access_range(mem, count);
if (count == 0)
return (NOT_FOUND_TARGET_RESPONSE);
 
if (curframe.valid)
{
unsigned char *mem_block;
unsigned char *mem_addr;
unsigned long mem_size;
unsigned long mem_stamp;
 
retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
(unsigned long **)&mem_block,
(unsigned long **)&mem_addr,
&mem_size, &mem_stamp);
 
switch (retval)
{
case OK_TARGET_RESPONSE:
#if 0
printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
mem, mem_block, mem_addr, mem_size, mem_stamp);
#endif
*location = mem_block + (mem - mem_addr);
length = mem_size - (mem - mem_addr);
 
if (length < count)
*incr = length;
else
*incr = count;
 
break;
 
case NOT_FOUND_TARGET_RESPONSE:
case NEAR_FOUND_TARGET_RESPONSE:
#if 0
printp("NOT FOUND: mem %x, checking code region\n", mem);
#endif
/* check to see if it's in the code region */
if ((CS_CODE_START <= (long)mem) &&
((long)mem < CS_CODE_START + CS_CODE_SIZE))
{
/* some or all of the address range is in the code */
*location = mem;
if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
*incr = count; /* it's totally in the code */
else
/* how much is in the code? */
*incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
#if 0
printp("FOUND in code region: %x\n", mem);
#endif
retval = OK_TARGET_RESPONSE;
}
else
retval = NOT_FOUND_TARGET_RESPONSE;
 
break;
 
default:
#if 0
printp("BAD RETURN: %d\n", retval);
#endif
retval = NOT_FOUND_TARGET_RESPONSE;
break;
}
}
else
{
*location = mem;
*incr = count;
retval = OK_TARGET_RESPONSE;
}
 
return (retval);
}
 
/* Convert the hex array pointed to by buf into binary to be placed in mem.
Return SUCCESS or FAIL. */
 
static long
hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
{
long i, ch;
 
for ( i=0; i<count; i++ )
{
ch = hex( *buf++ ) << 4;
ch = ch + hex( *buf++ );
if ( may_fault )
{
ch = set_uchar( mem++, ch );
if ( ch < 0 ) /* negative return indicates error */
return FAIL;
}
else
*mem++ = ch;
}
return SUCCESS;
}
 
/**********************************************/
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
/* RETURN NUMBER OF CHARS PROCESSED */
/**********************************************/
 
static int
hexToInt( char **ptr, unsigned long *intValue )
{
long numChars = 0;
long hexValue;
 
*intValue = 0;
while ( **ptr )
{
hexValue = hex( **ptr );
if ( hexValue >=0 )
{
*intValue = (*intValue << 4) | hexValue;
numChars ++;
}
else
break;
(*ptr)++;
}
return numChars;
}
 
static volatile long gdb_handling_trap1;
static volatile long gdb_handling_sstrace;
static volatile long gdb_signo;
 
/*
Here is the "callable" stub entry point.
Call this function with a GDB request as an argument,
and it will service the request and return.
 
May be further broken up as we go along, with individual requests
broken out as separate functions.
*/
 
static char * handle_trace_query (char *);
static char * handle_trace_set (char *);
static int handle_format (char **request, CFD *format);
static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
static char * crc_query (char *);
static char * handle_test (char *);
 
void
handle_request( char *request )
{
#if 0
remote_debug = 2;
#endif
switch( *request++ )
{
case 'k': /* "kill" */
curframe.valid = FALSE;
putpacket ("");
break;
case 'D': /* "detach" */
curframe.valid = FALSE;
putpacket ("");
break;
default: /* Unknown code. Return an empty reply message. */
putpacket( "" ); /* return empty packet */
break;
 
case 'H': /* Set thread for subsequent operations.
Hct... c = 'c' for thread used in step and continue;
t... can be -1 for all threads.
c = 'g' for thread used in other operations.
If zero, pick a thread, any thread. */
 
putpacket( "OK" );
break;
 
case 'g': /* Read registers.
Each byte of register data is described by
two hex digits. registers are in the
internal order for GDB, and the bytes in a
register are in the same order the machine
uses. */
{
/* Return the values in (one of) the registers cache(s).
Several situations may pertain:
1) We're synchronous, in which case the "registers" array
should actually be current.
2) We're asynchronous, in which case the "registers" array
holds whatever was cached most recently.
3) We're looking at a trace frame that was collected earlier:
we will return those earlier registers.
*/
 
/* all registers default to zero */
memset (outbuffer, '0', NUMREGBYTES);
outbuffer[NUMREGBYTES] = '\0';
 
if (curframe.valid) /* debugging a trace frame */
mem2hex( (unsigned char*) curframe.traceregs,
outbuffer, NUMREGBYTES, 0 );
else
mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
 
putpacket( outbuffer );
}
break;
case 'G': /* Write registers.
Gxxxxxxxx Each byte of register data is described by
two hex digits. */
if (curframe.valid) /* debugging a trace frame */
putpacket ("E03"); /* can't write regs into a trace frame! */
else
{
/* Write the values into the local registers cache...
Note that no actual registers are being changed. */
 
hex2mem( request,
(unsigned char *) registers, NUMREGBYTES, 0 );
putpacket( "OK" );
}
break;
case 'P': /* Write (single) register.
Pnn=xxxxxxxx register nn gets value xxxxxxxx;
two hex digits for each byte in the register
(target byte order). */
 
if (curframe.valid)
putpacket ("E03"); /* can't write regs into a trace frame! */
else
{
unsigned long regno;
 
if ( hexToInt( &request, &regno ) && *(request++) == '=' )
{
if ( regno < NUMREGS )
{
hexToInt( &request,
(unsigned long *) &registers[REGISTER_BYTE(regno)]);
 
putpacket( "OK" );
}
else
putpacket( "E01" ); /* bad packet or regno */
}
}
break;
case 'm': /* Read memory.
mAAAAAAAA,LLLL AAAAAAAA is address, LLLL is length.
Reply can be fewer bytes than requested
if able to read only part of the data. */
{
unsigned long addr, len;
 
if ( hexToInt( &request, &addr ) &&
*(request++) == ',' &&
hexToInt( &request, &len ) )
{
/* better not overwrite outbuffer! */
if ( len > (BUFMAX / 2) - 5 )
len = (BUFMAX / 2) - 5;
if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */
putpacket( "E03" ); /* read fault (access denied) */
else
putpacket( outbuffer ); /* read succeeded */
}
else
putpacket( "E01" ); /* badly formed read request */
 
}
break;
case 'M': /* Write memory.
Maaaaaaaa,llll:xxxx aaaaaaaa is address, llll is length;
xxxx is data to write. */
 
{
unsigned long addr, len;
 
if (curframe.valid) /* can't write memory into a trace frame! */
putpacket ("E03"); /* "access denied" */
else /*** if ( write_access_enabled ) ***/
{
if ( hexToInt( &request, &addr ) &&
*(request++) == ',' &&
hexToInt( &request, &len ) &&
*(request++) == ':' )
{
if (len == 2 &&
addr >= CS_CODE_START &&
addr <= LAST_CS_WORD)
{
unsigned long val;
 
if ( !hexToInt( &request, &val ) ||
write_to_protected_mem( (void *)addr, val ) )
putpacket( "E03" ); /* write fault (access denied) */
else
putpacket( "OK" ); /* write succeeded */
}
else
{
if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
putpacket( "E03" ); /* write fault (access denied) */
else
putpacket( "OK" ); /* write succeeded */
}
}
else
putpacket( "E02" ); /* badly formed write request */
}
}
break;
case 'c': /* Continue.
cAAAAAAAA AAAAAAAA is address from which to resume.
If omitted, resume at current PC. */
 
{
unsigned long addr;
 
if (curframe.valid)
{
/* Don't continue if debugging a trace frame! */
gdb_puts ("Error: can't continue!\n");
putpacket ("S03");
}
else
{
gdb_signo = 3;
if (isxdigit(request[0]))
{
hexToInt(&request, &addr);
registers[REGISTER_BYTE(PC)] = addr;
}
 
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = '\0';
}
}
break;
case 's': /* Step.
sAAAAAAAA AAAAAAAA is address from which to begin stepping.
If omitted, begin stepping at current PC. */
{
unsigned long addr;
 
if (curframe.valid)
{
/* Don't step if debugging a trace frame! */
gdb_puts ("Error: can't step!\n");
putpacket ("S03");
}
else
{
gdb_signo = 3;
if (isxdigit(request[0]))
{
hexToInt(&request, &addr);
registers[REGISTER_BYTE(PC)] = addr;
}
 
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = 't';
}
}
break;
case 'C': /* Continue with signal.
Cxx;AAAAAAAA xx is signal number in hex;
AAAAAAAA is adddress from which to resume.
If ;AAAAAAAA omitted, continue from PC. */
 
{
unsigned long addr = 0;
 
if (!gdb_handling_trap1 || curframe.valid)
{
/* Don't continue if not currently in synchronous mode,
or if currently debugging a trace frame! */
gdb_puts( "Error: can't continue!\n" );
putpacket( "S03" ); /* "sigquit" (better idea?) */
}
else
{
gdb_signo = 3;
if ( isxdigit( *request ) )
{
hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
request += 2;
if ( *request == ';' && isxdigit( *++request ) )
{
hexToInt( &request, &addr );
registers[REGISTER_BYTE(PC)] = addr;
}
}
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = '\0';
}
}
break;
case 'S': /* Step with signal.
Sxx;AAAAAAAA xx is signal number in hex;
AAAAAAAA is adddress from which to begin stepping.
If ;AAAAAAAA omitted, begin stepping from PC. */
{
unsigned long addr = 0;
 
if (!gdb_handling_trap1 || curframe.valid)
{
/* Don't step if not currently in synchronous mode,
or if currently debugging a trace frame! */
gdb_puts( "Error: can't step!\n" );
putpacket( "S03" ); /* "sigquit" (better idea?) */
}
else
{
gdb_signo = 3;
if ( isxdigit( *request ) )
{
hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
request += 2;
if ( *request == ';' && isxdigit( *++request ) )
{
hexToInt( &request, &addr );
registers[REGISTER_BYTE(PC)] = addr;
}
}
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = 't';
}
}
break;
case '?': /* Query the latest reason for stopping.
Should be same reply as was last generated
for step or continue. */
 
if ( gdb_signo == 0 )
gdb_signo = 3; /* default to SIGQUIT */
outbuffer[ 0 ] = 'S';
outbuffer[ 1 ] = hexchars[ gdb_signo >> 4 ];
outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
outbuffer[ 3 ] = 0;
putpacket( outbuffer );
break;
 
case 'd': /* Toggle debug mode
I'm sure we can think of something interesting. */
 
remote_debug = !remote_debug;
putpacket( "" ); /* return empty packet */
break;
 
case 'q': /* general query */
switch (*request++)
{
default:
putpacket (""); /* nak a request which we don't handle */
break;
case 'T': /* trace query */
putpacket (handle_trace_query (request));
break;
case 'C': /* crc query (?) */
if (*request++ == 'R' &&
*request++ == 'C' &&
*request++ == ':')
putpacket (crc_query (request));
else
putpacket (""); /* unknown query */
break;
}
break;
 
case 'Q': /* general set */
switch (*request++)
{
default:
putpacket (""); /* nak a request which we don't handle */
break;
case 'T': /* trace */
putpacket (handle_trace_set (request));
break;
}
break;
 
case 'T':
/* call test function: TAAA,BBB,CCC
A, B, and C are arguments to pass to gdb_c_test. Reply is
"E01" (bad arguments) or "OK" (test function called). */
putpacket (handle_test (request));
break;
}
}
 
static TDP_SETUP_INFO tdp_temp;
static int trace_running;
 
/*
* Function msgcmp:
*
* If second argument (str) is matched in first argument,
* then advance first argument past end of str and return "SAME"
* else return "DIFFERENT" without changing first argument.
*
* Return: zero for DIFFERENT, non-zero for SUCCESS
*/
 
static int
msgcmp (char **msgp, char *str)
{
char *next;
 
if (msgp != 0 && str != 0) /* input validation */
if ((next = *msgp) != 0)
{
for (;
*next && *str && *next == *str;
next++, str++)
;
 
if (*str == 0) /* matched all of str in msg */
return (int) (*msgp = next); /* advance msg ptr past str */
}
return 0; /* failure */
}
 
static char *
handle_trace_query (char *request)
{
if (msgcmp (&request, "Status"))
{
if (adbg_check_if_active ())
{
gdb_puts ("Target trace is running.\n");
return "T1";
}
else
{
gdb_puts ("Target trace not running.\n");
trace_running = 0;
return "T0";
}
}
else /* unknown trace query */
{
return "";
}
}
 
static void
gdb_note (char *fmt, int arg1)
{
if (remote_debug > 1)
{
sprintp (spare_buffer, fmt, arg1);
gdb_puts (spare_buffer);
}
}
 
static int
error_ret (int ret, char *fmt, int arg1)
{
if (remote_debug > 0)
{
sprintp (spare_buffer, fmt, arg1);
gdb_puts (spare_buffer);
}
return ret;
}
 
static int
handle_format (char **request, COLLECTION_FORMAT_DEF *format)
{
MEMRANGE_DEF m;
DTC_RESPONSE ret;
int elinum;
unsigned long regnum;
long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
 
if (format->id == 0)
{
if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
return dtc_error_ret (-1, "get_unused_format_id", ret);
 
if (**request == 'R')
{
(*request)++;
hexToInt (request, &format->regs_mask);
}
gdb_note ("STUB: call define_format (id = %d, ", format->id);
gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
 
if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
{
sprintp (spare_buffer,
"'define_format': DTC error '%s' for format id %d.\n",
get_err_text (ret),
format->id);
gdb_puts (spare_buffer);
return -1;
}
}
 
while ((**request == 'M') || (**request == 'X'))
{
switch (**request)
{
case 'M': /* M<regnum>,<offset>,<size> */
(*request)++;
hexToInt(request, &regnum);
 
if (regnum == 0 || regnum == (unsigned long) -1)
m.typecode = -1;
else if ((elinum = index_to_elinum (regnum)) > 0)
m.typecode = elinum;
else
return error_ret (-1,
"Memrange register %d is not between 0 and 15\n",
regnum);
 
if (*(*request)++ != ',')
return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
hexToInt(request, &m.offset);
if (*(*request)++ != ',')
return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
hexToInt(request, &m.size);
 
gdb_note ("STUB: call add_format_mem_range (typecode = 0x%x, ",
m.typecode);
gdb_note ("offset = 0x%X, ", m.offset);
gdb_note ("size = %d);\n", m.size);
if ((ret = add_format_mem_ranges (format->id, &m)) !=
OK_TARGET_RESPONSE)
{
dtc_error_ret (-1, "add_format_mem_ranges", ret);
sprintp (spare_buffer,
"format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
format->id, m.typecode, m.offset, m.size);
gdb_puts (spare_buffer);
return -1;
}
break;
 
case 'X': /* X<length>,<bytecodes> */
{
unsigned long length;
 
(*request)++;
hexToInt(request, &length);
 
if ((length <= 0) || (length > MAX_BYTE_CODES))
return error_ret (-1,
"Bytecode expression length (%d) too large\n",
length);
 
if (*(*request)++ != ',')
return error_ret (-1,
"Malformed bytecode expr (comma#%d missing)\n",
1);
t_expr->next = NULL;
/* subtract one to account for expr[0] in header */
t_expr->size = sizeof(struct t_expr_tag) + length - 1;
t_expr->expr_size = length;
 
hex2mem(*request, &t_expr->expr[0], length, 0);
*request += 2 * length;
build_and_add_expression(format->id, t_expr);
}
break;
}
}
return 0;
}
 
static char *
handle_trace_set (char *request)
{
long n_frame;
unsigned long frameno, tdp, pc, start, stop;
DTC_RESPONSE ret = -1;
static COLLECTION_FORMAT_DEF tempfmt1;
static char enable;
static char retbuf[20];
 
if (msgcmp (&request, "init"))
{
gdb_note ("STUB: call clear_trace_state();\n", 0);
curframe.valid = 0; /* all old frames become invalid now */
if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
return "OK";
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"clear_trace_state",
ret);
}
}
else if (msgcmp (&request, "Start"))
{
trace_running = 1;
curframe.valid = 0; /* all old frames become invalid now */
gdb_note ("STUB: call start_trace_experiment();\n", 0);
adbg_save_trace_in_nvd ();
if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
return "OK";
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"start_trace_experiment",
ret);
}
}
else if (msgcmp (&request, "Stop"))
{
trace_running = 0;
if (adbg_check_if_active ())
{
gdb_note ("STUB: call end_trace_experiment();\n", 0);
if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
return "OK";
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"end_trace_experiment",
ret);
}
}
else return "OK";
}
/* "TDP:" (The 'T' was consumed in handle_request.) */
else if (msgcmp (&request, "DP:"))
{
/* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
{S{R[M,X]+}}<tp-format>
 
D -- disable tracepoint (illegal from EMC's point of view)
E -- enable tracepoint?
 
R -- regs format: R<regs-mask>
M -- memory format: M<regnum>,<offset>,<size>
X -- expr format: X<size>,<bytecodes>
S -- fencepost between trap formats and stepping formats.
*/
 
/* state variable, required for splitting TDP packets. */
static int doing_step_formats;
 
/*
* TDP: packets may now be split into multiple packets.
* If a TDP packet is to be continued in another packet, it
* must end in a "-" character. The subsequent continuation
* packet will then begin with a "-" character, between the
* token "TDP:" and the tdp_id field. The ID and address
* will be repeated in each sub-packet. The step_count,
* pass_count, and 'enabled' field must appear in the first
* packet. The boundary between sub-packets may not appear
* between the "S" that denotes the start of stepping "formats",
* and the regs_mask that follows it. The split may also not
* occur in the middle of either a memrange description or a
* bytecode string. -- MVS
*/
 
if (*request == '-') /* this is a continuation of a
trace definition in progress */
{
unsigned long temp_id, temp_addr;
 
request++;
if (!(hexToInt (&request, &temp_id) &&
*request++ == ':'))
return "E11"; /* badly formed packet, field 1 */
 
if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
*request++ == ':'))
return "E12"; /* badly formed packet, field 2 */
 
if (temp_id != tdp_temp.id)
return "E11"; /* something wrong: field 1 doesn't match */
if (temp_addr != (unsigned long) tdp_temp.addr)
return "E12"; /* something wrong: field 2 doesn't match */
}
else /* This is a new TDP definition */
{
memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
doing_step_formats = FALSE;
 
if (!(hexToInt (&request, &tdp_temp.id) &&
*request++ == ':'))
return "E11"; /* badly formed packet, field 1 */
 
if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
*request++ == ':'))
return "E12"; /* badly formed packet, field 2 */
 
if (!(((enable = *request++) == 'D' || enable == 'E') &&
*request++ == ':'))
return "E13"; /* badly formed packet, field 3 */
#if 0
if (enable == 'D')
{
gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
return "E20";
}
#endif
if (!(hexToInt (&request, &tdp_temp.stepcount) &&
*request++ == ':'))
return "E14"; /* badly formed packet, field 4 */
 
if (!hexToInt (&request, &tdp_temp.pass_limit))
return "E15"; /* badly formed packet, field 5 */
 
}
 
/* Typically, the first group of collection descriptors
refers to the trap collection. There is an "S" token
to act as a fencepost between collection descriptors for
the trap, and those for the single-stepping.
 
However, when the packet is split up into several packets,
this "S" token may already have been seen in a previous
sub-packet; so we have to remember it in a state variable. */
 
if (*request == 'R' || *request == 'M' || *request == 'X')
{
if (handle_format (&request, &tempfmt1))
return "E16";
if (doing_step_formats)
tdp_temp.tp_format_p = tempfmt1.id;
else
tdp_temp.tdp_format_p = tempfmt1.id;
}
 
/* When we see the "S" token, we remember it in a state variable
(in case the packet is split up and continued in another message),
and discard all current state from the collection "format". */
if (*request == 'S')
{
doing_step_formats = TRUE;
/* discard prev format and start a new one */
memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
request++;
 
/* Having seen the "S" fencepost, it is now possible that
we will see some more collection descriptors pertaining
to the stepping collection. */
if (*request == 'R' || *request == 'M' || *request == 'X')
{
if (handle_format (&request, &tempfmt1))
return "E17";
/* new format ID is tp_format */
tdp_temp.tp_format_p = tempfmt1.id;
}
}
 
if (*request == '-') /* this TDP definition will be continued. */
sprintp (retbuf, "OK");
else if (enable == 'E') /* end of TDP definition: pass to ADBG (if enabled!) */
{
gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
gdb_note ("passc %d, ", tdp_temp.pass_limit);
gdb_note ("stepc %d, ", tdp_temp.stepcount);
gdb_note ("TDP fmt #%d, ", tdp_temp.tdp_format_p);
gdb_note ("TP fmt #%d);\n", tdp_temp.tp_format_p);
ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
 
if (ret == OK_TARGET_RESPONSE)
{
sprintp (retbuf, "OK");
}
else
{
sprintp (spare_buffer,
"'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
get_err_text (ret),
tdp_temp.id);
gdb_puts (spare_buffer);
sprintp (retbuf, "E2%x", ret);
}
/* Redundant, but let's try to make sure this state gets discarded. */
{
memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
}
}
else /* ADBG_DTC does not support disabled tracepoints -- ignore it. */
gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
 
return retbuf;
}
else if (msgcmp (&request, "Frame:"))
{
ret = OK_TARGET_RESPONSE;
 
if (msgcmp (&request, "pc:"))
{
if (!hexToInt (&request, &pc))
return "E10"; /* badly formed packet */
n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
gdb_note ("pc 0x%X);\n", pc);
ret = fetch_trace_frame_with_pc (&n_frame,
(void *) pc,
&curframe.format,
&curframe.frame_data);
}
else if (msgcmp (&request, "tdp:"))
{
if (!hexToInt (&request, &tdp))
return "E10"; /* badly formed packet */
n_frame = curframe.valid ? curframe.frame_id + 1: 0;
gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
gdb_note ("tdp 0x%X);\n", tdp);
ret = fetch_trace_frame_with_tdp (&n_frame,
tdp,
&curframe.format,
&curframe.frame_data);
}
else if (msgcmp (&request, "range:"))
{
if (!(hexToInt (&request, &start) &&
*request++ == ':'))
return "E11"; /* badly formed packet, field 1 */
else if (!hexToInt (&request, &stop))
return "E12"; /* badly formed packet, field 2 */
n_frame = curframe.valid ? curframe.frame_id + 1: 0;
gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
gdb_note ("start 0x%X, ", start);
gdb_note ("stop 0x%X);\n", stop);
ret = fetch_trace_frame_with_pc_in_range (&n_frame,
(void *) start,
(void *) stop,
&curframe.format,
&curframe.frame_data);
}
else if (msgcmp (&request, "outside:"))
{
if (!(hexToInt (&request, &start) &&
*request++ == ':'))
return "E11"; /* badly formed packet, field 1 */
else if (!hexToInt (&request, &stop))
return "E12"; /* badly formed packet, field 2 */
n_frame = curframe.valid ? curframe.frame_id + 1: 0;
gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
gdb_note ("start 0x%X, ", start);
gdb_note ("stop 0x%X);\n", stop);
ret = fetch_trace_frame_with_pc_outside (&n_frame,
(void *) start,
(void *) stop,
&curframe.format,
&curframe.frame_data);
}
else /* simple TFind by frame number: */
{
if (!hexToInt (&request, &frameno))
return "E10"; /* badly formed packet */
if (frameno != (unsigned long) -1)
{
gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
ret = fetch_trace_frame (n_frame = frameno,
&curframe.format,
&curframe.frame_data);
#if 0
printp("STUB: fetch_trace_frame: return %d\n", ret);
#endif
}
else /* discard any trace frame, debug "the real world" */
{
if (curframe.valid)
gdb_note ("STUB: discard current trace frame #%d.\n",
curframe.frame_id);
curframe.valid = 0;
return "OK";
}
}
if (ret == OK_TARGET_RESPONSE) /* fetch_trace_frame succeeded */
{ /* setup for debugging the trace frame */
curframe.valid = 1;
curframe.frame_id = n_frame;
curframe.tdp_id = curframe.frame_data->id;
 
memset ((char *) &curframe.traceregs, 0,
sizeof (curframe.traceregs));
curframe.traceregs[PC] = (unsigned long)
curframe.frame_data->program_counter;
 
if (curframe.format)
{
unsigned long regs_mask = curframe.format->regs_mask;
unsigned long *regs, *stack, *mem;
unsigned long regno, index = 0;
CFD *dummy;
 
if ((ret = get_addr_to_frame_regs_stack_mem
(curframe.frame_data, &dummy, &regs, &stack, &mem))
!= OK_TARGET_RESPONSE)
{
curframe.valid = 0;
sprintp (retbuf, "E2%x", ret);
return (char *)
dtc_error_ret ((int) &retbuf,
"get_addr_to_frame_regs_stack_mem",
ret);
}
 
if (remote_debug > 1)
{ /* echo what we've found to gdb console */
sprintp (spare_buffer,
"STUB: Found frame %d, TDP %d, format %d (%s):\n",
curframe.frame_id,
curframe.tdp_id & 0x7fffffff,
curframe.format->id,
curframe.tdp_id & 0x80000000 ?
"trap frame" : "stepping frame");
gdb_puts (spare_buffer);
}
/* copy trace frame regs into stub's data format */
for (regno = 0, index = 0;
regno < 16;
regno++, regs_mask >>= 1)
if (regs_mask & 1) /* got a collected register */
{
curframe.traceregs[regno] = regs[index++];
if (remote_debug > 1)
{
sprintp (spare_buffer,
" Collected 0x%08x for register %d.\n",
curframe.traceregs[regno], regno);
gdb_puts (spare_buffer);
}
}
if (remote_debug > 1)
{
long midx, ridx, len;
MEMRANGE_DEF *mrange;
unsigned char *data, *base;
 
if (curframe.format->stack_size > 0)
{
len = curframe.format->stack_size;
sprintp (spare_buffer,
" Collected %d bytes of stack at 0x%x:\n",
len, curframe.traceregs[A7]);
gdb_puts (spare_buffer);
 
/* print stack data, but stay under msg len */
if (len >= (NUMREGBYTES/2 - 2))
len = (NUMREGBYTES/2 - 3);
mem2hex ((unsigned char *) stack,
spare_buffer, len, 0);
spare_buffer [len * 2] = '\n';
spare_buffer [len * 2 + 1] = '\0'; /* EOS */
gdb_puts (spare_buffer);
}
else
gdb_puts ("Stack not collected\n");
 
for (midx = 0;
get_addr_to_a_mem_range (curframe.frame_data,
midx,
&mrange,
(void **) &data)
== OK_TARGET_RESPONSE;
midx++)
{
if ((mrange->typecode == 0) ||
(mrange->typecode == (unsigned long) -1))
{
sprintp (spare_buffer,
" Collected %d bytes at MEM: 0x%x:\n",
mrange->size, mrange->offset);
base = (unsigned char *) mrange->offset;
}
else
{
if ((ridx = elinum_to_index (mrange->typecode)) > 0)
base = (unsigned char *) curframe.traceregs[ridx]
+ (long) mrange->offset;
else
{
sprintp (spare_buffer,
"STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
midx,
mrange->typecode,
mrange->offset,
mrange->size);
gdb_puts (spare_buffer);
continue;
}
sprintp (spare_buffer,
" Collected %d bytes at 0x%x (REG %X + %d):\n",
mrange->size,
base,
mrange->typecode,
mrange->offset);
}
gdb_puts (spare_buffer);
len = mrange->size;
if (len >= (NUMREGBYTES/2 - 2))
len = (NUMREGBYTES/2 - 3);
mem2hex (data, spare_buffer, len, 0);
spare_buffer [len * 2] = '\n';
spare_buffer [len * 2 + 1] = '\0'; /* EOS */
gdb_puts (spare_buffer);
}
}
}
sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
return retbuf;
}
else if (ret == NOT_FOUND_TARGET_RESPONSE)
{
/* Here's a question: if the fetch_trace_frame call failed
(which probably means a bad "TFIND" command from GDB),
should we remain focused on the previous frame (if any),
or should we revert to "no current frame"?
*/
return "F-1";
}
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"fetch_trace_frame[...]",
ret);
}
}
else /* unknown trace command */
{
return "";
}
}
 
/* Table used by the crc32 function to calcuate the checksum. */
static unsigned long crc32_table[256];
 
static int crc_mem_err;
 
static unsigned long
crc32 (buf, len, crc)
unsigned char *buf;
int len;
unsigned long crc;
{
crc_mem_err = FALSE;
 
if (! crc32_table[1])
{
/* Initialize the CRC table and the decoding table. */
int i, j;
unsigned int c;
 
for (i = 0; i < 256; i++)
{
for (c = i << 24, j = 8; j > 0; --j)
c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
crc32_table[i] = c;
}
}
 
while (len--)
{
if (read_access_violation (buf))
{
crc_mem_err = TRUE;
return -1;
}
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
}
return crc;
}
 
static char *
crc_query (cmd)
char *cmd;
{
unsigned long startmem, len, crc;
static char buf[32];
 
if (hexToInt (&cmd, &startmem) &&
*cmd++ == ',' &&
hexToInt (&cmd, &len))
{
crc = crc32 ((unsigned char *) startmem, len, 0xffffffff);
if (!crc_mem_err)
{
sprintp (buf, "C%08x", crc);
return buf;
}
/* else error, fall thru */
}
sprintp (buf, "E01");
return buf;
}
 
 
static char *
handle_test (request)
char *request;
{
ULONG args[7];
int i;
 
/* Parse the arguments, a comma-separated list of hex numbers, into
ARGS. Parse at most six arguments. */
i = 1;
if (*request != '\0')
while (i < 7)
{
if (! hexToInt (&request, &args[i++]))
return "E01";
if (*request == '\0')
break;
if (*request++ != ',')
return "E01";
}
 
/* Fill the rest of the args array with zeros. This is what the
INLINES command processor does with omitted arguments. */
for (; i < 7; i++)
args[i] = 0;
 
gdb_c_test (args);
 
return "OK";
}
 
 
/* GDB_TRAP_1_HANDLER
 
By the time this is called, the registers have been saved in "registers",
and the interrupt priority has been set to permit serial UART interrupts.
 
However, since no gdb request has yet been received, and there is no
equivalent of getpacket for us to wait on, we can't sit here waiting
for packets and processing them.
 
In fact, the ONLY thing for us to do here is sit and wait.
As gdb sends packet requests, they will handle themselves at the
interrupt level. When gdb decides we can continue, it will reset
the global variable "gdb_handling_trap1", and we will return
(whereupon registers will be restored etc.) */
 
void gdb_trap_1_handler( void )
{
gdb_handling_trap1 = TRUE;
sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */
gdb_signo = 5;
putpacket( "S05" );
while ( gdb_handling_trap1 )
;
return;
}
 
void gdb_trace_handler( void )
{
sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */
gdb_handling_trap1 = TRUE;
gdb_handling_sstrace = TRUE;
gdb_signo = 5;
putpacket( "S05" );
while ( gdb_handling_trap1 )
;
return;
}
gdb_c_test.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: actions.c =================================================================== --- actions.c (nonexistent) +++ actions.c (revision 840) @@ -0,0 +1,134 @@ +/* + * Test program for trace action commands + */ + +static char gdb_char_test; +static short gdb_short_test; +static long gdb_long_test; +static char gdb_arr_test[25]; +static struct GDB_STRUCT_TEST +{ + char c; + short s; + long l; + int bfield : 11; /* collect bitfield */ + char arr[25]; + struct GDB_STRUCT_TEST *next; +} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test; + +static union GDB_UNION_TEST +{ + char c; + short s; + long l; + int bfield : 11; /* collect bitfield */ + char arr[4]; + union GDB_UNION_TEST *next; +} gdb_union1_test; + +void gdb_recursion_test (int, int, int, int, int, int, int); + +void gdb_recursion_test (int depth, + int q1, + int q2, + int q3, + int q4, + int q5, + int q6) +{ /* gdb_recursion_test line 0 */ + int q = q1; /* gdbtestline 1 */ + + q1 = q2; /* gdbtestline 2 */ + q2 = q3; /* gdbtestline 3 */ + q3 = q4; /* gdbtestline 4 */ + q4 = q5; /* gdbtestline 5 */ + q5 = q6; /* gdbtestline 6 */ + q6 = q; /* gdbtestline 7 */ + if (depth--) /* gdbtestline 8 */ + gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */ +} + + +unsigned long gdb_c_test( unsigned long *parm ) + +{ + char *p = "gdb_c_test"; + char *ridiculously_long_variable_name_with_equally_long_string_assignment; + register long local_reg = 7; + static unsigned long local_static, local_static_sizeof; + long local_long; + unsigned long *stack_ptr; + unsigned long end_of_stack; + + ridiculously_long_variable_name_with_equally_long_string_assignment = + "ridiculously long variable name with equally long string assignment"; + local_static = 9; + local_static_sizeof = sizeof (struct GDB_STRUCT_TEST); + local_long = local_reg + 1; + stack_ptr = (unsigned long *) &local_long; + end_of_stack = + (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1; + + gdb_char_test = gdb_struct1_test.c = (char) ((long) parm[1] & 0xff); + gdb_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff); + gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff); + gdb_union1_test.l = (long) parm[4]; + gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff); + gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff); + gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff); + gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff); + gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff); + gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff); + gdb_struct1_test.bfield = 144; + gdb_struct1_test.next = &gdb_struct2_test; + gdb_structp_test = &gdb_struct1_test; + gdb_structpp_test = &gdb_structp_test; + + gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3], + (long) parm[4], (long) parm[5], (long) parm[6]); + + gdb_char_test = gdb_short_test = gdb_long_test = 0; + gdb_structp_test = (void *) 0; + gdb_structpp_test = (void *) 0; + memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test)); + memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test)); + local_static_sizeof = 0; + local_static = 0; + return ( (unsigned long) 0 ); +} + +static void gdb_asm_test (void) +{ +} + +static void begin () /* called before anything else */ +{ +} + +static void end () /* called after everything else */ +{ +} + +int +main (argc, argv, envp) + int argc; + char *argv[], **envp; +{ + int i; + unsigned long myparms[10]; + +#ifdef usestubs + set_debug_traps (); + breakpoint (); +#endif + + begin (); + for (i = 0; i < sizeof (myparms) / sizeof (myparms[0]); i++) + myparms[i] = i; + + gdb_c_test (&myparms[0]); + + end (); + return 0; +} +
actions.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: limits.c =================================================================== --- limits.c (nonexistent) +++ limits.c (revision 840) @@ -0,0 +1,51 @@ +/* + * Test program for tracing internal limits (number of tracepoints etc.) + */ + +int n = 6; + +int arr[64]; + +static void foo(int x) +{ +} + +static void bar(int y) +{ +} + +static void baz(int z) +{ +} + +static void begin () /* called before anything else */ +{ +} + +static void end () /* called after everything else */ +{ +} + +int +main (argc, argv, envp) + int argc; + char *argv[], **envp; +{ + int i; + +#ifdef usestubs + set_debug_traps (); + breakpoint (); +#endif + + begin (); + for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) + arr[i] = i + 1; + + foo (1); + bar (2); + baz (3); + end (); + return 0; +} +
limits.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: save-trace.exp =================================================================== --- save-trace.exp (nonexistent) +++ save-trace.exp (revision 840) @@ -0,0 +1,172 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested save-trace.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} + +set testline1 [expr $baseline + 4] +set testline2 [expr $baseline + 5] +set testline3 [expr $baseline + 6] +set testline4 [expr $baseline + 7] +set testline5 [expr $baseline + 8] +set testline6 [expr $baseline + 9] + +# +# test save-trace command +# + +# setup a set of tracepoints to save + +gdb_delete_tracepoints + +foreach x { 1 2 3 4 5 6 } { + set testline [expr \$testline$x]; + set trcpt [gdb_gettpnum $testline]; + set trcpt$x $trcpt; + gdb_test "passcount $x" \ + "Setting tracepoint $trcpt.* to $x" \ + "10.x: set passcount for tracepoint $trcpt" + + gdb_trace_setactions "10.x: set actions for tracepoint $x" \ + "" \ + "collect q$x" "^$" \ + "while-stepping $x" "^$" \ + "collect q$x" "^$" \ + "end" "^$" +} + + +proc gdb_verify_tracepoints { testname } { + global gdb_prompt; + + set ws "\[\t \]+" + set nl "\[\r\n\]+" + set ourstate 1; + set result "pass"; + send_gdb "info tracepoints\n"; + gdb_expect 10 { + -re "y\[\t \]+0x\[0-9a-fA-F\]+\[\t \]+(\[0-9\]+)\[\t \]+(\[0-9\]+)\[\t \]+in gdb_recursion_test\[^\r\n\]+" { + if { $expect_out(1,string) != $expect_out(2,string) } { + #set result "fail"; + } + if { $expect_out(1,string) != $ourstate } { + set result "fail"; + } + incr ourstate; + exp_continue; + } + -re "$gdb_prompt $" { + if { $ourstate >= 6 } { + set result "pass"; + } else { + set result "fail"; + } + } + default { + set result "fail"; + } + } + $result $testname; + return $result; +} + +gdb_verify_tracepoints "10.x: verify trace setup"; + +# 10.1 Save current tracepoint definitions to a file + +remote_file host delete savetrace.tr +gdb_test "save-tracepoints savetrace.tr" \ + "Tracepoints saved to file 'savetrace.tr'." \ + "10.1: save tracepoint definitions" + +# 10.2 Read back tracepoint definitions + +gdb_delete_tracepoints +gdb_test "info tracepoints" "No tracepoints." "10.2: delete tracepoints" +gdb_test "source savetrace.tr" \ + "Tracepoint \[0-9\]+ at .*" \ + "10.2: read back saved tracepoints" +gdb_verify_tracepoints "10.2: verify recovered tracepoints"; +remote_file host delete savetrace.tr + +# 10.3 repeat with a path to the file + +set escapedfilename [string_to_regexp $objdir/savetrace.tr] +remote_file host delete $objdir/savetrace.tr +gdb_test "save-tracepoints $objdir/savetrace.tr" \ + "Tracepoints saved to file '${escapedfilename}'." \ + "10.3: save tracepoint definitions, full path" + +gdb_delete_tracepoints +gdb_test "info tracepoints" "No tracepoints." "10.3: delete tracepoints" +gdb_test "source $objdir/savetrace.tr" \ + "Tracepoint \[0-9\]+ at .*" \ + "10.4: read saved tracepoints, full path" +gdb_verify_tracepoints "10.3: verify recovered tracepoints, full path"; +remote_file host delete $objdir/savetrace.tr + +# 10.5 invalid filename +# [deferred -- not sure what a good invalid filename would be] + +# 10.6 save-trace (file already exists) +# [expect it to clobber the old one] + +# 10.7 help save-tracepoints + +gdb_test "help save-tracepoints" \ + "Save current tracepoint definitions as a script.*" \ + "10.7: help save-tracepoints" Index: collection.exp =================================================================== --- collection.exp (nonexistent) +++ collection.exp (revision 840) @@ -0,0 +1,634 @@ +# Copyright 1998, 2005, 2007, 2008 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +if [istarget "m68k-*-elf"] then { + pass "Test not supported on this target" + return; +} + +load_lib "trace-support.exp" + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +set testfile "collection" +set srcfile ${testfile}.c +set binfile $objdir/$subdir/$testfile + +if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested collection.exp + return -1 +} + +# Tests: +# 1) $args +# 2) function args by name +# 3) $locs +# 4) function locals by name +# 5) $regs +# 6) registers by name ($sp, $fp?) +# 7) globals by name +# 8) expressions (lots of different kinds: local and global) + +set ws "\[\r\n\t \]+" +set cr "\[\r\n\]+" + +# +# Utility procs +# + +proc test_register { reg test_id } { + global cr + global gdb_prompt + + send_gdb "print $reg\n" + gdb_expect { + -re "\\$\[0-9\]+ = \[x0\]+$cr$gdb_prompt " { + fail "collect $test_id: collected $reg (zero)" + } + -re "\\$\[0-9\]+ = \[x0-9a-fA-F\]+$cr$gdb_prompt " { + pass "collect $test_id: collected $reg" + } + -re "\[Ee\]rror.*$gdb_prompt " { + fail "collect $test_id: collected $reg (error)" + } + timeout { + fail "collect $test_id: collected $reg (timeout)" + } + } +} + +proc run_trace_experiment { msg test_func } { + global gdb_prompt + gdb_run_cmd + gdb_expect { + -re ".*Breakpoint \[0-9\]+, begin .*$gdb_prompt $" { + } + -re ".*$gdb_prompt $" { + fail "collect $msg: advance to go" + } + timeout { + fail "collect $msg: advance to go (timeout)" + } + } + gdb_test "tstart" \ + "\[\r\n\]+" \ + "collect $msg: start trace experiment" + gdb_test "continue" \ + "Continuing.*Breakpoint \[0-9\]+, end.*" \ + "collect $msg: run trace experiment" + gdb_test "tstop" \ + "\[\r\n\]+" \ + "collect $msg: stop trace experiment" + gdb_test "tfind start" \ + "#0 $test_func .*" \ + "collect $msg: tfind test frame" +} + + +# +# Test procs +# + +proc gdb_collect_args_test { myargs msg } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + gdb_test "trace args_test_func" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect $msg: set tracepoint" + gdb_trace_setactions "collect $msg: define actions" \ + "" \ + "collect $myargs" "^$" + + # Begin the test. + run_trace_experiment $msg args_test_func + + gdb_test "print argc" \ + "\\$\[0-9\]+ = 1 '.001'$cr" \ + "collect $msg: collected arg char" + gdb_test "print argi" \ + "\\$\[0-9\]+ = 2$cr" \ + "collect $msg: collected arg int" + gdb_test "print argf" \ + "\\$\[0-9\]+ = 3.\[23\]\[0-9\]*$cr" \ + "collect $msg: collected arg float" + gdb_test "print argd" \ + "\\$\[0-9\]+ = 4.\[34\]\[0-9\]*$cr" \ + "collect $msg: collected arg double" + + # struct arg as one of several args (near end of list) + gdb_test "print argstruct.memberc" \ + "\\$\[0-9\]+ = 101 'e'$cr" \ + "collect $msg: collected arg struct member char" + gdb_test "print argstruct.memberi" \ + "\\$\[0-9\]+ = 102$cr" \ + "collect $msg: collected arg struct member int" + gdb_test "print argstruct.memberf" \ + "\\$\[0-9\]+ = 103.\[23\]\[0-9\]*$cr" \ + "collect $msg: collected arg struct member float" + gdb_test "print argstruct.memberd" \ + "\\$\[0-9\]+ = 104.\[34\]\[0-9\]*$cr" \ + "collect $msg: collected arg struct member double" + + # array arg as one of several args (near end of list) + gdb_test "print argarray\[0\]" \ + "\\$\[0-9\]+ = 111$cr" \ + "collect $msg: collected argarray #0" + gdb_test "print argarray\[1\]" \ + "\\$\[0-9\]+ = 112$cr" \ + "collect $msg: collected argarray #1" + gdb_test "print argarray\[2\]" \ + "\\$\[0-9\]+ = 113$cr" \ + "collect $msg: collected argarray #2" + gdb_test "print argarray\[3\]" \ + "\\$\[0-9\]+ = 114$cr" \ + "collect $msg: collected argarray #3" + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect $msg: cease trace debugging" +} + +proc gdb_collect_argstruct_test { myargs msg } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + gdb_test "trace argstruct_test_func" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect $msg: set tracepoint" + gdb_trace_setactions "collect $msg: define actions" \ + "" \ + "collect $myargs" "^$" + + # Begin the test. + run_trace_experiment $msg argstruct_test_func + + # struct argument as only argument + gdb_test "print argstruct.memberc" \ + "\\$\[0-9\]+ = 101 'e'$cr" \ + "collect $msg: collected arg struct member char" + gdb_test "print argstruct.memberi" \ + "\\$\[0-9\]+ = 102$cr" \ + "collect $msg: collected arg struct member int" + gdb_test "print argstruct.memberf" \ + "\\$\[0-9\]+ = 103.\[23\]\[0-9\]*$cr" \ + "collect $msg: collected arg struct member float" + gdb_test "print argstruct.memberd" \ + "\\$\[0-9\]+ = 104.\[34\]\[0-9\]*$cr" \ + "collect $msg: collected arg struct member double" + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect $msg: cease trace debugging" +} + + +proc gdb_collect_argarray_test { myargs msg } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + gdb_test "trace argarray_test_func" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect $msg: set tracepoint" + gdb_trace_setactions "collect $msg: define actions" \ + "" \ + "collect $myargs" "^$" + + # Begin the test. + run_trace_experiment $msg argarray_test_func + + # array arg as only argument + gdb_test "print argarray\[0\]" \ + "\\$\[0-9\]+ = 111$cr" \ + "collect $msg: collected argarray #0" + gdb_test "print argarray\[1\]" \ + "\\$\[0-9\]+ = 112$cr" \ + "collect $msg: collected argarray #1" + gdb_test "print argarray\[2\]" \ + "\\$\[0-9\]+ = 113$cr" \ + "collect $msg: collected argarray #2" + gdb_test "print argarray\[3\]" \ + "\\$\[0-9\]+ = 114$cr" \ + "collect $msg: collected argarray #3" + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect $msg: cease trace debugging" +} + + +proc gdb_collect_locals_test { func mylocs msg } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # Find the comment-identified line for setting this tracepoint. + set testline 0 + send_gdb "list $func, +30\n" + gdb_expect { + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" { + set testline $expect_out(1,string) + pass "collect $msg: find tracepoint line" + } + -re ".*$gdb_prompt " { + fail "collect $msg: find tracepoint line (skipping locals test)" + return + } + timeout { + fail "collect $msg: find tracepoint line (skipping locals test)" + return + } + } + + gdb_test "trace $testline" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect $msg: set tracepoint" + gdb_trace_setactions "collect $msg: define actions" \ + "" \ + "collect $mylocs" "^$" + + # Begin the test. + run_trace_experiment $msg $func + + gdb_test "print locc" \ + "\\$\[0-9\]+ = 11 '.\[a-z0-7\]+'$cr" \ + "collect $msg: collected local char" + gdb_test "print loci" \ + "\\$\[0-9\]+ = 12$cr" \ + "collect $msg: collected local int" + gdb_test "print locf" \ + "\\$\[0-9\]+ = 13.\[23\]\[0-9\]*$cr" \ + "collect $msg: collected local float" + gdb_test "print locd" \ + "\\$\[0-9\]+ = 14.\[34\]\[0-9\]*$cr" \ + "collect $msg: collected local double" + + gdb_test "print locst.memberc" \ + "\\$\[0-9\]+ = 15 '.017'$cr" \ + "collect $msg: collected local member char" + gdb_test "print locst.memberi" \ + "\\$\[0-9\]+ = 16$cr" \ + "collect $msg: collected local member int" + gdb_test "print locst.memberf" \ + "\\$\[0-9\]+ = 17.\[67\]\[0-9\]*$cr" \ + "collect $msg: collected local member float" + gdb_test "print locst.memberd" \ + "\\$\[0-9\]+ = 18.\[78\]\[0-9\]*$cr" \ + "collect $msg: collected local member double" + + gdb_test "print locar\[0\]" \ + "\\$\[0-9\]+ = 121$cr" \ + "collect $msg: collected locarray #0" + gdb_test "print locar\[1\]" \ + "\\$\[0-9\]+ = 122$cr" \ + "collect $msg: collected locarray #1" + gdb_test "print locar\[2\]" \ + "\\$\[0-9\]+ = 123$cr" \ + "collect $msg: collected locarray #2" + gdb_test "print locar\[3\]" \ + "\\$\[0-9\]+ = 124$cr" \ + "collect $msg: collected locarray #3" + + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect $msg: cease trace debugging" +} + +proc gdb_collect_registers_test { myregs } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # We'll simply re-use the args_test_function for this test + gdb_test "trace args_test_func" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect $myregs: set tracepoint" + gdb_trace_setactions "collect $myregs: define actions" \ + "" \ + "collect $myregs" "^$" + + # Begin the test. + run_trace_experiment $myregs args_test_func + + test_register "\$fp" $myregs + test_register "\$sp" $myregs + test_register "\$pc" $myregs + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect $myregs: cease trace debugging" +} + +proc gdb_collect_expression_test { func expr val msg } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # Find the comment-identified line for setting this tracepoint. + set testline 0 + send_gdb "list $func, +30\n" + gdb_expect { + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" { + set testline $expect_out(1,string) + pass "collect $msg: find tracepoint line" + } + -re ".*$gdb_prompt " { + fail "collect $msg: find tracepoint line (skipping locals test)" + return + } + timeout { + fail "collect $msg: find tracepoint line (skipping locals test)" + return + } + } + + gdb_test "trace $testline" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect $msg: set tracepoint" + gdb_trace_setactions "collect $msg: define actions" \ + "" \ + "collect $expr" "^$" + + # Begin the test. + run_trace_experiment $msg $func + + gdb_test "print $expr" \ + "\\$\[0-9\]+ = $val$cr" \ + "collect $msg: got expected value '$val'" + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect $msg: cease trace debugging" +} + +proc gdb_collect_globals_test { } { + global cr + global gdb_prompt + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # Find the comment-identified line for setting this tracepoint. + set testline 0 + send_gdb "list globals_test_func, +30\n" + gdb_expect { + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" { + set testline $expect_out(1,string) + pass "collect globals: find tracepoint line" + } + -re ".*$gdb_prompt " { + fail "collect globals: find tracepoint line (skipping global test)" + return + } + timeout { + fail "collect globals: find tracepoint line (skipping global test)" + return + } + } + + gdb_test "trace $testline" \ + "Tracepoint \[0-9\]+ at .*" \ + "collect globals: set tracepoint" + gdb_trace_setactions "collect globals: define actions" \ + "" \ + "collect globalc, globali, globalf, globald" "^$" \ + "collect globalstruct, globalp, globalarr" "^$" + + # Begin the test. + run_trace_experiment "globals" globals_test_func + + gdb_test "print globalc" \ + "\\$\[0-9\]+ = 71 'G'$cr" \ + "collect globals: collected global char" + gdb_test "print globali" \ + "\\$\[0-9\]+ = 72$cr" \ + "collect globals: collected global int" + gdb_test "print globalf" \ + "\\$\[0-9\]+ = 73.\[23\]\[0-9\]*$cr" \ + "collect globals: collected global float" + gdb_test "print globald" \ + "\\$\[0-9\]+ = 74.\[34\]\[0-9\]*$cr" \ + "collect globals: collected global double" + + gdb_test "print globalstruct.memberc" \ + "\\$\[0-9\]+ = 81 'Q'$cr" \ + "collect globals: collected struct char member" + gdb_test "print globalstruct.memberi" \ + "\\$\[0-9\]+ = 82$cr" \ + "collect globals: collected struct member int" + gdb_test "print globalstruct.memberf" \ + "\\$\[0-9\]+ = 83.\[23\]\[0-9\]*$cr" \ + "collect globals: collected struct member float" + gdb_test "print globalstruct.memberd" \ + "\\$\[0-9\]+ = 84.\[34\]\[0-9\]*$cr" \ + "collect globals: collected struct member double" + + gdb_test "print globalp == &globalstruct" \ + "\\$\[0-9\]+ = 1$cr" \ + "collect globals: collected global pointer" + + gdb_test "print globalarr\[1\]" \ + "\\$\[0-9\]+ = 1$cr" \ + "collect globals: collected global array element #1" + gdb_test "print globalarr\[2\]" \ + "\\$\[0-9\]+ = 2$cr" \ + "collect globals: collected global array element #2" + gdb_test "print globalarr\[3\]" \ + "\\$\[0-9\]+ = 3$cr" \ + "collect globals: collected global array element #3" + + gdb_test "tfind none" \ + "#0 end .*" \ + "collect globals: cease trace debugging" +} + +proc gdb_trace_collection_test { } { + global gdb_prompt; + + gdb_test "set width 0" "" "" + delete_breakpoints + + # We generously give ourselves one "pass" if we successfully + # detect that this test cannot be run on this target! + if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + } + + gdb_test "break begin" "" "" + gdb_test "break end" "" "" + gdb_collect_args_test "\$args" \ + "args collectively" + gdb_collect_args_test "argc, argi, argf, argd, argstruct, argarray" \ + "args individually" + gdb_collect_argstruct_test "\$args" \ + "argstruct collectively" + gdb_collect_argstruct_test "argstruct" \ + "argstruct individually" + gdb_collect_argarray_test "\$args" \ + "argarray collectively" + gdb_collect_argarray_test "argarray" \ + "argarray individually" + gdb_collect_locals_test local_test_func "\$locals" \ + "auto locals collectively" + gdb_collect_locals_test local_test_func \ + "locc, loci, locf, locd, locst, locar" \ + "auto locals individually" + gdb_collect_locals_test reglocal_test_func "\$locals" \ + "register locals collectively" + gdb_collect_locals_test reglocal_test_func \ + "locc, loci, locf, locd, locst, locar" \ + "register locals individually" + gdb_collect_locals_test statlocal_test_func "\$locals" \ + "static locals collectively" + gdb_collect_locals_test statlocal_test_func \ + "locc, loci, locf, locd, locst, locar" \ + "static locals individually" + + gdb_collect_registers_test "\$regs" + gdb_collect_registers_test "\$fp, \$sp, \$pc" + gdb_collect_globals_test + + # + # Expression tests: + # + # *x (**x, ...) + # x.y (x.y.z, ...) + # x->y (x->y->z, ...) + # x[2] (x[2][3], ...) (const index) + # x[y] (x[y][z], ...) (index to be char, short, long, float, double) + # NOTE: + # We test the following operators by using them in an array index + # expression -- because the naked result of an operator is not really + # collected. To be sure the operator was evaluated correctly on the + # target, we have to actually use the result eg. in an array offset + # calculation. + # x[y + z] (tests addition: y and z various combos of types, sclasses) + # x[y - z] (tests subtraction) (ditto) + # x[y * z] (tests multiplication) (ditto) + # x[y / z] (tests division) (ditto) + # x[y % z] (tests modulo division) (ditto) + # x[y == z] (tests equality relation) (ditto) UNSUPPORTED + # x[y != z] (tests inequality relation) (ditto) UNSUPPORTED + # x[y > z] (tests greater-than relation) (ditto) UNSUPPORTED + # x[y < z] (tests less-than relation) (ditto) UNSUPPORTED + # x[y >= z] (tests greater-than-or-equal relation) (ditto) UNSUPPORTED + # x[y <= z] (tests less-than-or-equal relation) (ditto) UNSUPPORTED + # x[y && z] (tests logical and) (ditto) UNSUPPORTED + # x[y || z] (tests logical or) (ditto) UNSUPPORTED + # x[y & z] (tests binary and) (ditto) UNSUPPORTED + # x[y | z] (tests binary or) (ditto) UNSUPPORTED + # x[y ^ z] (tests binary xor) (ditto) UNSUPPORTED + # x[y ? z1 : z2] (tests ternary operator) (ditto) UNSUPPORTED + # x[y << z] (tests shift-left) (ditto) UNSUPPORTED + # x[y >> z] (tests shift-right) (ditto) UNSUPPORTED + # x[y = z] (tests assignment operator) (ditto) UNSUPPORTED + # x[++y] (tests pre-increment operator) (ditto) UNSUPPORTED + # x[--y] (tests pre-decrement operator) (ditto) UNSUPPORTED + # x[y++] (tests post-increment operator) (ditto) UNSUPPORTED + # x[y--] (tests post-decrement operator) (ditto) UNSUPPORTED + # x[+y] (tests unary plus) (ditto) + # x[-y] (tests unary minus) (ditto) + # x[!y] (tests logical not) (ditto) UNSUPPORTED + # x[~y] (tests binary not) (ditto) UNSUPPORTED + # x[(y, z)] (tests comma expression) (ditto) + # cast expr + # stack data + + gdb_collect_expression_test globals_test_func \ + "globalstruct.memberi" "82" "a.b" + gdb_collect_expression_test globals_test_func \ + "globalp->memberc" "81 'Q'" "a->b" + gdb_collect_expression_test globals_test_func \ + "globalarr\[2\]" "2" "a\[2\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[l3\]" "3" "a\[b\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[l3 + l2\]" "5" "a\[b + c\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[l3 - l2\]" "1" "a\[b - c\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[l3 * l2\]" "6" "a\[b * c\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[l6 / l3\]" "2" "a\[b / c\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[l7 % l3\]" "1" "a\[b % c\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[+l1\]" "1" "a\[+b\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[-lminus\]" "2" "a\[-b\]" + gdb_collect_expression_test globals_test_func \ + "globalarr\[\(l6, l7\)\]" "7" "a\[\(b, c\)\]" + +} + +# Start with a fresh gdb. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load $binfile + +if [target_info exists gdb_stub] { + gdb_step_for_stub; +} + +# Body of test encased in a proc so we can return prematurely. +gdb_trace_collection_test + +# Finished! +gdb_test "tfind none" "" "" + + + Index: while-stepping.exp =================================================================== --- while-stepping.exp (nonexistent) +++ while-stepping.exp (revision 840) @@ -0,0 +1,116 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile ${objdir}/${subdir}/${testfile} + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" $binfile \ + executable {debug nowarnings}] != "" } { + untested while-stepping.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# +# test while-stepping command +# + +gdb_delete_tracepoints +set trcpt1 [gdb_gettpnum gdb_c_test] +if { $trcpt1 <= 0 } then { + fail "Could not find gdb_c_test function" + return; +} + +# 5.12 basic while-stepping command (collect regs) + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+0\[\t \]+.*in gdb_c_test.*" \ + "5.12: set a tracepoint, stepcount is zero" + +set stepcount 12 + +gdb_trace_setactions "5.12: set stepcount to $stepcount" \ + "" \ + "while-stepping $stepcount" "" \ + "collect \$regs" "^$" \ + "end" "" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+$stepcount\[\t \]+.*in gdb_c_test.*" \ + "5.12: confirm stepcount set to $stepcount" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.* +.*while-stepping $stepcount.*" \ + "5.12: info trace shows \"while-stepping\"" + + +# 5.13 step out of context while collecting local variable +# [deferred to dynamic test section] + +proc while_stepping_bogus_arg { bogus msgstring } { + global gdb_prompt; + + gdb_trace_setactions "$msgstring" \ + "" \ + "while-stepping $bogus" "\[Ee\]rror|\[Ww\]arning" +} + +# 5.14 while-stepping (no argument) + +while_stepping_bogus_arg "" "5.14: while-stepping null stepcount" + +# 5.15 while-stepping (zero stepcount) + +while_stepping_bogus_arg "0" "5.15: while-stepping rejects zero stepcount" + +# 5.16 while-stepping without collecting anything +gdb_trace_setactions "5.16: step without collecting anything" \ + "" \ + "while-stepping $stepcount" "^$" \ + "end" "" + +gdb_test "info tracepoints" \ + ".*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+$stepcount\[\t \]+.*in gdb_c_test.*\[ \t\]+Actions for tracepoint $trcpt1:.*\[ \t\]+while-stepping $stepcount.*\[ \t\]+end.*\[ \t\]+end.*" \ + "5.16: confirm actions, step without collecting anything" + Index: while-dyn.exp =================================================================== --- while-dyn.exp (nonexistent) +++ while-dyn.exp (revision 840) @@ -0,0 +1,125 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp" + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + load_lib "emc-support.exp" + set testfile "gdb_c_test" + set srcfile $testfile.c + set binfile [board_info target d490_binfile]; + gdb_test "set remotetimeout 6" "" "" + set timeout 500 + gdb_target_monitor "$binfile" + # Give a TSTOP and ignore errors, to make sure any previous trace is off + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + send_gdb "compare-section CS\n" + gdb_expect { + -re "MIS-MATCHED.*$gdb_prompt $" { + untested while-dyn.exp + return -1 + all tests in this module will fail."; + } + -re ".*$gdb_prompt $" { } + } +} else { + set testfile "actions" + set srcfile $testfile.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested while-dyn.exp + return -1 + } + gdb_load $binfile + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + runto_main +} +gdb_reinitialize_dir $srcdir/$subdir + +# We generously give ourselves one "pass" if we successfully +# detect that this test cannot be run on this target! +if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + +} + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +# +# test while-stepping dynamically (live target) +# + +## verify number of trace frames collected matches stepcount + +gdb_delete_tracepoints +gdb_test "trace gdb_c_test" \ + "Tracepoint $decimal at .*" \ + "Set tracepoint at gdb_c_test" + +gdb_trace_setactions "5.12: define while-stepping " \ + "" \ + "collect \$fp" "^$" \ + "while-stepping 5" "^$" \ + "collect p" "^$" \ + "end" "^$" \ + "end" "" + +gdb_test "tstart" "" "" + +if [istarget "m68k-*-elf"] then { + gdb_emclaptop_command "85,1,2,3,4,5,6" + sleep 5 +} else { + gdb_test "break end" "" "" + gdb_test "continue" \ + "Continuing.*Breakpoint $decimal, end.*" \ + "run trace experiment" +} + +gdb_test "tstop" "" "" + +gdb_tfind_test "5.12: frame 5 should be the last one collected" "5" "5" + +send_gdb "tfind 6\n" +gdb_expect { + -re "failed to find.*$gdb_prompt $" { + pass "5.12: trace stopped after 5 stepping frames" + } + -re ".*$gdb_prompt $" { + fail "5.12: trace stopped after 5 stepping frames" + } +} + +gdb_test "tfind none" "" "" Index: actions.exp =================================================================== --- actions.exp (nonexistent) +++ actions.exp (revision 840) @@ -0,0 +1,207 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + set binfile [board_info target d490_binfile]; + set srcfile gdb_c_test.c +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested actions.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) + +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} + +set testline1 [expr $baseline + 7] + +# +# test actions command +# + +gdb_delete_tracepoints +set trcpt1 [gdb_gettpnum gdb_c_test]; +set trcpt2 [gdb_gettpnum gdb_asm_test]; +set trcpt3 [gdb_gettpnum $testline1]; +if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then { + fail "setting tracepoints" + return; +} + +# 5.1 actions of specified tracepoint + +send_gdb "info tracepoints\n" +gdb_expect { + -re "Actions for tracepoint \[0-9\]+:.*$gdb_prompt $" { + fail "5.1a: testsuite failure (tracepoint already has action)!" + } + -re "No tracepoints.*$gdb_prompt $" { + fail "5.1a: set three tracepoints, no actions (No tracepoints!)" + } + -re "$gdb_prompt $" { + pass "5.1a: set three tracepoints, no actions" + } +} + +gdb_trace_setactions "5.1b: set actions for first tracepoint" \ + "$trcpt1" \ + "collect gdb_char_test" "^$" + +send_gdb "info tracepoints\n" +gdb_expect { + -re "Actions for.* $trcpt1:.*collect gdb_char_test.*$gdb_prompt $" { + pass "5.1c: verify actions set for first tracepoint" + } + -re "$gdb_prompt $" { + fail "5.1c: verify actions set for first tracepoint" + } +} + +gdb_trace_setactions "5.1d: set actions for second tracepoint" \ + "$trcpt2" \ + "collect gdb_short_test" "^$" + +send_gdb "info tracepoints\n" +gdb_expect { + -re "Actions for.* $trcpt2:.*collect gdb_short_test.*$gdb_prompt $" { + pass "5.1e: verify actions set for second tracepoint" + } + -re "$gdb_prompt $" { + fail "5.1e: verify actions set for second tracepoint" + } +} + +gdb_trace_setactions "5.2a: set actions for last (default) tracepoint" \ + "" \ + "collect gdb_long_test" "^$" + +send_gdb "info tracepoints\n" +gdb_expect { + -re "Actions for.* $trcpt3:.*collect gdb_long_test.*$gdb_prompt $" { + pass "5.2b: verify actions set for last (default) tracepoint" + } + -re "$gdb_prompt $" { + fail "5.2b: verify actions set for last (default) tracepoint" + } +} + +# 5.3 replace actions set earlier + +gdb_trace_setactions "5.3a: reset actions for first tracepoint" \ + "$trcpt1" \ + "collect gdb_struct1_test" "^$" + +send_gdb "info tracepoints\n" +gdb_expect { + -re "Actions for.* $trcpt1:.*collect gdb_struct1_test.*$gdb_prompt $" { + pass "5.3b: verify actions set for first tracepoint" + } + -re "$gdb_prompt $" { + fail "5.3b: verify actions set for first tracepoint" + } +} + +# +# test end command (all by itself) +# + +# 5.4 end outside of context + +gdb_test "end" "This command cannot be used at the top level." \ + "5.4: 'end' command out of context" + +# 5.5 empty actions (just an end with no other actions) + +gdb_trace_setactions "5.5a: set empty actions for first tracepoint" \ + "$trcpt1" + +send_gdb "info tracepoints\n" +gdb_expect { + -re "No tracepoints.*$gdb_prompt $" { + fail "5.5c: verify NO actions for first tracepoint" + } + -re "Actions for.* $trcpt1:.*$gdb_prompt $" { + fail "5.5c: verify NO actions for first tracepoint" + } + -re "$gdb_prompt $" { + pass "5.5c: verify NO actions for first tracepoint" + } +} + +# 5.6 actions for invalid tracepoint number + +gdb_test "actions [expr $trcpt2 + $trcpt3]" \ + "No tracepoint number [expr $trcpt2 + $trcpt3]." \ + "5.6: actions for invalid tracepoint number" + +# 5.7 invalid action (other than 'collect', 'while-stepping' or 'end') +# "warning: .print gdb_c_test. is not a supported trace.*> $" \ + +gdb_trace_setactions "5.7: invalid action" \ + "$trcpt1" \ + "print gdb_c_test" \ + "warning: .print gdb_c_test. is not a supported trace" + +# 5.8 help actions (collect, while-stepping, end) + +gdb_test "help actions" \ + "Specify the actions to be taken at a tracepoint.*" \ + "5.8a: help actions" + +gdb_test "help collect" \ + "Specify one or more data items to be collected at a tracepoint.*" \ + "5.8b: help collect" + +gdb_test "help while-stepping" \ + "Specify single-stepping behavior at a tracepoint.*" \ + "5.8c: help while-stepping" + +gdb_test "help end" "Ends a list of commands or actions.*" \ + "5.8d: help end" + Index: limits.exp =================================================================== --- limits.exp (nonexistent) +++ limits.exp (revision 840) @@ -0,0 +1,316 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +if [istarget "m68k-*-elf"] then { + pass "Test not supported on this target" + return; +} + +load_lib "trace-support.exp" + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +set testfile "limits" +set srcfile ${testfile}.c +set binfile $objdir/$subdir/$testfile + +if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested limits.exp + return -1 +} + +# Tests: +# 1) Meet and exceed artificial limit on number of tracepoints +# 2) Meet and exceed artificial limit on number of memranges +# 3) Meet and exceed artificial limit on bytes of bytecode data +# [NOTE: number four is moved out into its own separate test module.] +# 4) Meet and exceed artificial limit on bytes of trace buffer storage +# (circular and non-circular modes). However note that a more +# thorough test of the circular mode can be made separately. + +set cr "\[\r\n\]+" + +proc gdb_tracepoint_limit_test { } { + global gdb_prompt + global cr + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # Set three tracepoints + gdb_test "trace foo" \ + "Tracepoint \[0-9\]+ at .*" \ + "tracepoint limit test: set first tracepoint" + + gdb_test "trace bar" \ + "Tracepoint \[0-9\]+ at .*" \ + "tracepoint limit test: set second tracepoint" + + gdb_test "trace baz" \ + "Tracepoint \[0-9\]+ at .*" \ + "tracepoint limit test: set third tracepoint" + + # Set secret artificial tracepoint limit to four + gdb_test "maint packet QTLimit:tp:4" \ + "received: .OK." \ + "tracepoint limit test: set limit to four" + + # Now sending three tracepoints should succeed. + send_gdb "tstart\n" + gdb_expect { + -re "$cr$gdb_prompt" { + pass "tracepoint limit test: send fewer than limit" + } + default { + fail "tracepoint limit test: send fewer than limit" + } + } + + # Set secret artificial tracepoint limit to three + gdb_test "maint packet QTLimit:tp:3" \ + "received: .OK." \ + "tracepoint limit test: set limit to three" + + # Now sending three tracepoints should still succeed. + send_gdb "tstart\n" + gdb_expect { + -re "$cr$gdb_prompt" { + pass "tracepoint limit test: send equal to limit" + } + default { + fail "tracepoint limit test: send equal to limit" + } + } + + # Set secret artificial tracepoint limit to two + gdb_test "maint packet QTLimit:tp:2" \ + "received: .OK." \ + "tracepoint limit test: set limit to two" + + # Now sending three tracepoints should fail. + gdb_test "tstart" \ + ".*\[Ee\]rror.*" \ + "tracepoint limit test: send more than limit" + + # Clean up: + gdb_test "tstop" "" "" + gdb_test "maint packet QTLimit:tp:FFFFFFFF" "" "" +} + +proc gdb_memrange_limit_test { } { + global gdb_prompt + global cr + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # Set three tracepoints, and make 'em collect memranges + gdb_test "trace foo" \ + "Tracepoint \[0-9\]+ at .*" \ + "memrange limit test: set first tracepoint" + + gdb_trace_setactions "memrange limit test: set first actions" \ + "" \ + "collect \$arg" "^$" + + gdb_test "trace bar" \ + "Tracepoint \[0-9\]+ at .*" \ + "memrange limit test: set second tracepoint" + + gdb_trace_setactions "memrange limit test: set second actions" \ + "" \ + "collect \$arg" "^$" + + gdb_test "trace baz" \ + "Tracepoint \[0-9\]+ at .*" \ + "memrange limit test: set third tracepoint" + + gdb_trace_setactions "memrange limit test: set third actions" \ + "" \ + "collect \$arg" "^$" + + # Set secret artificial memrange limit to four + gdb_test "maint packet QTLimit:memrange:4" \ + "received: .OK." \ + "memrange limit test: set limit to four" + + # Now sending three memranges should still succeed. + send_gdb "tstart\n" + gdb_expect { + -re "$cr$gdb_prompt" { + pass "memrange limit test: send fewer than limit" + } + default { + fail "memrange limit test: send fewer than limit" + } + } + + # Set secret artificial memrange limit to three + gdb_test "maint packet QTLimit:memrange:3" \ + "received: .OK." \ + "memrange limit test: set limit to three" + + # Now sending three memranges should still succeed. + send_gdb "tstart\n" + gdb_expect { + -re "$cr$gdb_prompt" { + pass "memrange limit test: send equal to limit" + } + default { + fail "memrange limit test: send equal to limit" + } + } + + # Set secret artificial memrange limit to two + gdb_test "maint packet QTLimit:memrange:2" \ + "received: .OK." \ + "memrange limit test: set limit to two" + + # Now sending three memranges should fail. + gdb_test "tstart" \ + ".*\[Ee\]rror.*" \ + "memrange limit test: send more than limit" + + # Clean up: + gdb_test "tstop" "" "" + gdb_test "maint packet QTLimit:memrange:FFFFFFFF" "" "" +} + + +proc gdb_bytecode_limit_test { } { + global gdb_prompt + global cr + + # Make sure we're in a sane starting state. + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + gdb_delete_tracepoints + + # Set three tracepoints + gdb_test "trace foo" \ + "Tracepoint \[0-9\]+ at .*" \ + "bytecode limit test: set first tracepoint" + + gdb_trace_setactions "bytecode limit test: set first actions" \ + "" \ + "collect x + n" "^$" + + gdb_test "trace bar" \ + "Tracepoint \[0-9\]+ at .*" \ + "bytecode limit test: set second tracepoint" + + gdb_trace_setactions "bytecode limit test: set second actions" \ + "" \ + "collect y + n" "^$" + + gdb_test "trace baz" \ + "Tracepoint \[0-9\]+ at .*" \ + "bytecode limit test: set third tracepoint" + + gdb_trace_setactions "bytecode limit test: set third actions" \ + "" \ + "collect z + n" "^$" + + # Set secret artificial bytecode limit to a large number + gdb_test "maint packet QTLimit:bytecode:400" \ + "received: .OK." \ + "bytecode limit test: set limit to large" + + # Now sending three bytecodes should still succeed. + send_gdb "tstart\n" + gdb_expect { + -re "$cr$gdb_prompt" { + pass "bytecode limit test: send fewer than limit" + } + default { + fail "bytecode limit test: send fewer than limit" + } + } + + # Set secret artificial bytecode limit to a small number + gdb_test "maint packet QTLimit:bytecode:40" \ + "received: .OK." \ + "bytecode limit test: set limit to small" + + # Now sending three bytecodes should fail. + gdb_test "tstart" \ + ".*\[Ee\]rror.*" \ + "bytecode limit test: send more than limit" + + + # Clean up: + gdb_test "tstop" "" "" + gdb_test "maint packet QTLimit:bytecode:FFFFFFFF" "" "" +} + +proc gdb_trace_limits_tests { } { + global gdb_prompt + + # We generously give ourselves one "pass" if we successfully + # detect that this test cannot be run on this target! + + if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + } + + if [gdb_test "maint packet QTLimit:tp:ffffffff" \ + "received: .OK." ""] then { + pass "This test cannot be run on this target" + return 1; + } + + if [gdb_test "maint packet QTLimit:memrange:ffffffff" \ + "received: .OK." ""] then { + pass "This test cannot be run on this target" + return 1; + } + + if [gdb_test "maint packet QTLimit:bytecode:ffffffff" \ + "received: .OK." ""] then { + pass "This test cannot be run on this target" + return; + } + + gdb_tracepoint_limit_test + gdb_memrange_limit_test + gdb_bytecode_limit_test +} + +# Start with a fresh gdb. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load $binfile + +if [target_info exists gdb_stub] { + gdb_step_for_stub; +} +# Body of test encased in a proc so we can return prematurely. +gdb_trace_limits_tests Index: passc-dyn.exp =================================================================== --- passc-dyn.exp (nonexistent) +++ passc-dyn.exp (revision 840) @@ -0,0 +1,188 @@ +# Copyright 1998, 2005, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start +if [istarget "m68k-*-elf"] then { + load_lib "emc-support.exp"; + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; + gdb_test "set remotetimeout 6" "" "" + set timeout 500 + gdb_target_monitor $binfile + # Give a TSTOP and ignore errors, to make sure any previous trace is off + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + send_gdb "compare-sections CS\n" + gdb_expect { + -re "MIS-MATCHED.*$gdb_prompt $" { + untested passc-dyn.exp + return -1 + all tests in this module will fail."; + } + -re ".*$gdb_prompt $" { } + } +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested passc-dyn.exp + return -1 + } + gdb_load $binfile + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + runto_main +} +gdb_reinitialize_dir $srcdir/$subdir + +# We generously give ourselves one "pass" if we successfully +# detect that this test cannot be run on this target! +if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + +} + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + + +# +# test passcount dynamically (live target) +# + +set baseline [gdb_find_recursion_test_baseline $srcfile]; + +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) + +set testline2 [expr $baseline + 4] +set testline3 [expr $baseline + 5] +set testline4 [expr $baseline + 6] + +# +# test passcount command semantics (live test) +# + +## Set three tracepoints with three different passcounts. +## Verify that the experiment stops after the one with the +## lowest passcount is hit. + +gdb_delete_tracepoints +set tdp2 [gdb_gettpnum "$testline2"] +set tdp3 [gdb_gettpnum "$testline3"] +set tdp4 [gdb_gettpnum "$testline4"] +if { $tdp2 <= 0 || $tdp3 <= 0 || $tdp4 <= 0 } then { + fail "setting tracepoints" + return; +} + +gdb_test "passcount 4 $tdp2" "Setting tracepoint $tdp2's passcount to 4" \ + "4.5: set passcount for tracepoint $tdp2" +gdb_test "passcount 2 $tdp3" "Setting tracepoint $tdp3's passcount to 2" \ + "4.5: set passcount for tracepoint $tdp3" +gdb_test "passcount 3 $tdp4" "Setting tracepoint $tdp4's passcount to 3" \ + "4.5: set passcount for tracepoint $tdp4" + +gdb_test "tstart" "" "" + +if [istarget "m68k-*-elf"] then { + gdb_emclaptop_command "85,1,2,3,4,5,6" + sleep 5 + gdb_emclaptop_command "85,7,8,9,A,B,C" + sleep 5 + gdb_emclaptop_command "85,D,E,F,10,11,12" + sleep 5 + # gdb_test "tstop" + ## + ## Note! Must NOT give the tstop command, because the passcount + ## has already stopped the experiment. You would not + ## think this would be an error, but in EMC's mind it is... + ## +} else { + gdb_test "break end" "" "" + gdb_test "continue" \ + "Continuing.*Breakpoint $decimal, end.*" \ + "run trace experiment" + gdb_test "tstop" "" "" +} + +gdb_test "tfind none" "" "" +if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x -1 x" ""] { + untested passc-dyn.exp + return -1 +} + +gdb_test "tfind tracepoint $tdp2" "" "" +if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 0 x" ""] { + untested passc-dyn.exp + return -1 +} + +gdb_test "tfind tracepoint $tdp3" "" "" +if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 1 x" ""] { + untested passc-dyn.exp + return -1 +} + +gdb_test "tfind tracepoint $tdp4" "" "" +if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 2 x" ""] { + untested passc-dyn.exp + return -1 +} + +gdb_test "tfind tracepoint $tdp2" "" "" +if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 3 x" ""] { + untested passc-dyn.exp + return -1 +} + +gdb_test "tfind tracepoint $tdp3" "" "" +if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 4 x" ""] { + untested passc-dyn.exp + return -1 +} + +## We should now be at the last frame, because this frame's passcount +## should have caused collection to stop. If we do a tfind now, +## it should fail. + +gdb_test "tfind" "failed to find.*" "4.5: dynamic passcount test" + +# Finished! +gdb_test "tfind none" "" "" + Index: tfind.exp =================================================================== --- tfind.exp (nonexistent) +++ tfind.exp (revision 840) @@ -0,0 +1,407 @@ +# Copyright 1998, 2002, 2005, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + load_lib "emc-support.exp"; + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; + gdb_test "set remotetimeout 6" "" "" + set timeout 500 + gdb_target_monitor $binfile + # Give a TSTOP and ignore errors, to make sure any previous trace is off + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + send_gdb "compare-sections CS\n" + gdb_expect { + -re "MIS-MATCHED.*$gdb_prompt $" { + untested tfind.exp + return -1 + all tests in this module will fail."; + } + -re ".*$gdb_prompt $" { } + } +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + + if { [gdb_compile "$srcdir/$subdir/$srcfile" "$binfile" \ + executable {debug nowarnings}] != "" } { + untested tfind.exp + return -1 + } + gdb_load $binfile + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + runto_main +} +gdb_reinitialize_dir $srcdir/$subdir + +# We generously give ourselves one "pass" if we successfully +# detect that this test cannot be run on this target! +if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + +} + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} + +set testline1 [expr $baseline + 1] +set testline2 [expr $baseline + 5] +set testline3 [expr $baseline + 6] +set testline4 [expr $baseline + 7] +set testline5 [expr $baseline + 8] + +# +# test tfind command +# + +gdb_delete_tracepoints +set tdp1 [gdb_gettpnum "\*gdb_recursion_test"] +set tdp2 [gdb_gettpnum $testline2] +set tdp3 [gdb_gettpnum $testline3] +set tdp4 [gdb_gettpnum $testline4] +set tdp5 [gdb_gettpnum $testline5] +if { $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \ + $tdp4 <= 0 || $tdp5 <= 0 } then { + fail "setting tracepoints" + return; +} + +# 6.1 test tstart command +send_gdb "tstart\n" +gdb_expect { + -re "Trace can only be run on remote targets.*$gdb_prompt $" { + fail "6.1: tstart (not connected to remote?)" + return; + } + -re "Target does not support this command.*$gdb_prompt $" { + fail "6.1: tstart (connected to wrong target?)" + return; + } + -re "Target returns error code.*$gdb_prompt $" { + fail "6.1: tstart (connected to wrong target?)" + return; + } + -re "$gdb_prompt $" { + pass "6.1: tstart" + } + default { + fail "6.1: tstart (default)" + return; + } +} + +# test tstatus (when trace on) +gdb_test "tstatus" "\[Tt\]race is running.*" "test tstatus on" + +# 6.2 test help tstart +gdb_test "help tstart" "Start trace data collection." "6.2: help tstart" + +if [istarget "m68k-*-elf"] then { + gdb_emclaptop_command "85,1,2,3,4,5,6" + sleep 5 + + gdb_emclaptop_command "85,7,8,9,A,B,C" + sleep 5 +} else { + gdb_test "break end" "" "" + gdb_test "continue" \ + "Continuing.*Breakpoint $decimal, end.*" \ + "run trace experiment" +} + +# 7.1 test tstop command +send_gdb "tstop\n" +gdb_expect { + -re "Trace can only be run on remote targets.*$gdb_prompt $" { + fail "7.1: tstop (not connected to remote?)" + return; + } + -re "Target does not support this command.*$gdb_prompt $" { + fail "7.1: tstop (connected to wrong target?)" + return; + } + -re "Target returns error code.*$gdb_prompt $" { + fail "7.1: tstop (connected to wrong target?)" + return; + } + -re "$gdb_prompt $" { + pass "7.1: tstop" + } + default { + fail "7.1: tstop (default)" + return; + } +} + +# 7.2 test help tstop +gdb_test "help tstop" "Stop trace data collection." "7.2: help tstop" + +# test tstatus (when trace off) +gdb_test "tstatus" "\[Tt\]race.* not running.*" "test tstatus off" + +## record starting PC +set save_pc [gdb_readexpr "(unsigned long) \$pc"]; +if { $save_pc == -1 } then { + fail "could not read PC" + return; +} + +# 8.7 tfind start +## check $trace_frame == 0 +gdb_tfind_test "8.7: tfind start command" "start" "0"; +## check $pc != startPC +gdb_test "printf \"x \%d x\\n\", \$pc != $save_pc" \ + "x 1 x" \ + "8.7b: tfind start" + +# 8.8 tfind none +## check $trace_frame == -1 +gdb_tfind_test "8.8: tfind none" "none" "-1"; +## check $pc == startPC +gdb_test "printf \"x \%d x\\n\", \$pc == $save_pc" \ + "x 1 x" \ + "8.8b: tfind none (restores non-trace PC)" + +# 8.9 tfind end +## check $trace_frame == -1 +gdb_tfind_test "8.9: tfind end, selects no frame" "end" "-1"; +## check $pc == startPC +gdb_test "printf \"x \%d x\\n\", \$pc == $save_pc" \ + "x 1 x" \ + "8.9b: tfind end (restores non-tracing PC)" + +# 8.1 tfind n +## check $trace_frame == n +gdb_tfind_test "8.1: tfind 1" "1" "1" +## check $trace_line corresponds to tracepoint for frame n +gdb_test "print \$trace_line" "$testline2" "8.1b: tfind 1 (correct line)" + +# 8.28 tfind invalid n (big number) +## check "not found" error +## check $trace_frame != n +gdb_test "tfind 32767" \ + "failed to find.*" \ + "8.28: tfind command rejects invalid frame number" + +gdb_test "printf \"x \%d x\\n\", \$trace_frame == 32767" \ + "x 0 x" \ + "8.28: tfind rejected bad input (32767)" + +# 8.31 tfind negative n +## check error +gdb_test "tfind -3" "invalid input.*" "8.31: tfind rejects negative input" +## check $trace_frame != -n +gdb_test "printf \"x \%d x\\n\", \$trace_frame == -3" "x 0 x" \ + "8.31: tfind rejected negative input (-3)" + +# 8.10 tfind +## check $trace_frame += 1 + +gdb_tfind_test "8.10: tfind start" "start" "0"; +gdb_test "print \$trace_line" "$baseline" \ + "8.10: tfind 0 (correct line $baseline)" +gdb_tfind_test "8.10: tfind noargument 1" "" "1"; +gdb_test "print \$trace_line" "$testline2" \ + "8.10: tfind 1 (correct line $testline2)" +gdb_tfind_test "8.10: tfind noargument 2" "" "2"; +gdb_test "print \$trace_line" "$testline3" \ + "8.10: tfind 2 (correct line $testline3)" +gdb_tfind_test "8.10: tfind noargument 3" "" "3"; +gdb_test "print \$trace_line" "$testline4" \ + "8.10: tfind 3 (correct line $testline4)" + +gdb_tfind_test "8.11: tfind 3" "3" "3"; +gdb_test "print \$trace_line" "$testline4" \ + "8.11: tfind 3 (correct line $testline4)" +gdb_tfind_test "8.11: tfind backward 2" "-" "2"; +gdb_test "print \$trace_line" "$testline3" \ + "8.11: tfind 2 (correct line $testline3)" +gdb_tfind_test "8.11: tfind backward 1" "-" "1"; +gdb_test "print \$trace_line" "$testline2" \ + "8.11: tfind 1 (correct line $testline2)" +gdb_tfind_test "8.11: tfind backward 0" "-" "0"; +gdb_test "print \$trace_line" "$baseline" \ + "8.11: tfind 0 (correct line $baseline)" + +gdb_tfind_test "8.12: tfind none" "none" "-1"; +gdb_tfind_test "8.12: tfind tracepoint " "tracepoint $tdp2" \ + "\$tracepoint" "$tdp2"; +gdb_test "print \$trace_line" "$testline2" \ + "8.12: tfind tracepoint (line $testline2)" + +gdb_tfind_test "8.25: tfind none" "none" "-1"; +gdb_test "tfind tracepoint 0" "failed to find.*" \ + "8.25: tfind tracepoint rejects zero" +gdb_test "tfind tracepoint 32767" "failed to find.*" \ + "8.25: tfind tracepoint rejects nonexistant tracepoint (32767)" +gdb_test "tfind tracepoint -1" "failed to find.*" \ + "8.25: tfind tracepoint rejects nonexistant tracepoint (-1)" + +# 8.37 tfind tracepoint n where n no longer exists (but used to) +gdb_test "delete trace $tdp2" "" "" +gdb_tfind_test "8.37: tfind none" "none" "-1"; +gdb_tfind_test "8.37: tfind deleted tracepoint" \ + "tracepoint $tdp2" \ + "\$tracepoint" "$tdp2"; +gdb_test "print \$trace_line" "$testline2" \ + "8.37: tfind deleted tracepoint (line $testline2)" + +# 8.13 tfind tracepoint +## check $tracepoint same before and after, $trace_frame changed + +gdb_tfind_test "8.13: tfind none" "none" "-1"; +gdb_tfind_test "8.13: tracepoint $tdp1" "tracepoint $tdp1" \ + "\$tracepoint" "$tdp1"; +gdb_test "print \$trace_line" "$baseline" \ + "8.13: tfind tracepoint $tdp1 (line $baseline)" +gdb_test "set \$save_frame = \$trace_frame" "" "" +gdb_tfind_test "8.13: tracepoint " "tracepoint" \ + "\$tracepoint" "$tdp1"; +gdb_test "printf \"x \%d x\\n\", \$trace_frame == \$save_frame" \ + "x 0 x" \ + "8.13: tracepoint , tracepoint number unchanged" + +# 1.12 set tracepoint in prologue +# +# tdp1 was set at *gdb_recursion_test (ie. the hard address of the +# function, before the prologue). Test to see that it succeeded. +# Current pc should be equal to the address of the function. + +gdb_test "printf \"x \%d x\\n\", \$pc == gdb_recursion_test" \ + "x 1 x" \ + "1.12: set tracepoint in prologue" + +# 8.14 tfind pc x +## check pc == x, $trace_frame != -1 +gdb_tfind_test "8.14: tfind 3" "3" "3" +gdb_test "print \$trace_line" "$testline4" \ + "8.14: tfind 3 (line $testline4)" + +gdb_test "set \$test_pc = \$pc" "" "" +gdb_tfind_test "8.14: tfind none" "none" "-1" +gdb_tfind_test "8.14: tfind pc" "pc \$test_pc" "\$trace_frame != -1" "1"; +gdb_test "print \$trace_line" "$testline4" \ + "8.14: tfind pc x (line $testline4)" +gdb_test "printf \"x \%d x\\n\", \$pc == \$test_pc" \ + "x 1 x" \ + "8.14: tfind pc x" + +# 8.15 tfind pc +## check pc same before and after, $trace_frame changed +gdb_tfind_test "8.15: tfind 3" "3" "3" +gdb_test "print \$trace_line" "$testline4" \ + "8.15: tfind 3 (line $testline4)" +gdb_test "set \$test_pc = \$pc" "" "" +gdb_tfind_test "8.15: tfind pc" "pc" "\$pc == \$test_pc" "1" +gdb_test "print \$trace_line" "$testline4" \ + "8.15: tfind pc (line $testline4)" +gdb_test "printf \"x \%d x\\n\", \$trace_frame != 3" "x 1 x" \ + "8.15: trace frame didn't change" + +# 8.26 tfind pc invalid x +## check error, pc != x (trace_frame unchanged?) +gdb_tfind_test "8.26: tfind start" "start" "0" +gdb_test "tfind pc 0" "failed to find.*" "8.26: tfind pc zero" +gdb_test "tfind pc -1" "failed to find.*" "8.26: tfind pc -1" + +# 8.16 tfind line n +## check #trace_frame != -1, $trace_line == n +gdb_tfind_test "8.16: tfind none" "none" "-1" +gdb_tfind_test "8.16: tfind line $testline3" \ + "line $testline3" \ + "\$trace_line == $testline3" "1" + +# 8.17 tfind line (# 8.19, 8.20) +## check $trace_line changed, no error, pc changed, frame changed, tdp changed +gdb_tfind_test "8.17: tfind none" "none" "-1" +gdb_tfind_test "8.17: tfind line $testline3" "line $testline3" "\$trace_line == $testline3" "1" +gdb_tfind_test "8.17: tfind line " "line" "\$trace_line != $testline3" "1" + +# 8.36 tfind and disassembly +gdb_tfind_test "8.36: tfind start" "start" "0" +set timeout 60 +send_gdb "disassemble gdb_c_test\n" +# look for disassembly of function label +gdb_expect { + -re ":.*$gdb_prompt $" { pass "8.36: trace disassembly" } + -re ".*$gdb_prompt $" { fail "8.36: trace disassembly" } + timeout { fail "8.36: trace disassembly (timeout)" } +} + +gdb_test "tfind line 0" \ + "out of range.*|failed to find.*" \ + "8.18: tfind line 0"; +gdb_test "tfind line 32767" \ + "out of range.*|failed to find.*" \ + "8.27: tfind line 32767"; +gdb_test "tfind line NoSuChFiLe.c:$baseline" \ + "No source file named.*" \ + "8.27: tfind line in bad source file"; + +# 8.32 tfind invalid subcommand (tfind foo) +## check error +gdb_test "tfind NoSuChOpTiOn 21" \ + "No symbol.*|\[Ww\]arning.*|\[Ee\]rror.*" \ + "8.32: tfind with bad subcommand" + +# 8.38 test help tfind +gdb_test "help tfind" "Select a trace frame.*" \ + "8.38: help tfind" +gdb_test "help tfind pc" "Select a trace frame by PC.*" \ + "8.38: help tfind PC" +gdb_test "help tfind end" "Synonym for 'none'.*" \ + "8.38: help tfind end" +gdb_test "help tfind none" "De-select any trace frame.*" \ + "8.38: help tfind none" +gdb_test "help tfind line" "Select a trace frame by source line.*" \ + "8.38: help tfind line" +gdb_test "help tfind start" "Select the first trace frame.*" \ + "8.38: help tfind start" +gdb_test "help tfind range" "Select a trace frame whose PC is in.*" \ + "8.38: help tfind range" +gdb_test "help tfind trace" "Select a trace frame by tracepoint number.*" \ + "8.38: help tfind tracepoint" + +# Finished! +gdb_tfind_test "8.17: tfind none" "none" "-1" Index: circ.c =================================================================== --- circ.c (nonexistent) +++ circ.c (revision 840) @@ -0,0 +1,90 @@ +/* + * Test program for tracing; circular buffer + */ + +int n = 6; + +int testload[13]; + +static void func0(void) +{ +} + +static void func1(void) +{ +} + +static void func2(void) +{ +} + +static void func3(void) +{ +} + +static void func4(void) +{ +} + +static void func5(void) +{ +} + +static void func6(void) +{ +} + +static void func7(void) +{ +} + +static void func8(void) +{ +} + +static void func9(void) +{ +} + +static void begin () /* called before anything else */ +{ +} + +static void end () /* called after everything else */ +{ +} + +int +main (argc, argv, envp) + int argc; + char *argv[], **envp; +{ + int i; + +#ifdef usestubs + set_debug_traps (); + breakpoint (); +#endif + + begin (); + for (i = 0; i < sizeof(testload) / sizeof(testload[0]); i++) + testload[i] = i + 1; + + func0 (); + func1 (); + func2 (); + func3 (); + func4 (); + func5(); + func6 (); + func7 (); + func8 (); + func9 (); + + end (); + +#ifdef usestubs + breakpoint (); +#endif + return 0; +}
circ.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: packetlen.exp =================================================================== --- packetlen.exp (nonexistent) +++ packetlen.exp (revision 840) @@ -0,0 +1,101 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp" + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + load_lib "emc-support.exp" + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; + gdb_test "set remotetimeout 6" "" "" + set timeout 500 + gdb_target_monitor "$binfile" + # Give a TSTOP and ignore errors, to make sure any previous trace is off + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + send_gdb "compare-sections CS\n" + gdb_expect { + -re "MIS-MATCHED.*$gdb_prompt $" { + untested packetlen.exp + return -1 + all tests in this module will fail."; + } + -re ".*$gdb_prompt $" { } + } +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested packetlen.exp + return -1 + } + gdb_load $binfile + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + runto_main +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +# +# Test collecting a whole bunch of stuff at a single tracepoint. +# The test is whether this crashes GDB. +# + +gdb_delete_tracepoints +gdb_test "trace gdb_c_test" "" "" +gdb_trace_setactions "setup collect actions" \ + "" \ + "collect parm\[0\], parm\[1\], parm\[2\], parm\[3\]" "^$" \ + "collect parm\[4\], parm\[5\], parm\[6\], parm\[7\]" "^$" \ + "collect p, local_reg, local_static, local_static_sizeof" "^$" \ + "collect local_long, stack_ptr, end_of_stack" "^$" \ + "collect gdb_char_test, gdb_short_test, gdb_long_test" "^$" \ + "collect gdb_arr_test, gdb_struct1_test, gdb_struct2_test" "^$" \ + "collect gdb_structp_test, gdb_structpp_test, gdb_union1_test" "^$" \ + "end" "" + +gdb_test "tstart" "" "survive the long packet send" +if [istarget "m68k-*-elf"] then { + gdb_emclaptop_command "85,1,2,3,4,5,6" + sleep 5 +} else { + gdb_test "break end" "" "" + gdb_test "continue" \ + "Continuing.*Breakpoint $decimal, end.*" \ + "run trace experiment" +} + +gdb_test "tstop" "" "confirm: survived the long packet send" + Index: infotrace.exp =================================================================== --- infotrace.exp (nonexistent) +++ infotrace.exp (revision 840) @@ -0,0 +1,99 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested infotrace.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# +# test "info tracepoints" command +# + +gdb_delete_tracepoints +set c_test_num [gdb_gettpnum gdb_c_test]; +set asm_test_num [gdb_gettpnum gdb_asm_test]; +if { $c_test_num <= 0 || $asm_test_num <= 0 } then { + fail "setting tracepoints" + return; +} + +# 2.1 info tracepoints (all) +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$c_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*$asm_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*" \ + "2.1: info tracepoints (all)" + +# 2.2 info tracepoint (specific) +gdb_test "info tracepoint $c_test_num" \ + "$c_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*" \ + "2.2a: info tracepoint $c_test_num (gdb_c_test)" + +gdb_test "info tracepoint $asm_test_num" \ + "$asm_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*" \ + "2.2b: info tracepoint $asm_test_num (gdb_asm_test)" + +# 2.3 info tracepoint (invalid tracepoint number) +gdb_test "info tracepoint [expr $c_test_num + $asm_test_num]" \ + "No tracepoint number [expr $c_test_num + $asm_test_num]." \ + "2.3: info tracepoint (invalid tracepoint number)" + +# 2.4 info tracepoints (list of numbers) +send_gdb "info tracepoints $c_test_num $asm_test_num \n" +gdb_expect { + -re "Num Enb .*$gdb_prompt $" { + fail "2.4: info trace rejects multiple tracepoint numbers" + } + -re ".*$gdb_prompt $" { + pass "2.4: info trace rejects multiple tracepoint numbers" + } +} + +# 2.5 help info trace +gdb_test "help info tracepoints" \ + "Status of tracepoints, or tracepoint number NUMBER.*" \ + "2.5: help info tracepoints" + Index: report.exp =================================================================== --- report.exp (nonexistent) +++ report.exp (revision 840) @@ -0,0 +1,424 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + load_lib "emc-support.exp"; + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; + gdb_test "set remotetimeout 6" "" "" + set timeout 500 + gdb_target_monitor $binfile + # Give a TSTOP and ignore errors, to make sure any previous trace is off + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + send_gdb "compare-sections CS\n" + gdb_expect { + -re "MIS-MATCHED.*$gdb_prompt $" { + untested report.exp + return -1 + all tests in this module will fail."; + } + -re ".*$gdb_prompt $" { } + } +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested report.exp + return -1 + } + gdb_load $binfile + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + runto_main +} +gdb_reinitialize_dir $srcdir/$subdir + +# We generously give ourselves one "pass" if we successfully +# detect that this test cannot be run on this target! +if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + +} + +set cr "\[\r\n\]+" + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +# +# test general reporting of trace experiment results +# + +set testline1 0 +set testline2 0 +set testline3 0 +set testline4 0 +set testline5 0 +set testline6 0 + +set arg1 1 +set arg2 2 +set arg3 3 +set arg4 4 +set arg5 5 +set arg6 6 + +set gdb_recursion_test_baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $gdb_recursion_test_baseline == -1 } { + fail "Could not find gdb_recursion_test function" + return; +} + +send_gdb "list $gdb_recursion_test_baseline, +12\n" +gdb_expect { + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 1 " { + set testline1 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 2 " { + set testline2 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 3 " { + set testline3 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 4 " { + set testline4 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 5 " { + set testline5 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 6 " { + set testline6 $expect_out(1,string) + exp_continue + } + -re ".*$gdb_prompt $" { + if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } { + untested report.exp + return -1 +all tests in this module will fail." + } + } + default { + untested report.exp + return -1 +all tests in this module will fail." + } +} + +# +# Setup trace experiment. This will involve: +# 1) a tracepoint where nothing is collected +# 2) a tracepoint where only regs are collected +# 3) a tracepoint where only args are collected +# 4) a tracepoint where only locals are collected +# 5) a tracepoint where some amount of stack memory is collected. +# 6) a tracepoint where some expressions are collected. +# + +gdb_delete_tracepoints +set tdp1 [gdb_gettpnum $testline1] +set tdp2 [gdb_gettpnum $testline2] +set tdp3 [gdb_gettpnum $testline3] +set tdp4 [gdb_gettpnum $testline4] +set tdp5 [gdb_gettpnum $testline5] +set tdp6 [gdb_gettpnum $testline6] + +if { $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \ + $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then { + fail "setting tracepoints failed" + return; +} + +gdb_trace_setactions "9.x: setup TP to collect regs" \ + "$tdp2" \ + "collect \$regs" "^$" + + +gdb_trace_setactions "9.x: setup TP to collect args" \ + "$tdp3" \ + "collect \$args" "^$" + +gdb_trace_setactions "9.x: setup TP to collect locals" \ + "$tdp4" \ + "collect \$locs" "^$" + +gdb_trace_setactions "9.x: setup TP to collect stack memory" \ + "$tdp5" \ + "collect \$fp, \*\(void \*\*\) \$sp @ 64" "^$" + +gdb_trace_setactions "9.x: setup TP to collect expressions" \ + "$tdp6" \ + "collect gdb_char_test, gdb_short_test, gdb_long_test" "^$" + +gdb_test "tstart" "" "" + +if [istarget "m68k-*-elf"] then { + gdb_emclaptop_command "85,$arg1,$arg2,$arg3,$arg4,$arg5,$arg6" + sleep 5 + +} else { + gdb_test "break end" "" "" + gdb_test "continue" \ + "Continuing.*Breakpoint $decimal, end.*" \ + "run trace experiment" +} + +gdb_test "tstop" "" "" + +# +# 9.1 test the tdump command +# + +set timeout 60 + +gdb_tfind_test "9.1: init: make sure not debugging any trace frame" "none" "-1" + +gdb_tfind_test "9.1: find frame for TP $tdp1" "tracepoint $tdp1" \ + "\$tracepoint" "$tdp1" + +# Nothing was collected at tdp1, so this tdump should be empty. +gdb_test "tdump" \ + "Data collected at tracepoint $tdp1, trace frame $decimal:" \ + "9.1: tdump, nothing collected" + +gdb_tfind_test "9.1: find frame for TP $tdp2" "tracepoint $tdp2" \ + "\$tracepoint" "$tdp2" + +# regs were collected at tdp2. +# How to match for the output of "info registers" on an unknown architecture? +# For now, assume that every architecture has a register called "pc". +gdb_test "tdump" \ + "\[\r\n\]pc .*" \ + "9.1: tdump, regs collected" + +gdb_tfind_test "9.1: find frame for TP $tdp3" "tracepoint $tdp3" \ + "\$tracepoint" "$tdp3" + +# args were collected at tdp3 +gdb_test "tdump" \ + "depth = 3.*q1 = 2.*q2 = 2.*q3 = 3.*q4 = 4.*q5 = 5.*q6 = 6" \ + "9.1: tdump, args collected" + +gdb_tfind_test "9.1: find frame for TP $tdp4" "tracepoint $tdp4" \ + "\$tracepoint" "$tdp4" + +# locals were collected at tdp4 +gdb_test "tdump" \ + "q = 1" \ + "9.1: tdump, locals collected" + +gdb_tfind_test "9.1: find frame for TP $tdp5" "tracepoint $tdp5" \ + "\$tracepoint" "$tdp5" + +# stack was collected at tdp5, plus the frame pointer +gdb_test "tdump" \ + ".fp = .*sp @ 64 = .*" \ + "9.1: tdump, memrange collected" + +gdb_tfind_test "9.1: find frame for TP $tdp6" "tracepoint $tdp6" \ + "\$tracepoint" "$tdp6" + +# globals were collected at tdp6 +gdb_test "tdump" \ + "gdb_char_test = 1.*gdb_short_test = 2.*gdb_long_test = 3" \ + "9.1: tdump, global variables collected" + +# 9.2 test tdump with arguments +# [no go, tdump doesn't have any arguments] + +# 9.3 help tdump + +gdb_test "help tdump" "Print everything collected at the current.*" \ + "9.3: help tdump" + +set linecount1 0 +set linecount2 0 +set linecount3 0 +set linecount4 0 +set linecount5 0 +set linecount6 0 + +gdb_tfind_test "11.x, 12.1: find start frame" "start" "0" + +# +# 11.x test built-in trace variables $trace_frame, $trace_line etc. +# + +gdb_test "printf \"x %d x\\n\", \$trace_frame" "x 0 x" \ + "11.1: test \$trace_frame" + +gdb_test "printf \"x %d x\\n\", \$tracepoint" "x $tdp1 x" \ + "11.2: test \$tracepoint" + +gdb_test "printf \"x %d x\\n\", \$trace_line" "x $testline1 x" \ + "11.3: test \$trace_line" + +send_gdb "print \$trace_file\n" +gdb_expect { + -re "\\$\[0-9\]+ = \"$srcfile\"\[\r\n\]+$gdb_prompt $" { + pass "11.4: test \$trace_file" + } + -re "\\$\[0-9\]+ = \"$srcdir/$subdir/$srcfile\"\[\r\n\]+$gdb_prompt $" { + pass "11.4: test \$trace_file" + } + -re "$gdb_prompt $" { + fail "11.4: test \$trace_file" + } + timeout { + fail "11.4: test \$trace_file (timeout)" + } +} + +#gdb_test "print \$trace_file" "\"$srcdir/$subdir/$srcfile\"" \ +# "11.4: test \$trace_file" + +# +# 12.x test report generation using arbitrary GDB commands, loops etc. +# + +send_gdb "while \$trace_frame != -1\n output \$trace_file\n printf \", line \%d \(tracepoint #\%d\)\\n\", \$trace_line, \$tracepoint\n tfind\n end\n" +gdb_expect { + -re " line $testline1 .tracepoint .$tdp1" { + set linecount1 [expr $linecount1 + 1] + exp_continue + } + -re " line $testline2 .tracepoint .$tdp2" { + set linecount2 [expr $linecount2 + 1] + exp_continue + } + -re " line $testline3 .tracepoint .$tdp3" { + set linecount3 [expr $linecount3 + 1] + exp_continue + } + -re " line $testline4 .tracepoint .$tdp4" { + set linecount4 [expr $linecount4 + 1] + exp_continue + } + -re " line $testline5 .tracepoint .$tdp5" { + set linecount5 [expr $linecount5 + 1] + exp_continue + } + -re " line $testline6 .tracepoint .$tdp6" { + set linecount6 [expr $linecount6 + 1] + exp_continue + } + -re ".*$gdb_prompt $" { + if { ($linecount1 < 4) || ($linecount2 < 4) || ($linecount3 < 4) || ($linecount4 < 4) || ($linecount5 < 4) || ($linecount6 < 4) } { + fail "12.1: trace report #1" + } else { + pass "12.1: trace report #1" + } + } + timeout { + fail "12.1: trace report #1 (timeout)" + } +} + +gdb_tfind_test "12.2: find first TDP #2 frame" "tracepoint $tdp2" \ + "\$tracepoint" "$tdp2" + +set linecount2 0 + +send_gdb "while \$trace_frame != -1\n printf \"tracepoint #\%d, FP 0x\%08x, SP 0x\%08x, PC 0x%08x\\n\", \$tracepoint, \$fp, \$sp, \$pc\n tfind tracepoint\n end\n" +gdb_expect { + -re "tracepoint #$tdp2, FP $hex, SP $hex, PC $hex" { + set linecount2 [expr $linecount2 + 1] + exp_continue + } + -re ".*$gdb_prompt $" { + if { ($linecount2 < 4) } { + fail "12.2: trace report #2" + } else { + pass "12.2: trace report #2" + } + } + timeout { + fail "12.2: trace report #2 (timeout)" + } +} + +gdb_tfind_test "12.3: find first TDP #3 frame" "tracepoint $tdp3" \ + "\$tracepoint" "$tdp3" + +set linecount3 0 + +send_gdb "while \$trace_frame != -1\n printf \"TDP #\%d, frame \%d: depth = \%d, q1 = \%d\\n\", \$tracepoint, \$trace_frame, depth, q1\n tfind tracepoint\n end\n" +gdb_expect { + -re "TDP #$tdp3, frame $decimal: depth = $decimal, q1 = $decimal" { + set linecount3 [expr $linecount3 + 1] + exp_continue + } + -re ".*$gdb_prompt $" { + if { ($linecount3 < 4) } { + fail "12.3: trace report #3" + } else { + pass "12.3: trace report #3" + } + } + timeout { + fail "12.3: trace report #3 (timeout)" + } +} + +gdb_tfind_test "12.4: find first TDP #6 frame" "tracepoint $tdp6" \ + "\$tracepoint" "$tdp6" + +set linecount6 0 + +send_gdb "while \$trace_frame != -1\n printf \"TDP #\%d, frame %d: char_test = \%d, long_test = \%d\\n\", \$tracepoint, \$trace_frame, gdb_char_test, gdb_long_test\n tfind tracepoint\n end\n" +gdb_expect { + -re "TDP #$tdp6, frame $decimal: char_test = $arg1, long_test = $arg3" { + set linecount6 [expr $linecount6 + 1] + exp_continue + } + -re ".*$gdb_prompt $" { + if { ($linecount6 < 4) } { + fail "12.4: trace report #4" + } else { + pass "12.4: trace report #4" + } + } + timeout { + fail "12.4: trace report #4 (timeout)" + } +} + +# Finished! +gdb_tfind_test "finished: make sure not debugging any trace frame" "none" "-1" Index: backtrace.exp =================================================================== --- backtrace.exp (nonexistent) +++ backtrace.exp (revision 840) @@ -0,0 +1,379 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + load_lib "emc-support.exp"; + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; + gdb_test "set remotetimeout 6" "" "" + set timeout 500 + gdb_target_monitor "$binfile" + # Give a TSTOP and ignore errors, to make sure any previous trace is off + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + send_gdb "compare-sections CS\n" + gdb_expect { + -re "MIS-MATCHED.*$gdb_prompt $" { + untested backtrace.exp + return -1 + all tests in this module will fail."; + } + -re ".*$gdb_prompt $" { } + } +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested backtrace.exp + return -1 + } + gdb_load $binfile + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + runto_main +} +gdb_reinitialize_dir $srcdir/$subdir + +# We generously give ourselves one "pass" if we successfully +# detect that this test cannot be run on this target! +if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + +} + +# +# test backtraces in trace frames +# + +set testline1 0 +set testline2 0 +set testline3 0 +set testline4 0 +set testline5 0 +set testline6 0 + +set arg1 1 +set arg2 2 +set arg3 3 +set arg4 4 +set arg5 5 +set arg6 6 + +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } { + fail "Could not find gdb_recursion_test function" + return; +} + +send_gdb "list $baseline, +12\n" +gdb_expect { + -re "\[\r\n\](\[0-9\]+).*gdbtestline 1 " { + set testline1 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+).*gdbtestline 2 " { + set testline2 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+).*gdbtestline 3 " { + set testline3 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+).*gdbtestline 4 " { + set testline4 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+).*gdbtestline 5 " { + set testline5 $expect_out(1,string) + exp_continue + } + -re "\[\r\n\](\[0-9\]+).*gdbtestline 6 " { + set testline6 $expect_out(1,string) + exp_continue + } + -re ".*$gdb_prompt $" { + if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } { + untested backtrace.exp + return -1 +all tests in this module will fail." + } + } + default { + untested backtrace.exp + return -1 +all tests in this module will fail." + } +} + +# +# Setup backtrace experiment. This will involve: +# 1) a tracepoint where nothing is collected +# 2) a tracepoint where only regs are collected +# 3) a tracepoint where regs, locals and args are collected +# 4) a tracepoint where regs plus some amount of stack are collected. +# + +gdb_delete_tracepoints +set tdp2 [gdb_gettpnum $testline2] +set tdp3 [gdb_gettpnum $testline3] +set tdp4 [gdb_gettpnum $testline4] +set tdp5 [gdb_gettpnum $testline5] +set tdp6 [gdb_gettpnum $testline6] +if { $tdp2 <= 0 || $tdp3 <= 0 || \ + $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then { + fail "setting tracepoints failed" + return; +} + +#gdb_trace_setactions "setup TP to collect FP" \ +# "$tdp2" \ +# "collect \$fp" "" +# + +gdb_trace_setactions "8.6: setup TP to collect regs" \ + "$tdp3" \ + "collect \$regs" "^$" + +gdb_trace_setactions "8.6: setup TP to collect regs, args, and locals" \ + "$tdp4" \ + "collect \$regs, \$args, \$locs" "^$" + +gdb_trace_setactions "8.6: setup TP to collect stack mem cast expr" \ + "$tdp6" \ + "collect \$fp, \(\*\(void \*\*\) \(\$sp\)\) @ 64" "^$" + +gdb_test "tstart" "" "" + +if [istarget "m68k-*-elf"] then { + gdb_emclaptop_command "85,$arg1,$arg2,$arg3,$arg4,$arg5,$arg6" + sleep 5 +} else { + gdb_test "break end" "" "" + gdb_test "continue" \ + "Continuing.*Breakpoint $decimal, end.*" \ + "run trace experiment" +} + +gdb_test "tstop" "" "" + +proc gdb_backtrace_tdp_1 { msg } { + global gdb_prompt + + # We are in a trace frame at which we didn't collect anything + # except $PC. Therefore we expect to be able to identify stack + # frame #0, but that's about all. In particular we do not expect + # to be able to display the function's arguments or locals, and we + # do not expect to be able to identify the caller of this function. + + send_gdb "backtrace\n" + gdb_expect { + -re "#0\[\t \]+gdb_recursion_test.*depth=.*$gdb_prompt $" { + pass "$msg" + } + -re ".*$gdb_prompt $" { + fail "$msg" + } + timeout { fail "$msg (timeout)" } + } +} + +proc gdb_backtrace_tdp_2 { msg } { + global gdb_prompt + + # We are in a trace frame at which we collected only the registers + # Therefore we expect to be able to identify stack frame #0, but + # we don't expect to be able to display its args unles they are + # passed in registers (which isn't the case for m68k), and we + # don't expect to be able to identify the caller's stack frame. + + send_gdb "backtrace\n" + gdb_expect { + -re "#0\[\t \]+gdb_recursion_test.*depth=.*$gdb_prompt $" { + pass "$msg" + } + -re ".*$gdb_prompt $" { + fail "$msg" + } + timeout { fail "$msg (timeout)" } + } +} + +proc gdb_backtrace_tdp_3 { msg } { + global gdb_prompt + + # We are in a trace frame at which we collected all registers, all + # arguments and all locals. This means that the display of + # stack frame #0 should be complete (including argument values). + + send_gdb "backtrace\n" + gdb_expect { + -re "#0\[\t \]+gdb_recursion_test.*depth=\[0-9\]+.*q1=\[0-9\]+.*q2=\[0-9\]+.*q3=\[0-9\]+.*q4=\[0-9\]+.*q5=\[0-9\]+.*q6=\[0-9\]+.*$gdb_prompt $" { + pass "$msg" + } + -re "#0\[\t \]+gdb_recursion_test.*depth=Cannot access.*$gdb_prompt $" { + fail "$msg (failed to collect arguments)" + } + -re ".*$gdb_prompt $" { + fail "$msg" + } + timeout { fail "$msg (timeout)" } + } +} + +proc gdb_backtrace_tdp_4 { msg depth } { + global gdb_prompt + + # We are in a trace frame at which we collected all registers, + # plus a sizeable hunk of stack memory. This should enable us to + # display at least several stack frames worth of backtrace. We'll + # assume that if we can't display at least "depth" levels (with + # args), it counts as an error. + + send_gdb "backtrace\n" + gdb_expect { + -re "#$depth\[\t \].*gdb_recursion_test.*depth=\[0-9\]+.*q1=\[0-9\]+.*q2=\[0-9\]+.*q3=\[0-9\]+.*q4=\[0-9\]+.*q5=\[0-9\]+.*q6=\[0-9\]+.*$gdb_prompt $" { + pass "$msg" + } + -re "#$depth\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" { + fail "$msg (args missing from #$depth stack frame)" + } + -re "#\[0-9\]+\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" { + fail "$msg (fewer than $depth stack frames found)" + } + -re ".*$gdb_prompt $" { + fail "$msg" + } + timeout { fail "$msg (timeout)" } + } +} + +# +# begin backtrace test +# + +set timeout 60 + +gdb_tfind_test "init: make sure not debugging any trace frame" "none" "-1" + +gdb_tfind_test "8.6: find start frame" "start" "0" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp2:" "" +gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 1, collect nothing" + +gdb_tfind_test "8.6: find frame 1" "1" "1" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp3:" "" +gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 1, collect regs" + +gdb_tfind_test "8.6: find frame 2" "2" "2" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp4:" "" +gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 1, collect args and locals" + + +gdb_tfind_test "8.6: find frame 4" "4" "4" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp6:" "" +gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" + +gdb_tfind_test "8.6: find frame 5" "5" "5" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp2:" "" +gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 2, collect nothing" + +gdb_tfind_test "8.6: find frame 6" "6" "6" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp3:" "" +gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 2, collect regs" + +gdb_tfind_test "8.6: find frame 7" "7" "7" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp4:" "" +gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 2, collect args and locals" + + +gdb_tfind_test "8.6: find frame 9" "9" "9" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp6:" "" +gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" + +gdb_tfind_test "8.6: find frame 10" "10" "10" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp2:" "" +gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 3, collect nothing" + +gdb_tfind_test "8.6: find frame 11" "11" "11" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp3:" "" +gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 3, collect regs" + +gdb_tfind_test "8.6: find frame 12" "12" "12" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp4:" "" +gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 3, collect args and locals" + + +gdb_tfind_test "8.6: find frame 14" "14" "14" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp6:" "" +gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" + +gdb_tfind_test "8.6: find frame 15" "15" "15" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp2:" "" +gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 4, collect nothing" + +gdb_tfind_test "8.6: find frame 16" "16" "16" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp3:" "" +gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 4, collect regs" + +gdb_tfind_test "8.6: find frame 17" "17" "17" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp4:" "" +gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 4, collect args and locals" + + +gdb_tfind_test "8.6: find frame 19" "19" "19" +gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ + "TDP $tdp6:" "" +gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" + +gdb_test "printf \"x \%d x\\n\", depth == 3" \ + "x 0 x" \ + "1.13: trace in recursion: depth not equal to 3" + +# Finished! +gdb_test "tfind none" "" "" Index: passcount.exp =================================================================== --- passcount.exp (nonexistent) +++ passcount.exp (revision 840) @@ -0,0 +1,178 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start +if [istarget "m68k-*-elf"] then { + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested passcount.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} + +set testline1 [expr $baseline + 3] + +# +# test "passcount" command +# + +gdb_delete_tracepoints +set trcpt1 [gdb_gettpnum gdb_c_test]; +set trcpt2 [gdb_gettpnum gdb_asm_test]; +set trcpt3 [gdb_gettpnum $testline1]; +if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then { + fail "setting tracepoints" + return; +} + +# 4.1 passcount of specified tracepoint + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \ + "4.1a: set three tracepoints, passcounts all zero" + +gdb_test "passcount 2 $trcpt1" \ + "Setting tracepoint $trcpt1.s passcount to 2" \ + "4.1b: set 1st tracepoint's passcount to two" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \ + "4.1c: verify 1st tracepoint's passcount set to two" + +gdb_test "passcount 4 $trcpt2" \ + "Setting tracepoint $trcpt2.s passcount to 4" \ + "4.1d: set 2nd tracepoint's passcount to four" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \ + "4.1c: verify 2nd tracepoint's passcount set to four" + +# 4.2 passcount of last (default) tracepoint + +gdb_test "passcount 6" \ + "Setting tracepoint $trcpt3.s passcount to 6" \ + "4.2b: set last (default) tp's passcount to six" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+6\[\t \]+.*in gdb_recursion_test.*" \ + "4.2b: verify last (default) tp's passcount set to six" + +# 4.3 run until stopped explicitly by user +# [deferred to dynamic test section] + +# 4.4 reset the previously set passcounts to new values + +gdb_test "passcount 7" \ + "Setting tracepoint $trcpt3.s passcount to 7" \ + "4.4a: reset last (default) tp's passcount to seven" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+7\[\t \]+.*in gdb_recursion_test.*" \ + "4.4a: verify reset last (default) tp's passcount to seven" + +gdb_test "passcount 5 $trcpt2" \ + "Setting tracepoint $trcpt2.s passcount to 5" \ + "4.4b: reset second tracepoint's passcount to five" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+5\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+7\[\t \]+.*in gdb_recursion_test.*" \ + "4.4c: verify reset second tracepoint's passcount to five" + +# 4.20 passcount for "all" + +gdb_test "passcount 3 all" \ + ".*$trcpt1.s pass.* 3.*$trcpt2.s pass.* 3.*$trcpt3.s pass.* 3" \ + "4.20a: set all three passcounts to three" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*in gdb_recursion_test.*" \ + "4.20a: set all three passcounts to three" + +gdb_test "passcount 4 all" \ + ".*$trcpt1.s pass.* 4.*$trcpt2.s pass.* 4.*$trcpt3.s pass.* 4" \ + "4.20a: reset all three passcounts to four" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \ + "4.20b: reset all three passcounts to four" + +# 4.5 Verify trace stops on first "satisfied" passcount +# [deferred to dynamic test section] + +# 4.6 minimum passcount boundary condition + +gdb_test "passcount 0 $trcpt1" \ + "Setting tracepoint $trcpt1.s passcount to 0" \ + "4.6: set passcount to zero" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \ + "4.6: set passcount to zero" + +# 4.7 (test a very large passcount) + +gdb_test "passcount 32767 $trcpt1" \ + "Setting tracepoint $trcpt1.s passcount to 32767" \ + "4.7: set passcount to large number (32767)" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+32767\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \ + "4.7: set passcount to large number (32767)" + +# 4.8 set passcount for invalid tracepoint + +gdb_test "passcount 1 [expr $trcpt2 + $trcpt3]" \ + "No tracepoint number [expr $trcpt2 + $trcpt3]." \ + "4.8: invalid tracepoint number in passcount" + +# 4.9 help passcount +gdb_test "help passcount" "Set the passcount for a tracepoint.*" \ + "4.9: help passcount" + Index: circ.exp =================================================================== --- circ.exp (nonexistent) +++ circ.exp (revision 840) @@ -0,0 +1,215 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +if [istarget "m68k-*-elf"] then { + pass "Test not supported on this target" + return; +} + +load_lib "trace-support.exp" + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +set testfile "circ" +set srcfile ${testfile}.c +set binfile $objdir/$subdir/$testfile + +if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested circ.exp + return -1 +} + +# Tests: +# 1) Set up a trace experiment that will collect approximately 10 frames, +# requiring more than 512 but less than 1024 bytes of cache buffer. +# (most targets should have at least 1024 bytes of cache buffer!) +# Run and confirm that it collects all 10 frames. +# 2) Artificially limit the trace buffer to 512 bytes, and rerun the +# experiment. Confirm that the first several frames are collected, +# but that the last several are not. +# 3) Set trace buffer to circular mode, still with the artificial limit +# of 512 bytes, and rerun the experiment. Confirm that the last +# several frames are collected, but the first several are not. +# + +# return 0 for success, 1 for failure +proc run_trace_experiment { pass } { + gdb_run_cmd + + if [gdb_test "tstart" \ + "\[\r\n\]*" \ + "start trace experiment, pass $pass"] then { return 1; } + if [gdb_test "continue" \ + "Continuing.*Breakpoint \[0-9\]+, end.*" \ + "run to end, pass $pass"] then { return 1; } + if [gdb_test "tstop" \ + "\[\r\n\]*" \ + "stop trace experiment, pass $pass"] then { return 1; } + return 0; +} + +# return 0 for success, 1 for failure +proc set_a_tracepoint { func } { + if [gdb_test "trace $func" \ + "Tracepoint \[0-9\]+ at .*" \ + "set tracepoint at $func"] then { + return 1; + } + if [gdb_trace_setactions "set actions for $func" \ + "" \ + "collect testload" "^$"] then { + return 1; + } + return 0; +} + +# return 0 for success, 1 for failure +proc setup_tracepoints { } { + gdb_delete_tracepoints + if [set_a_tracepoint func0] then { return 1; } + if [set_a_tracepoint func1] then { return 1; } + if [set_a_tracepoint func2] then { return 1; } + if [set_a_tracepoint func3] then { return 1; } + if [set_a_tracepoint func4] then { return 1; } + if [set_a_tracepoint func5] then { return 1; } + if [set_a_tracepoint func6] then { return 1; } + if [set_a_tracepoint func7] then { return 1; } + if [set_a_tracepoint func8] then { return 1; } + if [set_a_tracepoint func9] then { return 1; } + return 0; +} + +# return 0 for success, 1 for failure +proc trace_buffer_normal { } { + if [gdb_test "maint packet QTBuffer:size:ffffffff" \ + "received: .OK." ""] then { + pass "This test cannot be run on this target" + return 1; + } + if [gdb_test "maint packet QTBuffer:circular:0" \ + "received: .OK." ""] then { + pass "This test cannot be run on this target" + return 1; + } + return 0; +} + +# return 0 for success, 1 for failure +proc gdb_trace_circular_tests { } { + + # We generously give ourselves one "pass" if we successfully + # detect that this test cannot be run on this target! + if { ![gdb_target_supports_trace] } then { + pass "Current target does not support trace" + return 1; + } + + if [trace_buffer_normal] then { return 1; } + + gdb_test "break begin" "" "" + gdb_test "break end" "" "" + gdb_test "tstop" "" "" + gdb_test "tfind none" "" "" + + if [setup_tracepoints] then { return 1; } + + # First, run the trace experiment with default attributes: + # Make sure it behaves as expected. + if [run_trace_experiment 1] then { return 1; } + if [gdb_test "tfind start" \ + "#0 func0 .*" \ + "find frame zero, pass 1"] then { return 1; } + + if [gdb_test "tfind 9" \ + "#0 func9 .*" \ + "find frame nine, pass 1"] then { return 1; } + + if [gdb_test "tfind none" \ + "#0 end .*" \ + "quit trace debugging, pass 1"] then { return 1; } + + # Then, shrink the trace buffer so that it will not hold + # all ten trace frames. Verify that frame zero is still + # collected, but frame nine is not. + if [gdb_test "maint packet QTBuffer:size:200" \ + "received: .OK." "shrink the target trace buffer"] then { + return 1; + } + if [run_trace_experiment 2] then { return 1; } + if [gdb_test "tfind start" \ + "#0 func0 .*" \ + "find frame zero, pass 2"] then { return 1; } + + if [gdb_test "tfind 9" \ + ".* failed to find .*" \ + "fail to find frame nine, pass 2"] then { return 1; } + + if [gdb_test "tfind none" \ + "#0 end .*" \ + "quit trace debugging, pass 2"] then { return 1; } + + # Finally, make the buffer circular. Now when it runs out of + # space, it should wrap around and overwrite the earliest frames. + # This means that: + # 1) frame zero will be overwritten and therefore unavailable + # 2) the earliest frame in the buffer will be other-than-zero + # 3) frame nine will be available (unlike on pass 2). + if [gdb_test "maint packet QTBuffer:circular:1" \ + "received: .OK." "make the target trace buffer circular"] then { + return 1; + } + if [run_trace_experiment 3] then { return 1; } + if [gdb_test "tfind start" \ + "#0 func\[1-9\] .*" \ + "first frame is NOT frame zero, pass 3"] then { return 1; } + + if [gdb_test "tfind 9" \ + "#0 func9 .*" \ + "find frame nine, pass 3"] then { return 1; } + + if [gdb_test "tfind none" \ + "#0 end .*" \ + "quit trace debugging, pass 3"] then { return 1; } + + return 0; +} + +# Start with a fresh gdb. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load $binfile + +if [target_info exists gdb_stub] { + gdb_step_for_stub; +} +# Body of test encased in a proc so we can return prematurely. +if { ![gdb_trace_circular_tests] } then { + # Set trace buffer attributes back to normal + trace_buffer_normal; +} + +# Finished! +gdb_test "tfind none" "" "" Index: collection.c =================================================================== --- collection.c (nonexistent) +++ collection.c (revision 840) @@ -0,0 +1,280 @@ +/* + * Test program for trace collection + */ + +/* + * Typedefs + */ + +typedef struct TEST_STRUCT { + char memberc; + int memberi; + float memberf; + double memberd; +} test_struct; + +typedef int test_array [4]; + +/* + * Global variables to be collected + */ + +char globalc; +int globali; +float globalf; +double globald; +test_struct globalstruct; +test_struct *globalp; +int globalarr[16]; + +/* + * Additional globals used in arithmetic tests + */ + +signed char c0, c1, c2, c3, c4, c5, c6, c7, + c8, c9, c10, c11, c12, c13, c14, c15, cminus; +signed short s0, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s11, s12, s13, s14, s15, sminus; +signed long l0, l1, l2, l3, l4, l5, l6, l7, + l8, l9, l10, l11, l12, l13, l14, l15, lminus; + + +/* + * Test functions + */ + +static void begin () /* called before anything else */ +{ +} + +static void end () /* called after everything else */ +{ +} + +/* Test collecting args. */ +int args_test_func (argc, argi, argf, argd, argstruct, argarray) + char argc; + int argi; + float argf; + double argd; + test_struct argstruct; + int argarray[4]; +{ + int i; + + i = (int) argc + argi + argf + argd + argstruct.memberi + argarray[1]; + + return i; +} + +/* Test collecting struct args. */ +int argstruct_test_func (argstruct) + test_struct argstruct; +{ + return (int) argstruct.memberc + argstruct.memberi + + argstruct.memberf + argstruct.memberd; +} + +/* Test collecting array args. */ +int argarray_test_func (argarray) + int argarray[4]; +{ + return (int) argarray[0] + argarray[1] + argarray[2] + argarray[3]; +} + + + +int local_test_func () /* test collecting locals */ +{ + char locc = 11; + int loci = 12; + float locf = 13.3; + double locd = 14.4; + test_struct locst; + int locar[4]; + int i; + + locst.memberc = 15; + locst.memberi = 16; + locst.memberf = 17.7; + locst.memberd = 18.8; + locar[0] = 121; + locar[1] = 122; + locar[2] = 123; + locar[3] = 124; + + i = /* Set_Tracepoint_Here */ + (int) locc + loci + locf + locd + locst.memberi + locar[1]; + + return i; +} + +int reglocal_test_func () /* test collecting register locals */ +{ + register char locc = 11; + register int loci = 12; + register float locf = 13.3; + register double locd = 14.4; + register test_struct locst; + register int locar[4]; + int i; + + locst.memberc = 15; + locst.memberi = 16; + locst.memberf = 17.7; + locst.memberd = 18.8; + locar[0] = 121; + locar[1] = 122; + locar[2] = 123; + locar[3] = 124; + + i = /* Set_Tracepoint_Here */ + (int) locc + loci + locf + locd + locst.memberi + locar[1]; + + return i; +} + +int statlocal_test_func () /* test collecting static locals */ +{ + static char locc; + static int loci; + static float locf; + static double locd; + static test_struct locst; + static int locar[4]; + int i; + + locc = 11; + loci = 12; + locf = 13.3; + locd = 14.4; + locst.memberc = 15; + locst.memberi = 16; + locst.memberf = 17.7; + locst.memberd = 18.8; + locar[0] = 121; + locar[1] = 122; + locar[2] = 123; + locar[3] = 124; + + i = /* Set_Tracepoint_Here */ + (int) locc + loci + locf + locd + locst.memberi + locar[1]; + + /* Set static locals back to zero so collected values are clearly special. */ + locc = 0; + loci = 0; + locf = 0; + locd = 0; + locst.memberc = 0; + locst.memberi = 0; + locst.memberf = 0; + locst.memberd = 0; + locar[0] = 0; + locar[1] = 0; + locar[2] = 0; + locar[3] = 0; + + return i; +} + + +int globals_test_func () +{ + int i = 0; + + i += globalc + globali + globalf + globald; + i += globalstruct.memberc + globalstruct.memberi; + i += globalstruct.memberf + globalstruct.memberd; + i += globalarr[1]; + + return i; /* Set_Tracepoint_Here */ +} + +int +main (argc, argv, envp) + int argc; + char *argv[], **envp; +{ + int i = 0; + test_struct mystruct; + int myarray[4]; + +#ifdef usestubs + set_debug_traps (); + breakpoint (); +#endif + + begin (); + /* Assign collectable values to global variables. */ + l0 = s0 = c0 = 0; l1 = s1 = c1 = 1; + l2 = s2 = c2 = 2; l3 = s3 = c3 = 3; + l4 = s4 = c4 = 4; l5 = s5 = c5 = 5; + l6 = s6 = c6 = 6; l7 = s7 = c7 = 7; + l8 = s8 = c8 = 8; l9 = s9 = c9 = 9; + l10 = s10 = c10 = 10; l11 = s11 = c11 = 11; + l12 = s12 = c12 = 12; l13 = s13 = c13 = 13; + l14 = s14 = c14 = 14; l15 = s15 = c15 = 15; + lminus = sminus = cminus = -2; + globalc = 71; + globali = 72; + globalf = 73.3; + globald = 74.4; + globalstruct.memberc = 81; + globalstruct.memberi = 82; + globalstruct.memberf = 83.3; + globalstruct.memberd = 84.4; + globalp = &globalstruct; + + for (i = 0; i < 15; i++) + globalarr[i] = i; + + mystruct.memberc = 101; + mystruct.memberi = 102; + mystruct.memberf = 103.3; + mystruct.memberd = 104.4; + myarray[0] = 111; + myarray[1] = 112; + myarray[2] = 113; + myarray[3] = 114; + + /* Call test functions, so they can be traced and data collected. */ + i = 0; + i += args_test_func (1, 2, 3.3, 4.4, mystruct, myarray); + i += argstruct_test_func (mystruct); + i += argarray_test_func (myarray); + i += local_test_func (); + i += reglocal_test_func (); + i += statlocal_test_func (); + i += globals_test_func (); + + /* Values of globals at end of test should be different from + values that they had when trace data was captured. */ + + l0 = s0 = c0 = 0; l1 = s1 = c1 = 0; + l2 = s2 = c2 = 0; l3 = s3 = c3 = 0; + l4 = s4 = c4 = 0; l5 = s5 = c5 = 0; + l6 = s6 = c6 = 0; l7 = s7 = c7 = 0; + l8 = s8 = c8 = 0; l9 = s9 = c9 = 0; + l10 = s10 = c10 = 0; l11 = s11 = c11 = 0; + l12 = s12 = c12 = 0; l13 = s13 = c13 = 0; + l14 = s14 = c14 = 0; l15 = s15 = c15 = 0; + lminus = sminus = cminus = 0; + + /* Set 'em back to zero, so that the collected values will be + distinctly different from the "realtime" (end of test) values. */ + + globalc = 0; + globali = 0; + globalf = 0; + globald = 0; + globalstruct.memberc = 0; + globalstruct.memberi = 0; + globalstruct.memberf = 0; + globalstruct.memberd = 0; + globalp = 0; + for (i = 0; i < 15; i++) + globalarr[i] = 0; + + end (); + return 0; +}
collection.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: tracecmd.exp =================================================================== --- tracecmd.exp (nonexistent) +++ tracecmd.exp (revision 840) @@ -0,0 +1,169 @@ +# Copyright 1998, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start +if [istarget "m68k-*-elf"] then { + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested tracecmd.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} + +set testline1 [expr $baseline + 1] +set testline2 [expr $baseline + 3] + +# +# test "help tracepoints" +# + +set helpcnt 0; +test_class_help "tracepoints" { + "Tracing of program execution without stopping the program\.[\r\n\]+" +} "1.0: help tracepoints" + +# +# test trace command: +# + +# 1.1 trace source line +gdb_delete_tracepoints +gdb_test "trace $srcfile:$testline2" \ + "Tracepoint $decimal at $hex: file.*$srcfile, line $testline2." \ + "1.1a: set tracepoint at sourceline" +gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline2" \ + "1.1b: trace sourcefile:line" + +# 1.2 trace invalid source line +gdb_delete_tracepoints +gdb_test "trace $srcfile:99999" "No line 99999 in file \".*$srcfile\"." \ + "1.2a: trace invalid line in sourcefile" +gdb_test "info trace" "No tracepoints.*" \ + "1.2b: reject invalid line in srcfile" + +# 1.3 trace line in invalid source file +gdb_delete_tracepoints +gdb_test "trace NoSuChFiLe.c:1" "No source file named NoSuChFiLe.c." \ + "1.3a: trace invalid source file" +gdb_test "info trace" "No tracepoints.*" \ + "1.3b: reject invalid srcfile" + +# 1.4 trace function by name +gdb_delete_tracepoints +gdb_test "trace gdb_recursion_test" \ + "Tracepoint $decimal at $hex: file.*$srcfile, line $testline1." \ + "1.4a: trace function by name" +gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline1" \ + "1.4b: trace function by name" + +# 1.5 trace non-existant function +gdb_delete_tracepoints +gdb_test "trace NoSuChFuNc" "Function \"NoSuChFuNc\" not defined." \ + "1.5a: trace invalid function" +gdb_test "info trace" "No tracepoints.*" \ + "1.5b: reject invalid srcfile" + +# 1.6 trace at a specific address +# Collect the address of "gdb_asm_test", and use that. +send_gdb "print gdb_asm_test\n" +gdb_expect { + -re "\[$\]\[0-9\].*0x(\[0-9a-fA-F\]+).*$gdb_prompt $" { + set asm_test_addr $expect_out(1,string) + } + timeout { } +} + +gdb_delete_tracepoints +gdb_test "trace \*0x$asm_test_addr" \ + "Tracepoint $decimal at .*$asm_test_addr.*" \ + "1.6a: trace at specific address" +gdb_test "info trace" "$asm_test_addr.*gdb_asm_test.*" \ + "1.6b: verify trace at specific address" + +# 1.7 trace at function's exact address +# Collect the address of the function for comparison +send_gdb "print gdb_recursion_test\n" +gdb_expect { + -re "\[$\]\[0-9\].*0x(\[0-9a-fA-F\]+).*$gdb_prompt $" { + set c_test_addr $expect_out(1,string) + } + timeout { } +} + +gdb_delete_tracepoints +gdb_test "trace \*gdb_recursion_test" \ + "Tracepoint $decimal at .*$c_test_addr.*" \ + "1.7a: trace at function label (before prologue)" +gdb_test "info trace" "$c_test_addr.*in gdb_recursion_test.*:$baseline" \ + "1.7b: verify trace at specific address" + +# 1.8 trace at invalid address +# no address is invalid + +# 1.9 trace no arguments +gdb_test "trace" "trace command requires an argument" \ + "1.9: trace " + +# 1.10 set large number of tracepoints +# deferred to limits test module + +# 1.11 tracepoint conditions +# conditions on tracepoints not implemented + +# 1.12 set tracepoint in prologue +# [see tfind.exp] + +# 1.13 trace on recursion +# interesting only in "live" session: see backtrace.exp for live test. + +# 1.14 help trace +gdb_test "help trace" "Set a tracepoint at .*" "1.14: help trace" + + Index: deltrace.exp =================================================================== --- deltrace.exp (nonexistent) +++ deltrace.exp (revision 840) @@ -0,0 +1,269 @@ +# Copyright 1998, 1999, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Michael Snyder (msnyder@cygnus.com) + +load_lib "trace-support.exp"; + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +gdb_exit +gdb_start + +if [istarget "m68k-*-elf"] then { + set srcfile gdb_c_test.c + set binfile [board_info target d490_binfile]; +} else { + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/$testfile + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested deltrace.exp + return -1 + } +} +gdb_reinitialize_dir $srcdir/$subdir + +# If testing on a remote host, download the source file. +# remote_download host $srcdir/$subdir/$srcfile + +gdb_file_cmd $binfile + +# define relative source line numbers: +# all subsequent line numbers are relative to this first one (baseline) +set baseline [gdb_find_recursion_test_baseline $srcfile]; +if { $baseline == -1 } then { + fail "Could not find gdb_recursion_test function" + return; +} +set testline1 [expr $baseline + 4] + +# +# test "delete tracepoints" command +# + +# 3.1 delete tracepoints (all) +gdb_delete_tracepoints +gdb_test "trace gdb_c_test" "Tracepoint \[0-9\]+ at .*" "set tracepoint 1" +gdb_test "trace gdb_asm_test" "Tracepoint \[0-9\]+ at .*" "set tracepoint 2" +gdb_test "trace $testline1" "Tracepoint \[0-9\]+ at .*" "set tracepoint 3" + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_recursion_test.*" \ + "3.1a: set three tracepoints" + +send_gdb "delete tracepoints\n" +gdb_expect 30 { + -re "Delete all tracepoints.*y or n.*$" { + send_gdb "y\n" + gdb_expect 30 { + -re "$gdb_prompt $" { + pass "3.1b: delete all tracepoints" + } + timeout { fail "3.1b: delete all tracepoints (timeout)" } + } + } + -re "$gdb_prompt $" { # This should only happen if there are no tracepoints + fail "3.1b: delete all tracepoints (no tracepoints?)" + } + timeout { fail "3.1b: delete all tracepoints (timeout)" } +} + +# 3.2 delete tracepoint +gdb_delete_tracepoints +set trcpt1 [gdb_gettpnum gdb_c_test]; +set trcpt2 [gdb_gettpnum gdb_asm_test]; +set trcpt3 [gdb_gettpnum $testline1]; +if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then { + fail "setting tracepoints" + return; +} + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in.*gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in.*gdb_recursion_test.*" \ + "3.2a: set three tracepoints" + +#gdb_test "delete tracepoint $trcpt1" "" "" +send_gdb "delete tracepoint $trcpt1\n" +gdb_expect { + -re "No tracepoint number.*$gdb_prompt $" { + fail "3.2b: delete first tracepoint" + } + -re ".*\[Ee\]rror.*$gdb_prompt $" { + fail "3.2b: delete first tracepoint" + } + -re "$gdb_prompt $" { + pass "3.2b: delete first tracepoint" + } + timeout { + fail "3.2b: delete first tracepoint (timeout)" + } +} + +send_gdb "info tracepoints\n" +gdb_expect { + -re "$trcpt1\[\t \]+y\[\t \]+0x.*in.*gdb_c_test.*$gdb_prompt $" { + fail "3.2c: verify delete first tracepoint (argh)" + } + -re "$trcpt2\[\t \]+y.*gdb_asm_test.*\[\r\n\t ]+$trcpt3\[\t \]+y.* in gdb_recursion_test at .*$gdb_prompt $" { + pass "3.2c: verify delete first tracepoint" + } + -re ".*$gdb_prompt $" { + fail "3.2c: verify delete first tracepoint (mumble)" + } + timeout { + fail "3.2c: verify delete first tracepoint (timeout)" + } +} + +#gdb_test "delete tracepoint $trcpt2" "" "" +send_gdb "delete tracepoint $trcpt2\n" +gdb_expect { + -re "No tracepoint number.*$gdb_prompt $" { + fail "3.2d: delete second tracepoint" + } + -re ".*\[Ee\]rror.*$gdb_prompt $" { + fail "3.2d: delete second tracepoint" + } + -re "$gdb_prompt $" { + pass "3.2d: delete second tracepoint" + } + timeout { + fail "3.2d: delete second tracepoint (timeout)" + } +} + +send_gdb "info tracepoints\n" +gdb_expect { + -re "$trcpt1\[\t \]+y\[\t \]+0x.*in.*gdb_c_test.*$gdb_prompt $" { + fail "3.2e: verify delete second tracepoint" + } + -re "$trcpt2\[\t \]+y\[\t \]+0x.*in gdb_asm_test.*$gdb_prompt $" { + fail "3.2e: verify delete second tracepoint" + } + -re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" { + pass "3.2e: verify delete second tracepoint" + } + -re "$gdb_prompt $" { + fail "3.2e: verify delete second tracepoint" + } + timeout { + fail "3.2e: verify delete second tracepoint (timeout)" + } +} + +#gdb_test "delete tracepoint $trcpt3" "" "" +send_gdb "delete tracepoint $trcpt3\n" +gdb_expect { + -re "No tracepoint number.*$gdb_prompt $" { + fail "3.2f: delete third tracepoint" + } + -re ".*\[Ee\]rror.*$gdb_prompt $" { + fail "3.2f: delete third tracepoint" + } + -re "$gdb_prompt $" { + pass "3.2f: delete third tracepoint" + } + timeout { + fail "3.2f: delete third tracepoint (timeout)" + } +} + +# send_gdb "ARF! \\n\n" +send_gdb "info tracepoints\n" +gdb_expect { + -re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" { + fail "3.2g: verify delete third tracepoint" + } + -re "$gdb_prompt $" { + pass "3.2g: verify delete third tracepoint" + } + timeout { + fail "3.2g: verify delete third tracepoint (timeout)" + } +} + +# 3.3 delete three tracepoints at once +gdb_delete_tracepoints +set trcpt1 [gdb_gettpnum gdb_c_test]; +set trcpt2 [gdb_gettpnum gdb_asm_test]; +set trcpt3 [gdb_gettpnum $testline1]; +if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then { + fail "setting tracepoints" + return; +} + +gdb_test "info tracepoints" \ + "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_recursion_test.*" \ + "3.3a: set three tracepoints" + +#gdb_test "delete tracepoint $trcpt1 $trcpt2 $trcpt3" "" "" +send_gdb "delete tracepoint $trcpt1 $trcpt2 $trcpt3\n" +gdb_expect { + -re "No tracepoint number.*$gdb_prompt $" { + fail "3.3b: delete three tracepoints" + } + -re ".*\[Ee\]rror.*$gdb_prompt $" { + fail "3.3b: delete three tracepoints" + } + -re "$gdb_prompt $" { + pass "3.3b: delete three tracepoints" + } + timeout { + fail "3.3b: delete three tracepoint (timeout)" + } +} + +send_gdb "info tracepoints\n" +gdb_expect { + -re "$trcpt1\[\t \]+y\[\t \]+0x.*in gdb_c_test.*$gdb_prompt $" { + fail "3.3c: verify delete three tracepoints (first one persists)" + } + -re "$trcpt2\[\t \]+y\[\t \]+0x.*in gdb_asm_test.*$gdb_prompt $" { + fail "3.3c: verify delete three tracepoints (second one persists)" + } + -re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" { + fail "3.3c: verify delete three tracepoints (third one persists)" + } + -re "$gdb_prompt $" { + pass "3.3c: verify delete three tracepoints" + } + timeout { + fail "3.3c: verify delete three tracepoints (timeout)" + } +} + +# 3.4 delete invalid tracepoint number +gdb_test "delete tracepoint [expr $trcpt2 + $trcpt3]" \ + "No tracepoint number [expr $trcpt2 + $trcpt3]." \ + "3.4: delete invalid tracepoint number" + +# 3.5 delete tracepoint number zero +gdb_test "delete tracepoint 0" "bad tracepoint number at or near '0'" \ + "3.5: delete tracepoint number zero" + +# 3.6 help delete tracepoints +gdb_test "help delete tracepoints" \ + "Delete specified tracepoints.*" \ + "3.6: help delete tracepoints"

powered by: WebSVN 2.1.0

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