!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/arch/s390/kernel/   drwxr-xr-x
Free 318.36 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     gdb-stub.c (12.08 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *  arch/s390/kernel/gdb-stub.c
 *
 *  S390 version
 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
 *
 *  Originally written by Glenn Engel, Lake Stevens Instrument Division
 *
 *  Contributed by HP Systems
 *
 *  Modified for SPARC by Stu Grossman, Cygnus Support.
 *
 *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
 *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
 *
 *  Copyright (C) 1995 Andreas Busse
 */

/*
 *  To enable debugger support, two things need to happen.  One, a
 *  call to set_debug_traps() is necessary in order to allow any breakpoints
 *  or error conditions to be properly intercepted and reported to gdb.
 *  Two, a breakpoint needs to be generated to begin communication.  This
 *  is most easily accomplished by a call to breakpoint().  Breakpoint()
 *  simulates a breakpoint by executing a BREAK instruction.
 *
 *
 *    The following gdb commands are supported:
 *
 * command          function                               Return value
 *
 *    g             return the value of the CPU registers  hex data or ENN
 *    G             set the value of the CPU registers     OK or ENN
 *
 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
 *
 *    c             Resume at current address              SNN   ( signal NN)
 *    cAA..AA       Continue at address AA..AA             SNN
 *
 *    s             Step one instruction                   SNN
 *    sAA..AA       Step one instruction from AA..AA       SNN
 *
 *    k             kill
 *
 *    ?             What was the last sigval ?             SNN   (signal NN)
 *
 *
 * All commands and responses are sent with a packet which includes a
 * checksum.  A packet consists of
 *
 * $<packet info>#<checksum>.
 *
 * where
 * <packet info> :: <characters representing the command or response>
 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
 *
 * When a packet is received, it is first acknowledged with either '+' or '-'.
 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
 *
 * Example:
 *
 * Host:                  Reply:
 * $m0,10#2a               +$00010203040506070809101112131415#42
 *
 */
#define TRUE 1
#define FALSE 0
#include <asm/gdb-stub.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <linux/stddef.h>

#define S390_REGS_COMMON_SIZE offsetof(struct gdb_pt_regs,orig_gpr2)

/*
 * external low-level support routines
 */


extern void fltr_set_mem_err(void);
extern void trap_low(void);

/*
 * breakpoint and test functions
 */
extern void breakpoint(void);
extern void breakinst(void);

/*
 * local prototypes
 */

static void getpacket(char *buffer);
static void putpacket(char *buffer);
static int hex(unsigned char ch);
static int hexToInt(char **ptr, int *intValue);
static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault);


/*
 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
 * at least NUMREGBYTES*2 are needed for register packets
 */
#define BUFMAX 2048

static char input_buffer[BUFMAX];
static char output_buffer[BUFMAX];
int gdb_stub_initialised = FALSE;    
static const char hexchars[]="0123456789abcdef";


/*
 * Convert ch from a hex digit to an int
 */
static int hex(unsigned char ch)
{
    if (ch >= 'a' && ch <= 'f')
        return ch-'a'+10;
    if (ch >= '0' && ch <= '9')
        return ch-'0';
    if (ch >= 'A' && ch <= 'F')
        return ch-'A'+10;
    return -1;
}

/*
 * scan for the sequence $<data>#<checksum>
 */
static void getpacket(char *buffer)
{
    unsigned char checksum;
    unsigned char xmitcsum;
    int i;
    int count;
    unsigned char ch;

    do {
        /*
         * wait around for the start character,
         * ignore all other characters
         */
        while ((ch = (getDebugChar() & 0x7f)) != '$') ;

        checksum = 0;
        xmitcsum = -1;
        count = 0;
    
        /*
         * now, read until a # or end of buffer is found
         */
        while (count < BUFMAX) {
            ch = getDebugChar() & 0x7f;
            if (ch == '#')
                break;
            checksum = checksum + ch;
            buffer[count] = ch;
            count = count + 1;
        }

        if (count >= BUFMAX)
            continue;

        buffer[count] = 0;

        if (ch == '#') {
            xmitcsum = hex(getDebugChar() & 0x7f) << 4;
            xmitcsum |= hex(getDebugChar() & 0x7f);

            if (checksum != xmitcsum)
                putDebugChar('-');    /* failed checksum */
            else {
                putDebugChar('+'); /* successful transfer */

                /*
                 * if a sequence char is present,
                 * reply the sequence ID
                 */
                if (buffer[2] == ':') {
                    putDebugChar(buffer[0]);
                    putDebugChar(buffer[1]);

                    /*
                     * remove sequence chars from buffer
                     */
                    count = strlen(buffer);
                    for (i=3; i <= count; i++)
                        buffer[i-3] = buffer[i];
                }
            }
        }
    }
    while (checksum != xmitcsum);
}

/*
 * send the packet in buffer.
 */
static void putpacket(char *buffer)
{
    unsigned char checksum;
    int count;
    unsigned char ch;

    /*
     * $<packet info>#<checksum>.
     */

    do {
        putDebugChar('$');
        checksum = 0;
        count = 0;

        while ((ch = buffer[count]) != 0) {
            if (!(putDebugChar(ch)))
                return;
            checksum += ch;
            count += 1;
        }

        putDebugChar('#');
        putDebugChar(hexchars[checksum >> 4]);
        putDebugChar(hexchars[checksum & 0xf]);

    }
    while ((getDebugChar() & 0x7f) != '+');
}



/*
 * Convert the memory pointed to by mem into hex, placing result in buf.
 * Return a pointer to the last char put in buf (null), in case of mem fault,
 * return 0.
 * If MAY_FAULT is non-zero, then we will handle memory faults by returning
 * a 0, else treat a fault like any other fault in the stub.
 */
static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
{
    unsigned char ch;

/*    set_mem_fault_trap(may_fault); */

    while (count-- > 0) {
        ch = *(mem++);
#if 0
        if (mem_err)
            return 0;
#endif
        *buf++ = hexchars[ch >> 4];
        *buf++ = hexchars[ch & 0xf];
    }

    *buf = 0;

/*    set_mem_fault_trap(0); */

    return buf;
}

/*
 * convert the hex array pointed to by buf into binary to be placed in mem
 * return a pointer to the character AFTER the last byte written
 */
static char *hex2mem(char *buf, char *mem, int count, int may_fault)
{
    int i;
    unsigned char ch;

/*    set_mem_fault_trap(may_fault); */

    for (i=0; i<count; i++)
    {
        ch = hex(*buf++) << 4;
        ch |= hex(*buf++);
        *(mem++) = ch;
#if 0
        if (mem_err)
            return 0;
#endif
    }

/*    set_mem_fault_trap(0); */

    return mem;
}



/*
 * Set up exception handlers for tracing and breakpoints
 */
void set_debug_traps(void)
{
//    unsigned long flags;
    unsigned char c;

//    save_and_cli(flags);
    /*
     * In case GDB is started before us, ack any packets
     * (presumably "$?#xx") sitting there.
     */
    while((c = getDebugChar()) != '$');
    while((c = getDebugChar()) != '#');
    c = getDebugChar(); /* eat first csum byte */
    c = getDebugChar(); /* eat second csum byte */
    putDebugChar('+'); /* ack it */

    gdb_stub_initialised = TRUE;
//    restore_flags(flags);
}


/*
 * Trap handler for memory errors.  This just sets mem_err to be non-zero.  It
 * assumes that %l1 is non-zero.  This should be safe, as it is doubtful that
 * 0 would ever contain code that could mem fault.  This routine will skip
 * past the faulting instruction after setting mem_err.
 */
extern void fltr_set_mem_err(void)
{
  /* FIXME: Needs to be written... */
}


/*
 * While we find nice hex chars, build an int.
 * Return number of chars processed.
 */
static int hexToInt(char **ptr, int *intValue)
{
    int numChars = 0;
    int hexValue;

    *intValue = 0;

    while (**ptr)
    {
        hexValue = hex(**ptr);
        if (hexValue < 0)
            break;

        *intValue = (*intValue << 4) | hexValue;
        numChars ++;

        (*ptr)++;
    }

    return (numChars);
}

void gdb_stub_get_non_pt_regs(struct gdb_pt_regs *regs)
{
    s390_fp_regs *fpregs=&regs->fp_regs;
    int has_ieee=save_fp_regs1(fpregs);

    if(!has_ieee)
    {
        fpregs->fpc=0;
        fpregs->fprs[1].d=
        fpregs->fprs[3].d=
        fpregs->fprs[5].d=
        fpregs->fprs[7].d=0;
        memset(&fpregs->fprs[8].d,0,sizeof(freg_t)*8);
    }
}

void gdb_stub_set_non_pt_regs(struct gdb_pt_regs *regs)
{
    restore_fp_regs1(&regs->fp_regs);
}

void gdb_stub_send_signal(int sigval)
{
    char *ptr;
    ptr = output_buffer;

    /*
     * Send trap type (converted to signal)
     */
    *ptr++ = 'S';
    *ptr++ = hexchars[sigval >> 4];
    *ptr++ = hexchars[sigval & 0xf];
    *ptr++ = 0;
    putpacket(output_buffer);    /* send it off... */
}

/*
 * This function does all command processing for interfacing to gdb.  It
 * returns 1 if you should skip the instruction at the trap address, 0
 * otherwise.
 */
void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval)
{
    int trap;            /* Trap type */
    int addr;
    int length;
    char *ptr;
    unsigned long *stack;

    
    /*
     * reply to host that an exception has occurred
     */
#if 0
    send_signal(sigval);
#endif
    /*
     * Wait for input from remote GDB
     */
    while (1) 
    {
        output_buffer[0] = 0;
        getpacket(input_buffer);

        switch (input_buffer[0])
        {
        case '?':
#if 0
            send_signal(sigval);
#endif
            continue;

        case 'd':
            /* toggle debug flag */
            break;

        /*
         * Return the value of the CPU registers
         */
        case 'g':
            gdb_stub_get_non_pt_regs(regs);
            ptr = output_buffer;
            ptr=  mem2hex((char *)regs,ptr,S390_REGS_COMMON_SIZE,FALSE);
            ptr=  mem2hex((char *)&regs->crs[0],ptr,NUM_CRS*CR_SIZE,FALSE);
            ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs),FALSE);
            break;
      
        /*
         * set the value of the CPU registers - return OK
         * FIXME: Needs to be written
         */
        case 'G':
            ptr=input_buffer;
            hex2mem (ptr, (char *)regs,S390_REGS_COMMON_SIZE, FALSE);
            ptr+=S390_REGS_COMMON_SIZE*2;
            hex2mem (ptr, (char *)regs->crs[0],NUM_CRS*CR_SIZE, FALSE);
            ptr+=NUM_CRS*CR_SIZE*2;
            hex2mem (ptr, (char *)&regs->fp_regs,sizeof(s390_fp_regs), FALSE);
            gdb_stub_set_non_pt_regs(regs);
            strcpy(output_buffer,"OK");
        break;

        /*
         * mAA..AA,LLLL  Read LLLL bytes at address AA..AA
         */
        case 'm':
            ptr = &input_buffer[1];

            if (hexToInt(&ptr, &addr)
                && *ptr++ == ','
                && hexToInt(&ptr, &length)) {
                if (mem2hex((char *)addr, output_buffer, length, 1))
                    break;
                strcpy (output_buffer, "E03");
            } else
                strcpy(output_buffer,"E01");
            break;

        /*
         * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
         */
        case 'M': 
            ptr = &input_buffer[1];

            if (hexToInt(&ptr, &addr)
                && *ptr++ == ','
                && hexToInt(&ptr, &length)
                && *ptr++ == ':') 
            {
                if (hex2mem(ptr, (char *)addr, length, 1))
                    strcpy(output_buffer, "OK");
                else
                    strcpy(output_buffer, "E03");
            }
            else
                strcpy(output_buffer, "E02");
            break;

        /*
         * cAA..AA    Continue at address AA..AA(optional)
         */
        case 'c':    
            /* try to read optional parameter, pc unchanged if no parm */

            ptr = &input_buffer[1];
            if (hexToInt(&ptr, &addr))
                regs->psw.addr = addr;
            /*
             * Need to flush the instruction cache here, as we may
             * have deposited a breakpoint, and the icache probably
             * has no way of knowing that a data ref to some location
             * may have changed something that is in the instruction
             * cache.
             * NB: We flush both caches, just to be sure...
             */

            flush_cache_all();
            return;
            /* NOTREACHED */
            break;


        /*
         * kill the program
         */
        case 'k' :
            break;        /* do nothing */


        /*
         * Reset the whole machine (FIXME: system dependent)
         */
        case 'r':
            break;


        /*
         * Step to next instruction
         */
        case 's':
            /*
             * There is no single step insn in the MIPS ISA, so we
             * use breakpoints and continue, instead.
             */
#if 0
            single_step(regs);
#endif
            flush_cache_all();
            return;
            /* NOTREACHED */
            break;

        }      /* switch */

    /*
     * reply to the request
     */
    
        putpacket(output_buffer);
    
    } /* while */
}

/*
 * This function will generate a breakpoint exception.  It is used at the
 * beginning of a program to sync up with a debugger and can be used
 * otherwise as a quick means to stop program execution and "break" into
 * the debugger.
 */
void breakpoint(void)
{
    if (!gdb_stub_initialised)
        return;
    asm volatile (".globl    breakinst\n"
        "breakinst:\t.word   %0"
        : : "i" (S390_BREAKPOINT_U16) );
}








:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0048 ]--