📄 gdb-fileio.c
字号:
/*==========================================================================
//
// gdb-fileio.c
//
// Implementation of File I/O using the GDB remote protocol
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jlarmour
// Contributors:
// Date: 2002-04-09
// Purpose: Implementation of File I/O using the GDB remote
// protocol
// Description: 'F' packet requests are of the form:
// F<name>[,<parameter>]...
// where name is the ASCII syscall name, and the
// parameters are generally included as hex ints,
// in ASCII.
//
//####DESCRIPTIONEND####
//========================================================================*/
/* CONFIGURATION */
#include <pkgconf/hal.h>
/* HEADERS */
#include <stddef.h> // size_t
#include <cyg/infra/cyg_type.h>
#ifdef CYGPKG_ISOINFRA
# include <pkgconf/isoinfra.h>
# include <string.h>
#endif
#include "board.h" // sets correct definitions for generic stub header
#include <cyg/hal/generic-stub.h>
#include "gdb-fileio.h"
/* TYPES */
// this is used by newlib's mode_t so we should match it
#ifdef __GNUC__
#define _ST_INT32 __attribute__ ((__mode__ (__SI__)))
#else
#define _ST_INT32
#endif
typedef int newlib_int_t;
typedef unsigned int newlib_uint_t;
typedef long newlib_long_t;
typedef long newlib_time_t;
typedef unsigned int newlib_mode_t _ST_INT32;
typedef short newlib_dev_t;
typedef unsigned short newlib_uid_t;
typedef unsigned short newlib_gid_t;
typedef unsigned short newlib_ino_t;
typedef unsigned short newlib_nlink_t;
typedef long newlib_off_t;
struct newlib_timeval {
newlib_time_t tv_sec;
newlib_long_t tv_usec;
};
struct newlib_stat
{
newlib_dev_t st_dev;
newlib_ino_t st_ino;
newlib_mode_t st_mode;
newlib_nlink_t st_nlink;
newlib_uid_t st_uid;
newlib_gid_t st_gid;
newlib_dev_t st_rdev;
newlib_off_t st_size;
// We assume we've been compiled with the same flags as newlib here
#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
newlib_time_t st_atime;
newlib_time_t st_mtime;
newlib_time_t st_ctime;
#else
newlib_time_t st_atime;
newlib_long_t st_spare1;
newlib_time_t st_mtime;
newlib_long_t st_spare2;
newlib_time_t st_ctime;
newlib_long_t st_spare3;
newlib_long_t st_blksize;
newlib_long_t st_blocks;
newlib_long_t st_spare4[2];
#endif
};
/* EXTERNS */
__externC char __remcomInBuffer[]; // from generic-stub.c, for packet data
__externC char __remcomOutBuffer[]; // ditto
/* STATICS/GLOBALS */
static int __fileio_retcode, __fileio_errno;
static cyg_bool __fileio_retcode_set, __fileio_errno_set, __fileio_ctrlc_set;
/* MACROS */
// endian independent conversion functions from big endian protocol types
// to newlib types
#define GDBFILEIO_FIO_TO_NEWLIB( _f, _n, _ftype ) \CYG_MACRO_START \ char *_cf = (char *)(_f); \ int _i; \ char _sign = 0; \ if (*_cf == '-') { \ _sign = 1; \ _cf++; \ } \ (_n) = 0; \ for (_i=0; _i<sizeof(_ftype); _i++) { \ (_n) = ((_n) << 8) | _cf[_i]; \ } \ if (_sign) \ (_n) = -(_n); \CYG_MACRO_END
#define GDBABS(_x_) (((_x_) < 0) ? (-(_x_)) : (_x_))
#define GDBFILEIO_NEWLIB_TO_FIO( _f, _n, _ftype ) \CYG_MACRO_START \ char *_cf = (char *)(_f); \ int _i = 0; \ if ((_n) < 0) \ _cf[_i++] = '-'; \ for (; _i<sizeof(_ftype); _i++) { \ _cf[_i] = ((GDBABS(_n)) >> 8*(sizeof(_ftype)-_i-1)) & 0xff; \ } \CYG_MACRO_END
/* FUNCTIONS */
#ifndef CYGINT_ISO_STRING_STRFUNCS
static size_t strlen( const char *s )
{
size_t retval;
const char *start = s;
while (*s)
s++;
retval = s - start;
return retval;
}
#endif
static int
chars_to_hex( char *charsin, char *hexout, int bytes )
{
int numChars = 0;
int allzero = true;
while (bytes--) {
if (0 != *charsin)
allzero = false;
*hexout++ = __tohex( (*charsin / 16) & 15 );
*hexout++ = __tohex( (*charsin++) & 15 );
numChars += 2;
}
if (allzero) // doesn't matter if we actually set more than needed above
return (numChars > 2 ? 2 : numChars);
return numChars;
}
static void
gdbfileio_fio_to_newlib_time_t( fio_time_t *f, newlib_time_t *n )
{
GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_time_t );
} // gdbfileio_fio_to_newlib_time_t()
static void
gdbfileio_newlib_to_fio_int_t( newlib_int_t *n, fio_int_t *f )
{
GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_int_t );
} // gdbfileio_newlib_to_fio_int_t()
static void
gdbfileio_newlib_to_fio_uint_t( newlib_uint_t *n, fio_uint_t *f )
{
GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_uint_t );
} // gdbfileio_newlib_to_fio_uint_t()
static void
gdbfileio_fio_to_newlib_long_t( fio_long_t *f, newlib_long_t *n )
{
GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_long_t );
} // gdbfileio_fio_to_newlib_long_t()
static void
gdbfileio_newlib_to_fio_long_t( newlib_long_t *n, fio_long_t *f )
{
GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_long_t );
} // gdbfileio_newlib_to_fio_long_t()
static void
gdbfileio_fio_to_newlib_mode_t( fio_mode_t *f, newlib_mode_t *n )
{
GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_mode_t );
} // gdbfileio_fio_to_newlib_mode_t()
static void
gdbfileio_newlib_to_fio_mode_t( newlib_mode_t *n, fio_mode_t *f )
{
GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_mode_t );
} // gdbfileio_newlib_to_fio_mode_t()
static void
gdbfileio_fio_to_newlib_dev_t( fio_uint_t *f, newlib_dev_t *n )
{
GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_uint_t );
} // gdbfileio_fio_to_newlib_dev_t()
static void
gdbfileio_fio_to_newlib_ino_t( fio_uint_t *f, newlib_ino_t *n )
{
GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_uint_t );
} // gdbfileio_fio_to_newlib_ino_t()
// these defines are good enough for now (to save code size) as they
// are the same functions in practice
#define gdbfileio_fio_to_newlib_nlink_t gdbfileio_fio_to_newlib_ino_t
#define gdbfileio_fio_to_newlib_uid_t gdbfileio_fio_to_newlib_ino_t
#define gdbfileio_fio_to_newlib_gid_t gdbfileio_fio_to_newlib_ino_t
#define gdbfileio_fio_to_newlib_off_t gdbfileio_fio_to_newlib_long_t
// this function is commonly used by most functions to handle everything
// once the packet has been constructed. It doesn't have to be used - it's
// just nice to keep this in one place for maintenance reasons.
static int
gdbfileio_common_sendpkt( char *buf, int *sig )
{
int status;
__putpacket( buf );
do {
__getpacket( __remcomInBuffer );
status = __process_packet( __remcomInBuffer );
} while ( status == 0 );
if ( __fileio_ctrlc_set )
*sig = SIGINT;
if ( !__fileio_retcode_set ) // deal with protocol failure
return -FILEIO_EINVAL;
if ( __fileio_retcode < 0 && __fileio_errno_set )
return -__fileio_errno;
else
return __fileio_retcode;
} // gdbfileio_common_sendpkt()
// deal with a received F packet. This is called from __process_packet in
// generic-stub.c
__externC void
cyg_hal_gdbfileio_process_F_packet( char *packet,
char *__remcomOutBuffer )
{
// Reply packet structure:
// F<retcode>[,<errno>[,<Ctrl-C flag>]][;<call specific attachment>]
char *p = &packet[1];
cyg_bool minus = false;
target_register_t temptrt;
__fileio_retcode_set = __fileio_errno_set = __fileio_ctrlc_set = false;
if (*p == '-') {
minus = true;
p++;
}
__hexToInt( &p, &temptrt );
__fileio_retcode = minus ? -(int)temptrt : (int)temptrt;
__fileio_retcode_set = true;
if ( *p++ == ',' ) {
// get errno
__hexToInt( &p, &temptrt );
__fileio_errno = (int)temptrt;
__fileio_errno_set = true;
if ( *p++ == ',' ) {
if ( *p == 'C' ) {
__fileio_ctrlc_set = true;
}
}
}
// ignore anything afterwards (e.g. call specific attachment) for now
} // cyg_hal_gdbfileio_process_F_packet()
__externC int
cyg_hal_gdbfileio_open( const char *name, int flags, int mode, int *sig )
{
size_t namelen;
unsigned int i=0;
fio_mode_t fmode;
fio_int_t fflags;
// clear out unsupported flags/modes, as per the spec
flags &= FILEIO_O_SUPPORTED;
mode &= FILEIO_S_SUPPORTED;
gdbfileio_newlib_to_fio_int_t( &flags, &fflags );
gdbfileio_newlib_to_fio_mode_t( &mode, &fmode );
__remcomOutBuffer[i++] = 'F';
__remcomOutBuffer[i++] = 'o';
__remcomOutBuffer[i++] = 'p';
__remcomOutBuffer[i++] = 'e';
__remcomOutBuffer[i++] = 'n';
__remcomOutBuffer[i++] = ',';
i += __intToHex( &__remcomOutBuffer[i], (target_register_t)name,
sizeof(name)*8 );
// i now points after the parameter
__remcomOutBuffer[i++] = '/';
namelen = strlen( name )+1; // includes '\0'
i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
sizeof(namelen)*8 );
__remcomOutBuffer[i++] = ',';
i += chars_to_hex( (char *)&fflags, &__remcomOutBuffer[i], sizeof(fflags) );
__remcomOutBuffer[i++] = ',';
i += chars_to_hex( (char *)&fmode, &__remcomOutBuffer[i], sizeof(fmode) );
__remcomOutBuffer[i] = 0;
return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -