trap_retval ReqSplit_cmd( void )
{
    char                *cmd;
    char                *start;
    split_cmd_ret       *ret;
    unsigned            len;

    cmd = GetInPtr( sizeof( split_cmd_req ) );
    ret = GetOutPtr( 0 );
    ret->parm_start = 0;
    start = cmd;
    len = GetTotalSize() - sizeof( split_cmd_req );
    while( len != 0 ) {
        switch( *cmd ) {
        case '\0':
        case ' ':
        case '\t':
            ret->parm_start = 1;
            len = 0;
            continue;
        }
        ++cmd;
        --len;
    }
    ret->parm_start += cmd - start;
    ret->cmd_end = cmd - start;
    CONV_LE_16( ret->cmd_end );
    CONV_LE_16( ret->parm_start );
    return( sizeof( *ret ) );
}
Exemple #2
0
trap_retval RemoteGet( void *data, trap_elen len )
{
    unsigned_16         rec_len;

    len = len;

    _DBG_NET(("RemoteGet\r\n"));

    if( IS_VALID_SOCKET( data_socket ) ) {
        int     size;

        size = recvData( &rec_len, sizeof( rec_len ) );
#ifdef __RDOS__
        while( size == 0 ) {
            if( !IS_VALID_SOCKET( data_socket ) )
                return( REQUEST_FAILED );
            size = recvData( &rec_len, sizeof( rec_len ) );
        }
#endif
        if( size == sizeof( rec_len ) ) {
            CONV_LE_16( rec_len );
#ifdef __RDOS__
            if( rec_len && recvData( data, rec_len ) == rec_len ) {
#else
            if( rec_len == 0 || recvData( data, rec_len ) == rec_len ) {
#endif
                _DBG_NET(("Got a packet - size=%d\r\n", rec_len));
                return( rec_len );
            }
        }
    }
    return( REQUEST_FAILED );
}

trap_retval RemotePut( void *data, trap_elen len )
{
    unsigned_16         send_len;
    int                 snd;

    _DBG_NET(("RemotePut\r\n"));

    if( IS_VALID_SOCKET( data_socket ) ) {
        send_len = len;
        CONV_LE_16( send_len );
        snd = send( data_socket, (void *)&send_len, sizeof( send_len ), 0 );
        if( IS_RET_OK( snd ) ) {
            if( len != 0 )
                snd = send( data_socket, data, len, 0 );
            if( len == 0 || IS_RET_OK( snd ) ) {
#ifdef __RDOS__
                RdosPushTcpConnection( data_socket );
#endif
                _DBG_NET(("RemotePut...OK\r\n"));
                return( len );
            }
        }
    }
    return( REQUEST_FAILED );
}
Exemple #3
0
unsigned ReqRead_mem( void )
{
    read_mem_req    *acc;
    unsigned        len;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->mem_addr.offset );
    CONV_LE_16( acc->mem_addr.segment );
    CONV_LE_16( acc->len );
    len = ReadMem( pid, GetOutPtr( 0 ), acc->mem_addr.offset, acc->len );
    return( len );
}
Exemple #4
0
unsigned ReqWrite_mem( void )
{
    write_mem_req   *acc;
    write_mem_ret   *ret;
    unsigned        len;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->mem_addr.offset );
    CONV_LE_16( acc->mem_addr.segment );
    ret = GetOutPtr( 0 );
    len = GetTotalSize() - sizeof( *acc );
    ret->len = WriteMem( pid, GetInPtr( sizeof( *acc ) ), acc->mem_addr.offset, len );
    CONV_LE_16( ret->len );
    return( sizeof( *ret ) );
}
Exemple #5
0
static unsigned DoAWrite( unsigned req, sys_handle hdl, void *ptr, unsigned len )
{
    mx_entry            in[2];
    mx_entry            out[1];
    union {
        file_write_req              file;
        file_write_console_req      con;
    } acc;
    file_write_ret      ret;

    SUPP_FILE_SERVICE( acc.file, req );
    if( req == REQ_FILE_WRITE_CONSOLE ) {
        in[0].len = sizeof( acc.con );
    } else {
        acc.file.handle = hdl;
    CONV_LE_32( acc.file.handle );
        in[0].len = sizeof( acc.file );
    }
    in[0].ptr = &acc;
    in[1].ptr = ptr;
    in[1].len = len;
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    TrapAccess( 2, &in, 1, &out );
    CONV_LE_32( ret.err );
    CONV_LE_16( ret.len );
    if( ret.err != 0 ) {
        StashErrCode( ret.err, OP_REMOTE );
        return( ERR_RETURN );
    } else {
        return( ret.len );
    }
}
Exemple #6
0
static unsigned DoRead( sys_handle hdl, void *ptr, unsigned len )
{
    mx_entry            in[1];
    mx_entry            out[2];
    file_read_req       acc;
    file_read_ret       ret;
    unsigned            got;

    SUPP_FILE_SERVICE( acc, REQ_FILE_READ );
    acc.handle = hdl;
    acc.len = len;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    out[1].ptr = ptr;
    out[1].len = len;
    CONV_LE_32( acc.handle );
    CONV_LE_16( acc.len );
    got = TrapAccess( 1, &in, 2, &out );
    CONV_LE_32( ret.err );
    if( ret.err != 0 ) {
        StashErrCode( ret.err, OP_REMOTE );
        return( ERR_RETURN );
    } else {
        return( got - sizeof( ret ) );
    }
}
Exemple #7
0
static bool AccConnect( void )
{
    connect_req         *acc;
    char                *data;
    connect_ret         *ret;
    trap_elen           max;
    trap_elen           len;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    data = GetOutPtr( sizeof( *ret ) );
    if( acc->ver.major != TrapVersion.major || acc->ver.minor > TrapVersion.minor ) {
        strcpy( data, TRP_ERR_WRONG_SERVER_VERSION );
        PutBuffPacket( RWBuff, sizeof( *acc ) + sizeof( TRP_ERR_WRONG_SERVER_VERSION ) );
    } else {
        len = TrapAccess( 1, &In[0], 1, &Out[0] );
        max = MaxPacketSize();
        if( max > sizeof( RWBuff ) )
            max = sizeof( RWBuff );
        if( ret->max_msg_size > max )
            ret->max_msg_size = max;
        CONV_LE_16( ret->max_msg_size );
        PutBuffPacket( RWBuff, len );
    }
    if( data[0] != '\0' ) {
        ServError( data );
        return( FALSE );
    }
    return( TRUE );
}
Exemple #8
0
unsigned MakeAsyncRun( bool single )
{
    async_go_req        acc;
    async_go_ret        ret;
    addr_ptr            tmp;

    if( SuppAsyncId == 0 ) return( 0 );

    acc.supp.core_req = REQ_PERFORM_SUPPLEMENTARY_SERVICE;
    acc.supp.id = SuppAsyncId;

    if( single )
        acc.req = REQ_ASYNC_STEP;
    else
        acc.req = REQ_ASYNC_GO;

    OnAnotherThreadSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
    CONV_LE_16( ret.conditions );

    if( ret.conditions & COND_RUNNING ) {
        ret.stack_pointer.offset = 0;
        ret.stack_pointer.segment = 0;
        ret.program_counter.offset = 0;
        ret.program_counter.segment = 0;
    } else {
        CONV_LE_32( ret.stack_pointer.offset );
        CONV_LE_16( ret.stack_pointer.segment );
        CONV_LE_32( ret.program_counter.offset );
        CONV_LE_16( ret.program_counter.segment );
        if( ret.conditions & COND_CONFIG ) {
            GetSysConfig();
            CheckMADChange();
        }
        DbgRegs->mad = SysConfig.mad;
        /* Use 'tmp' because of alignment problems */
        tmp = ret.stack_pointer;
        MADRegSpecialSet( MSR_SP, &DbgRegs->mr, &tmp );
        tmp = ret.program_counter;
        MADRegSpecialSet( MSR_IP, &DbgRegs->mr, &tmp );
        if( ret.conditions & COND_THREAD ) {
            DbgRegs->tid = RemoteSetThread( 0 );
        }
    }
    return( ret.conditions );
}
Exemple #9
0
unsigned_16 GetUInt( void )
/*************************/
{
    unsigned_16 word;

    word = *(unsigned_16 *)RecPtr;
    CONV_LE_16( word );
    RecPtr += 2;
    return( word );
}
trap_retval ReqFile_write_console( void )
{
    file_write_console_ret      *ret;

    ret = GetOutPtr( 0 );
    ret->len = DoWrite( 2, GetInPtr( sizeof( file_write_console_req ) ),
                        GetTotalSize() - sizeof( file_write_console_req ) );
    ret->err = errno;
    CONV_LE_32( ret->err );
    CONV_LE_16( ret->len );
    return( sizeof( *ret ) );
}
trap_retval ReqFile_write( void )
{
    file_write_req      *acc;
    file_write_ret      *ret;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->handle );
    ret = GetOutPtr( 0 );
    ret->len = DoWrite( acc->handle, GetInPtr( sizeof( *acc ) ),
                        GetTotalSize() - sizeof( *acc ) );
    ret->err = errno;
    CONV_LE_32( ret->err );
    CONV_LE_16( ret->len );
    return( sizeof( *ret ) );
}
Exemple #12
0
static void fix_sym64_byte_order( elf_file_handle elf_file_hnd, Elf64_Sym *e_sym )
{
    // note that one of the branches will always get compiled out,
    // depending on host endianness
    if( elf_file_hnd->flags & ORL_FILE_FLAG_BIG_ENDIAN ) {
        CONV_BE_32( e_sym->st_name );
        SCONV_BE_64( e_sym->st_value );
        SCONV_BE_64( e_sym->st_size );
        CONV_BE_16( e_sym->st_shndx );
    } else {
        CONV_LE_32( e_sym->st_name );
        SCONV_LE_64( e_sym->st_value );
        SCONV_LE_64( e_sym->st_size );
        CONV_LE_16( e_sym->st_shndx );
    }
}
Exemple #13
0
unsigned ReqClear_break( void )
{
    clear_break_req *acc;
    bp_t            opcode;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->break_addr.offset );
    CONV_LE_16( acc->break_addr.segment );
    opcode = acc->old;
    WriteMem( pid, &opcode, acc->break_addr.offset, sizeof( opcode ) );
    Out( "ReqClear_break at " );
    OutNum( acc->break_addr.offset );
    Out( " (setting to " );
    OutNum( opcode );
    Out( ")\n" );
    return( 0 );
}
Exemple #14
0
unsigned ReqGet_sys_config( void )
{
    get_sys_config_ret  *ret;

    ret = GetOutPtr( 0 );
    ret->sys.os = OS_LINUX;

    // TODO: Detect OS version (kernel version?)!
    ret->sys.osmajor = 1;
    ret->sys.osminor = 0;

    ret->sys.cpu = MIPS_R3000;
    ret->sys.fpu = 0;
    ret->sys.huge_shift = 3;
    ret->sys.mad = MAD_MIPS;
    CONV_LE_16( ret->sys.mad );
    return( sizeof( *ret ) );
}
Exemple #15
0
static unsigned ReadSection( handle filehndl, unsigned off )
{
    unsigned_16 len;
    unsigned    last;
    void        *new;

    if( ReadStream( filehndl, &len, sizeof( len ) ) != sizeof( len ) ) {
        return( 0 );
    }
    CONV_LE_16( len );
    last = off + len;
    if( last > ParseTableSize ) {
        new = ParseTable;
        _Realloc( new, last );
        if( new == NULL ) return( 0 );
        ParseTable = new;
        ParseTableSize = last;
    }
Exemple #16
0
static unsigned_32 GetOffset( void )
/**********************************/
{
    if( isMS386 ) {
        unsigned_32 dword;

        dword = *(unsigned_32 *)RecPtr;
        CONV_LE_32( dword );
        RecPtr += 4;
        return( dword );
    } else {
        unsigned_16 word;

        word = *(unsigned_16 *)RecPtr;
        CONV_LE_16( word );
        RecPtr += 2;
        return( word );
    }
}
Exemple #17
0
unsigned ReqSet_break( void )
{
    set_break_req   *acc;
    set_break_ret   *ret;
    bp_t            opcode;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    CONV_LE_32( acc->break_addr.offset );
    CONV_LE_16( acc->break_addr.segment );
    ReadMem( pid, &opcode, acc->break_addr.offset, sizeof( opcode ) );
    ret->old = opcode;
    opcode = BRK_POINT;
    WriteMem( pid, &opcode, acc->break_addr.offset, sizeof( opcode ) );
    Out( "ReqSet_break at " );
    OutNum( acc->break_addr.offset );
    Out( " (was " );
    OutNum( ret->old );
    Out( ")\n" );
    return( sizeof( *ret ) );
}
trap_retval ReqFile_read( void )
{
    unsigned            total;
    unsigned            len;
    char                *ptr;
    size_t              curr;
    ssize_t             rv;
    file_read_req       *acc;
    file_read_ret       *ret;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->handle );
    CONV_LE_16( acc->len );
    ret = GetOutPtr( 0 );
    ptr = GetOutPtr( sizeof( *ret ) );
    len = acc->len;
    total = 0;
    for( ;; ) {
        if( len == 0 ) break;
        curr = len;
        if( curr > INT_MAX ) curr = INT_MAX;
        rv = read( acc->handle, ptr, curr );
        if( rv < 0 ) {
            total = -1;
            break;
        }
        total += rv;
        if( rv != curr ) break;
        ptr += rv;
        len -= rv;
    }
    if( total == -1 ) {
        total = 0;
    } else {
        errno = 0;
    }
    ret->err = errno;
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) + total );
}
void RemotePollRunThread( void )
{
    run_thread_poll_req      acc;
    run_thread_poll_ret      ret;

    if( SuppRunThreadId == 0 ) return;

    acc.supp.core_req = REQ_PERFORM_SUPPLEMENTARY_SERVICE;
    acc.supp.id = SuppRunThreadId;
    acc.req = REQ_RUN_THREAD_POLL;

    OnAnotherThreadSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
    CONV_LE_16( ret.conditions );

    if( ret.conditions & COND_CONFIG ) {
        GetSysConfig();
        CheckMADChange();
    }
    if( ret.conditions & COND_THREAD ) {
        CheckForNewThreads( TRUE );
    }
}
Exemple #20
0
/*
 * AccMapAddr - map address in image from link-time virtual address to
 * actual linear address as loaded in memory. For executables, this will
 * in effect return the address unchanged (image base 0x08048100 equals
 * linear 0x08048100), for shared libs this will typically add the offset
 * from zero (link time VA) to actual load base.
 */
trap_retval ReqMap_addr( void )
{
    map_addr_req    *acc;
    map_addr_ret    *ret;
    unsigned long   val;
    lib_load_info   *lli;

    // Note: Info about the process address space is stored in the user register
    //       for GDB, so we can use that to find out what we need to convert these
    //       values in here...
    acc = GetInPtr( 0 );
    CONV_LE_32( acc->in_addr.offset );
    CONV_LE_16( acc->in_addr.segment );
    CONV_LE_32( acc->mod_handle );
    ret = GetOutPtr( 0 );
    ret->lo_bound = 0;
    ret->hi_bound = ~(addr_off)0;
    errno = 0;
    if( (val = ptrace( PTRACE_PEEKUSER, pid, (void *)(offsetof( user_struct, start_code )), 0 )) == -1 ) {
        if( errno ) {
            Out( "ReqMap_addr: first PTRACE_PEEKUSER failed!\n" );
            val = 0;
        }
    }
#ifdef __MIPS__
    // Hack for MIPS - the above call seems to be failing but isn't returning
    // an error; it's possible that the call just isn't valid.
    val = 0;
#endif
    ret->out_addr.offset = acc->in_addr.offset + val;

    if( acc->mod_handle > ModuleTop ) {
        Out( "ReqMap_addr: Invalid handle passed!\n" );
        return( sizeof( *ret ) );
    } else {
        lli = &moduleInfo[acc->mod_handle];
    }

    Out( "ReqMap_addr: addr " );
    OutNum( acc->in_addr.segment );
    Out( ":" );
    OutNum( acc->in_addr.offset );
    Out( " in module " );
    OutNum( acc->mod_handle );
    if( acc->in_addr.segment == MAP_FLAT_DATA_SELECTOR ||
        acc->in_addr.segment == flatDS ) {
        if( (val = ptrace( PTRACE_PEEKUSER, pid, (void *)offsetof( user_struct, u_tsize ), 0 )) == -1 ) {
            if( errno ) {
                Out( "ReqMap_addr: second PTRACE_PEEKUSER failed!\n" );
                val = 0;
            }
        }
        ret->out_addr.offset += val;
        ret->out_addr.segment = flatDS;
    } else {
        ret->out_addr.segment = flatCS;
    }
    ret->out_addr.offset += lli->offset;
    Out( " to " );
    OutNum( ret->out_addr.offset );
    Out( "\n" );
    CONV_LE_32( ret->out_addr.offset );
    CONV_LE_16( ret->out_addr.segment );
    CONV_LE_32( ret->lo_bound );
    CONV_LE_32( ret->hi_bound );
    return( sizeof( *ret ) );
}
Exemple #21
0
trap_retval RemoteGet( byte *rec, trap_elen len )
{
    unsigned_16         rec_len;

    len = len;

    _DBG_NET(("RemoteGet\r\n"));

#ifdef __RDOS__
    if( !IS_INVALID_SOCKET( data_socket ) && !RdosIsTcpConnectionClosed( data_socket ) ) {
#else
    if( !IS_INVALID_SOCKET( data_socket ) ) {
#endif
        if( FullGet( &rec_len, sizeof( rec_len ) ) == sizeof( rec_len ) ) {
            CONV_LE_16( rec_len );
            if( rec_len == 0 || FullGet( rec, rec_len ) == rec_len ) {
                _DBG_NET(("Got a packet - size=%d\r\n", rec_len));
                return( rec_len );
            }
        }
    }
    return( REQUEST_FAILED );
}

trap_retval RemotePut( byte *rec, trap_elen len )
{
    unsigned_16         send_len;

    _DBG_NET(("RemotePut\r\n"));

#ifdef __RDOS__
    if( !IS_INVALID_SOCKET( data_socket ) && !RdosIsTcpConnectionClosed( data_socket ) ) {
#else
    if( !IS_INVALID_SOCKET( data_socket ) ) {
#endif
        send_len = len;
        CONV_LE_16( send_len );
        if( !IS_SOCK_ERROR( send( data_socket, (void *)&send_len, sizeof( send_len ), 0 ) ) ) {
            if( len == 0 || !IS_SOCK_ERROR( send( data_socket, (void *)rec, len, 0 ) ) ) {
#ifdef __RDOS__
                 RdosPushTcpConnection( data_socket );
#endif
                _DBG_NET(("RemotePut...OK\r\n"));
                return( len );
            }
        }
    }
    return( REQUEST_FAILED );
}

#ifndef __RDOS__

static void nodelay( void )
{
    struct protoent     *proto;
    int                 delayoff;
    int                 p;

    delayoff = 1;
    proto = getprotobyname( "tcp" );
    p = proto ? proto->p_proto : IPPROTO_TCP;
    setsockopt( data_socket, p, TCP_NODELAY, (void *)&delayoff, sizeof( delayoff ) );
}

#endif

bool RemoteConnect( void )
{
#ifdef SERVER
  #ifdef __RDOS__
    void *obj;

    obj = RdosWaitTimeout( wait_handle, 250 );
    if( obj != NULL ) {
        data_socket = RdosGetTcpListen( listen_handle );
        if( !IS_INVALID_SOCKET( data_socket ) ) {
            _DBG_NET(("Found a connection\r\n"));
            return( TRUE );
        }
    }
  #else
    struct          timeval timeout;
    fd_set          ready;
    struct          sockaddr dummy;
    trp_socklen     dummy_len = sizeof( dummy );

    FD_ZERO( &ready );
    FD_SET( control_socket, &ready );
    timeout.tv_sec = 0;
    timeout.tv_usec = 10000;
    if( select( control_socket + 1, &ready, 0, 0, &timeout ) > 0 ) {
        data_socket = accept( control_socket, &dummy, &dummy_len );
        if( !IS_INVALID_SOCKET( data_socket ) ) {
            nodelay();
            _DBG_NET(("Found a connection\r\n"));
            return( TRUE );
        }
    }
  #endif
#else
  #ifdef __RDOS__
    // todo: Add code for connect!
  #else
    data_socket = socket( AF_INET, SOCK_STREAM, 0 );
    if( !IS_INVALID_SOCKET( data_socket ) ) {
        if( connect( data_socket, (struct sockaddr TRAPFAR *)&socket_address, sizeof( socket_address ) ) >= 0 ) {
            nodelay();
            return( TRUE );
        }
    }
  #endif
#endif
    return( FALSE );
}
Exemple #22
0
static unsigned ProgRun( int step )
{
    static int          ptrace_sig = 0;
    static int          ld_state = 0;
    user_regs_struct    regs;
    int                 status;
    prog_go_ret         *ret;
    void                (*old)(int);
    int                 debug_continue;

    if( pid == 0 )
        return( 0 );
    ret = GetOutPtr( 0 );

    if( at_end ) {
        ptrace_sig = 0;
        ret->conditions = COND_TERMINATE;
        goto end;
    }

    /* we only want child-generated SIGINTs now */
    do {
        old = setsig( SIGINT, SIG_IGN );
        if( step ) {
            Out( "PTRACE_SINGLESTEP\n" );
            if( ptrace( PTRACE_SINGLESTEP, pid, NULL, (void *)ptrace_sig ) == -1 )
                perror( "PTRACE_SINGLESTEP" );
        } else {
            Out( "PTRACE_CONT\n" );
            if( ptrace( PTRACE_CONT, pid, NULL, (void *)ptrace_sig ) == -1 )
                perror( "PTRACE_CONT" );
        }
        waitpid( pid, &status, 0 );
        setsig( SIGINT, old );

#if defined( MD_x86 )
        ptrace( PTRACE_GETREGS, pid, NULL, &regs );
#elif defined( MD_ppc )
        regs.eip = ptrace( PTRACE_PEEKUSER, pid, REGSIZE * PT_NIP, NULL );
        regs.esp = ptrace( PTRACE_PEEKUSER, pid, REGSIZE * PT_R1, NULL );
#elif defined( MD_mips )
        regs.eip = ptrace( PTRACE_PEEKUSER, pid, (void *)PC, NULL );
        regs.esp = ptrace( PTRACE_PEEKUSER, pid, (void *)29, NULL );
#endif
        Out( " eip " );
        OutNum( regs.eip );
        Out( "\n" );

        debug_continue = FALSE;
        if( WIFSTOPPED( status ) ) {
            switch( ( ptrace_sig = WSTOPSIG( status ) ) ) {
            case SIGSEGV:
            case SIGILL:
            case SIGFPE:
            case SIGABRT:
            case SIGBUS:
            case SIGQUIT:
            case SIGSYS:
                last_sig = ptrace_sig;
                ret->conditions = COND_EXCEPTION;
                ptrace_sig = 0;
                break;
            case SIGINT:
                ret->conditions = COND_USER;
                ptrace_sig = 0;
                break;
            case SIGTRAP:
                ret->conditions = step ? COND_TRACE : COND_BREAK;
                Out( "sigtrap\n" );
                ptrace_sig = 0;
                break;
            default:
                /* For signals that we do not wish to handle, we need
                 * to continue the debuggee until we get a signal
                 * that we need to handle
                 */
                Out( "Unknown signal " );
                OutNum( ptrace_sig );
                Out( "\n" );
                debug_continue = TRUE;
                break;
            }
        } else if( WIFEXITED( status ) ) {
            Out( "WIFEXITED\n" );
            at_end = TRUE;
            ret->conditions = COND_TERMINATE;
            ptrace_sig = 0;
            goto end;
        }
    } while( debug_continue );

    if( ret->conditions == COND_BREAK ) {
#if defined( MD_x86 )
        if( regs.eip == rdebug.r_brk + sizeof( old_ld_bp ) ) {
#elif defined( MD_ppc ) || defined( MD_mips )
        if( regs.eip == rdebug.r_brk ) {
#endif
            int         psig = 0;
            void        (*oldsig)(int);
            bp_t        opcode = BRK_POINT;

            /* The dynamic linker breakpoint was hit, meaning that
             * libraries are being loaded or unloaded. This gets a bit
             * tricky because we must restore the original code that was
             * at the breakpoint and execute it, but we still want to
             * keep the breakpoint.
             */
            WriteMem( pid, &old_ld_bp, rdebug.r_brk, sizeof( old_ld_bp ) );
            ReadMem( pid, &rdebug, (addr48_off)dbg_rdebug, sizeof( rdebug ) );
            Out( "ld breakpoint hit, state is " );
            switch( rdebug.r_state ) {
            case RT_ADD:
                Out( "RT_ADD\n" );
                ld_state = RT_ADD;
                AddOneLib( rdebug.r_map );
                break;
            case RT_DELETE:
                Out( "RT_DELETE\n" );
                ld_state = RT_DELETE;
                break;
            case RT_CONSISTENT:
                Out( "RT_CONSISTENT\n" );
                if( ld_state == RT_DELETE )
                    DelOneLib( rdebug.r_map );
                ld_state = RT_CONSISTENT;
                break;
            default:
                Out( "error!\n" );
                break;
            }
            regs.orig_eax = -1;
#if defined( MD_x86 )
            regs.eip--;
            ptrace( PTRACE_SETREGS, pid, NULL, &regs );
#endif
            oldsig = setsig( SIGINT, SIG_IGN );
            ptrace( PTRACE_SINGLESTEP, pid, NULL, (void *)psig );
            waitpid( pid, &status, 0 );
            setsig( SIGINT, oldsig );
            WriteMem( pid, &opcode, rdebug.r_brk, sizeof( old_ld_bp ) );
            ret->conditions = COND_LIBRARIES;
        } else {
#if defined( MD_x86 )
            Out( "decrease eip(sigtrap)\n" );
            regs.orig_eax = -1;
            regs.eip--;
            ptrace( PTRACE_SETREGS, pid, NULL, &regs );
#endif
        }
    }
    orig_eax = regs.orig_eax;
    last_eip = regs.eip;
    ret->program_counter.offset = regs.eip;
    ret->program_counter.segment = regs.cs;
    ret->stack_pointer.offset = regs.esp;
    ret->stack_pointer.segment = regs.ss;
    ret->conditions |= COND_CONFIG;

    /* If debuggee has dynamic section, try getting the r_debug struct
     * every time the debuggee stops. The r_debug data may not be available
     * immediately after the debuggee process loads.
     */
    if( !have_rdebug && (dbg_dyn != NULL) ) {
        if( Get_ld_info( pid, dbg_dyn, &rdebug, &dbg_rdebug ) ) {
            bp_t        opcode;

            AddInitialLibs( rdebug.r_map );
            have_rdebug = TRUE;
            ret->conditions |= COND_LIBRARIES;

            /* Set a breakpoint in dynamic linker. That way we can be
             * informed on dynamic library load/unload events.
             */
            ReadMem( pid, &old_ld_bp, rdebug.r_brk, sizeof( old_ld_bp ) );
            Out( "Setting ld breakpoint at " );
            OutNum( rdebug.r_brk );
            Out( " old opcode was " );
            OutNum( old_ld_bp );
            Out( "\n" );
            opcode = BRK_POINT;
            WriteMem( pid, &opcode, rdebug.r_brk, sizeof( opcode ) );
        }
    }
 end:
    CONV_LE_32( ret->stack_pointer.offset );
    CONV_LE_16( ret->stack_pointer.segment );
    CONV_LE_32( ret->program_counter.offset );
    CONV_LE_16( ret->program_counter.segment );
    CONV_LE_16( ret->conditions );
    return( sizeof( *ret ) );
}

unsigned ReqProg_step( void )
{
    return( ProgRun( TRUE ) );
}

unsigned ReqProg_go( void )
{
    return( ProgRun( FALSE ) );
}

unsigned ReqRedirect_stdin( void  )
{
    redirect_stdin_ret *ret;

    ret = GetOutPtr( 0 );
    ret->err = 1;
    return( sizeof( *ret ) );
}
Exemple #23
0
void WriteLittleEndian16( unsigned_16 num )
{
    CONV_LE_16( num );
    WriteNew( &num, sizeof( num ) );
}