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 *) ®s, |
(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, ®no ) && *(request++) == '=' ) |
{ |
if ( regno < NUMREGS ) |
{ |
hexToInt( &request, |
(unsigned long *) ®isters[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, ®num); |
|
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, ®s, &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"