Beispiel #1
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 );
    }
}
Beispiel #2
0
unsigned long RemoteSeek( sys_handle hdl, unsigned long pos, unsigned method )
{
    file_seek_req       acc;
    file_seek_ret       ret;
    int                 locfile;

    if( SuppFileId == 0 ) return( 0 );

    /* Seek on local copy too (if available) */
    locfile = GetCachedHandle( hdl );
    if( locfile != -1 ) {
        lseek( locfile, pos, method );
    }

    SUPP_FILE_SERVICE( acc, REQ_FILE_SEEK );
    acc.handle = hdl;
    /* Magic again! The seek mode mapped exactly to our definition! */
    acc.mode = method;
    acc.pos = pos;
    CONV_LE_32( acc.handle );
    CONV_LE_32( acc.pos );
    TrapSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
    CONV_LE_32( ret.pos );
    CONV_LE_32( ret.err );
    if( ret.err != 0 ) {
        StashErrCode( ret.err, OP_REMOTE );
        return( -1UL );
    } else {
        return( ret.pos );
    }
}
Beispiel #3
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 ) );
    }
}
Beispiel #4
0
sys_handle RemoteOpen( char *name, open_access mode )
{
    mx_entry            in[2];
    mx_entry            out[1];
    file_open_req       acc;
    file_open_ret       ret;
    int                 locfile;

    if( SuppFileId == 0 ) return( NIL_SYS_HANDLE );

    SUPP_FILE_SERVICE( acc, REQ_FILE_OPEN );
    acc.mode = 0;
    if( mode & OP_READ )
        acc.mode |= TF_READ;
    if( mode & OP_WRITE )
        acc.mode |= TF_WRITE;
    if( mode & OP_CREATE ) {
        acc.mode |= TF_CREATE;
        if( mode & OP_EXEC )
            acc.mode |= TF_EXEC;
    }
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = name;
    in[1].len = strlen( name ) + 1;
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    TrapAccess( 2, &in, 1, &out );
    CONV_LE_32( ret.err );
    CONV_LE_32( ret.handle );
    if( ret.err != 0 ) {
        StashErrCode( ret.err, OP_REMOTE );
            return( NIL_SYS_HANDLE );
    } else {
        /* See if the file is available locally. If so, open it here as
         * well as on the remote machine.
         */
        // TODO: check if remote file is the same!

#ifdef LOGGING
        fprintf( logf, "Trying to open local copy of remote file (remote handle %d)\n", ret.handle );
        fprintf( logf, "%s\n", name );
#endif

        if( (locfile = open(name, O_RDONLY | O_BINARY, 0 )) != -1 ) {
            if(AddCachedHandle( locfile, ret.handle ) != 0 )
                close( locfile );
#ifdef LOGGING
            fprintf(logf, "Success\n", name);
#endif
        }
        return( ret.handle );
    }
}
Beispiel #5
0
static void fix_rel_byte_order( elf_file_handle elf_file_hnd, Elf32_Rel *e_rel )
{
    // 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_rel->r_offset );
        CONV_BE_32( e_rel->r_info );
    } else {
        CONV_LE_32( e_rel->r_offset );
        CONV_LE_32( e_rel->r_info );
    }
}
Beispiel #6
0
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 ) );
}
Beispiel #7
0
static void fix_sym_byte_order( elf_file_handle elf_file_hnd, Elf32_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 );
        CONV_BE_32( e_sym->st_value );
        CONV_BE_32( e_sym->st_size );
        CONV_BE_16( e_sym->st_shndx );
    } else {
        CONV_LE_32( e_sym->st_name );
        CONV_LE_32( e_sym->st_value );
        CONV_LE_32( e_sym->st_size );
        CONV_LE_16( e_sym->st_shndx );
    }
}
Beispiel #8
0
unsigned ReqFile_string_to_fullpath( void )
{
    file_string_to_fullpath_req *acc;
    file_string_to_fullpath_ret *ret;
    int                         exe;
    int                         len;
    char                        *name;
    char                        *fullname;
    pid_t                       pidd;

    pidd = 0;
    acc = GetInPtr( 0 );
    name = GetInPtr( sizeof( *acc ) );
    ret = GetOutPtr( 0 );
    fullname = GetOutPtr( sizeof( *ret ) );
    exe = ( acc->file_type == TF_TYPE_EXE ) ? TRUE : FALSE;
    if( exe ) {
        pidd = RunningProc( name, &name );
    }
    if( pidd != 0 ) {
        len = GetExeNameFromPid( pidd, fullname, PATH_MAX );
    } else {
        len = FindFilePath( exe, name, fullname );
    }
    if( len == 0 ) {
        ret->err = ENOENT;      /* File not found */
    } else {
        ret->err = 0;
    }
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) + len + 1 );
}
Beispiel #9
0
trap_retval ReqFile_close( void )
{
    file_close_req      *acc;
    file_close_ret      *ret;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->handle );
    ret = GetOutPtr( 0 );
    if( close( acc->handle ) != -1 ) {
        errno = 0;
        ret->err = 0;
    } else {
        ret->err = errno;
    }
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}
Beispiel #10
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 );
}
Beispiel #11
0
trap_retval ReqFile_seek( void )
{
    file_seek_req       *acc;
    file_seek_ret       *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->pos = lseek( acc->handle, acc->pos, acc->mode );
    if( ret->pos != ((off_t)-1) ) {
        errno = 0;
        ret->err = 0;
    } else {
        ret->err = errno;
    }
    CONV_LE_32( ret->pos );
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}
Beispiel #12
0
unsigned_32 GetLInt( void )
/*************************/
{
    unsigned_32 dword;

    dword = *(unsigned_32 *)RecPtr;
    CONV_LE_32( dword );
    RecPtr += 4;
    return( dword );
}
Beispiel #13
0
//NYI: The 'bool executable' should be changed to allow different file types
unsigned RemoteStringToFullName( bool executable, char *name, char *res,
                                 unsigned res_len )
{
    mx_entry            in[2];
    mx_entry            out[2];
    file_string_to_fullpath_req acc;
    file_string_to_fullpath_ret ret;
    handle              h;

    if( SuppFileId == 0 ) {
        h = LclStringToFullName( name, strlen( name ), res );
        if( h == NIL_HANDLE ) return( 0 );
        FileClose( h );
        return( strlen( res ) );
    }
#ifdef __NT__
    // check whether short filename is necessary
    switch( SysConfig.os ) {
    case OS_AUTOCAD:
    case OS_DOS:
    case OS_RATIONAL:
    case OS_PHARLAP:
    case OS_WINDOWS:
        // convert long file name to short "DOS" compatible form
        {
            char short_filename[MAX_PATH + 1] = "";

            GetShortPathNameA( name, short_filename, MAX_PATH );
            if( strlen( short_filename ) != 0 ) {
                strcpy( name, short_filename );
            }
        }
        break;
    }
#endif
    SUPP_FILE_SERVICE( acc, REQ_FILE_STRING_TO_FULLPATH );
    acc.file_type = ( executable ? TF_TYPE_EXE : TF_TYPE_PRS );
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = name;
    in[1].len = strlen( name ) + 1;
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    out[1].ptr = res;
    out[1].len = res_len;
    TrapAccess( 2, &in, 2, &out );
    CONV_LE_32( ret.err );
    if( ret.err != 0 ) {
        *res = NULLCHAR;
        return( 0 );
    } else {
        return( strlen( res ) );
    }
}
Beispiel #14
0
/*
 * AccGetLibName - get lib name of current module
 */
trap_retval ReqGet_lib_name( void )
{
    get_lib_name_req    *acc;
    get_lib_name_ret    *ret;
    char                *name;
    unsigned            i;
    trap_elen           ret_len;

    acc = GetInPtr( 0 );
    CONV_LE_32( acc->mod_handle );
    ret = GetOutPtr( 0 );
    name = GetOutPtr( sizeof( *ret ) );

    ret->mod_handle = 0;
    ret_len = sizeof( *ret );

    for( i = 0; i < ModuleTop; ++i ) {
        if( moduleInfo[i].newly_unloaded ) {
            Out( "(newly unloaded) " );
            ret->mod_handle = i;
            *name = '\0';
            moduleInfo[i].newly_unloaded = false;
            ++ret_len;
            break;
        } else if( moduleInfo[i].newly_loaded ) {
            Out( "(newly loaded) " );
            ret->mod_handle = i;
            strcpy( name, moduleInfo[i].filename );
            moduleInfo[i].newly_loaded = false;
            ret_len += strlen( name ) + 1;
            break;
        }
    }
    Out( "ReqGet_lib_name: in handle " );
    OutNum( acc->mod_handle );
    Out( " out handle " );
    OutNum( ret->mod_handle );
    Out( "\n" );
    CONV_LE_32( ret->mod_handle );
    return( ret_len );
}
Beispiel #15
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 );
}
Beispiel #16
0
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 ) );
}
Beispiel #17
0
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 );
}
Beispiel #18
0
trap_retval ReqFile_erase( void )
{
    file_erase_ret      *ret;

    ret = GetOutPtr( 0 );
    if( unlink( (char *)GetInPtr( sizeof( file_erase_req ) ) ) != 0 ) {
        ret->err = errno;
    } else {
        errno = 0;
        ret->err = 0;
    }
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}
Beispiel #19
0
unsigned RemoteClose( sys_handle hdl )
{
    file_close_req      acc;
    file_close_ret      ret;
    int                 locfile;

    if( SuppFileId == 0 ) return( 0 );

    locfile = GetCachedHandle( hdl );
    if( locfile != -1 ) {
        close( locfile );
        DelCachedHandle( locfile );
#ifdef LOGGING
        fprintf( logf, "Closing remote file handle %d\n", hdl );
#endif
    }

    SUPP_FILE_SERVICE( acc, REQ_FILE_CLOSE );
    acc.handle = hdl;
    CONV_LE_32( acc.handle );
    TrapSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
    CONV_LE_32( ret.err );
    return( StashErrCode( ret.err, OP_REMOTE ) );
}
Beispiel #20
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 ) );
}
Beispiel #21
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 );
}
Beispiel #22
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 );
    }
}
Beispiel #23
0
unsigned RemoteErase( char *name )
{
    mx_entry            in[2];
    mx_entry            out[1];
    file_erase_req      acc;
    file_erase_ret      ret;

    if( SuppFileId == 0 ) return( 0 );
    SUPP_FILE_SERVICE( acc, REQ_FILE_ERASE );
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = name;
    in[1].len = strlen( name ) + 1;
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    TrapAccess( 2, &in, 1, &out );
    CONV_LE_32( ret.err );
    return( StashErrCode( ret.err, OP_REMOTE ) );
}
Beispiel #24
0
long RemoteFork( char *cmd, unsigned len )
{
    mx_entry            in[2];
    mx_entry            out[1];
    file_run_cmd_req    acc;
    file_run_cmd_ret    ret;

    if( SuppFileId == 0 ) return( 0 );
    SUPP_FILE_SERVICE( acc, REQ_FILE_RUN_CMD );
    acc.chk_size = CheckSize;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = cmd;
    in[1].len = len;
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    TrapAccess( 2, &in, 1, &out );
    CONV_LE_32( ret.err );
    return( StashErrCode( ret.err, OP_REMOTE ) );
}
Beispiel #25
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 ) );
}
Beispiel #26
0
unsigned ReqProg_kill( void )
{
    prog_kill_ret   *ret;

    if( pid != 0 && !at_end ) {
        if( attached ) {
            ptrace( PTRACE_DETACH, pid, NULL, NULL );
            attached = FALSE;
        } else {
            int status;

            ptrace( PTRACE_KILL, pid, NULL, NULL );
            waitpid( pid, &status, 0 );
        }
    }
    DelProcess();
    at_end = FALSE;
    pid = 0;
    ret = GetOutPtr( 0 );
    ret->err = 0;
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}
Beispiel #27
0
void WriteLittleEndian32( unsigned_32 num )
{
    CONV_LE_32( num );
    WriteNew( &num, sizeof( num ) );
}
Beispiel #28
0
unsigned ReqProg_load( void )
{
    char                        **args;
    char                        *parms;
    char                        *parm_start;
    int                         i;
    char                        exe_name[PATH_MAX];
    char                        *name;
    pid_t                       save_pgrp;
    prog_load_req               *acc;
    prog_load_ret               *ret;
    unsigned                    len;
    int                         status;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );

    last_sig = -1;
    have_rdebug = FALSE;
    dbg_dyn = NULL;
    at_end = FALSE;
    parms = (char *)GetInPtr( sizeof( *acc ) );
    parm_start = parms;
    len = GetTotalSize() - sizeof( *acc );
    if( acc->true_argv ) {
        i = 1;
        for( ;; ) {
            if( len == 0 ) break;
            if( *parms == '\0' ) {
                i++;
            }
            ++parms;
            --len;
        }
        args = alloca( i * sizeof( *args ) );
        parms = parm_start;
        len = GetTotalSize() - sizeof( *acc );
        i = 1;
        for( ;; ) {
            if( len == 0 ) break;
            if( *parms == '\0' ) {
                args[i++] = parms + 1;
            }
            ++parms;
            --len;
        }
        args[i - 1] = NULL;
    } else {
        while( *parms != '\0' ) {
            ++parms;
            --len;
        }
        ++parms;
        --len;
        i = SplitParms( parms, NULL, len );
        args = alloca( (i + 2)  * sizeof( *args ) );
        args[SplitParms( parms, &args[1], len ) + 1] = NULL;
    }
    args[0] = parm_start;
    attached = TRUE;
    pid = RunningProc( args[0], &name );
    if( pid == 0 || ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
        attached = FALSE;
        args[0] = name;
        if( FindFilePath( TRUE, args[0], exe_name ) == 0 ) {
            exe_name[0] = '\0';
        }
        save_pgrp = getpgrp();
        setpgid( 0, OrigPGrp );
        pid = fork();
        if( pid == -1 )
            return( 0 );
        if( pid == 0 ) {
            if( ptrace( PTRACE_TRACEME, 0, NULL, NULL ) < 0 ) {
                exit( 1 );
            }
            execve( exe_name, (const char **)args, (const char **)dbg_environ );
            exit( 1 ); /* failsafe */
        }
        setpgid( 0, save_pgrp );
    } else if( pid ) {
        GetExeNameFromPid( pid, exe_name, PATH_MAX );
    }
    ret->flags = 0;
    ret->mod_handle = 0;
    if( (pid != -1) && (pid != 0) ) {
        int status;

        ret->task_id = pid;
        ret->flags |= LD_FLAG_IS_PROT | LD_FLAG_IS_32;
        /* wait until it hits _start (upon execve) or
           gives us a SIGSTOP (if attached) */
        if( waitpid( pid, &status, 0 ) < 0 )
            goto fail;
        if( !WIFSTOPPED( status ) )
            goto fail;
        if( attached ) {
            ret->flags |= LD_FLAG_IS_STARTED;
            if( WSTOPSIG( status ) != SIGSTOP )
                goto fail;
        } else {
            if( WSTOPSIG( status ) != SIGTRAP )
                goto fail;
        }

#if defined( MD_x86 )
        if( !GetFlatSegs( &flatCS, &flatDS ) )
            goto fail;
#endif

        dbg_dyn = GetDebuggeeDynSection( exe_name );
        AddProcess();
        errno = 0;
    }
    ret->err = errno;
    if( ret->err != 0 ) {
        pid = 0;
    }
    CONV_LE_32( ret->err );
    CONV_LE_32( ret->task_id );
    CONV_LE_32( ret->mod_handle );
    return( sizeof( *ret ) );
fail:
    if( pid != 0 && pid != -1 ) {
        if( attached ) {
            ptrace( PTRACE_DETACH, pid, NULL, NULL );
            attached = FALSE;
        } else {
            ptrace( PTRACE_KILL, pid, NULL, NULL );
            waitpid( pid, &status, 0 );
        }
    }
    pid = 0;
    CONV_LE_32( ret->err );
    CONV_LE_32( ret->task_id );
    CONV_LE_32( ret->mod_handle );
    return( 0 );
}
Beispiel #29
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 ) );
}
Beispiel #30
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 ) );
}