⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linuxacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Main Linux specific debugger trap file OS access module.
*
****************************************************************************/

/* TODO:
   * complete watchpoints
   * combine global into a struct (like the QNX trap file) to make it a little
     clearer what is global and what not.
   * implement thread support
   * implement corefile post-mortem support
*/

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include "trpimp.h"
#include "trperr.h"
#include "mad.h"
#include "madregs.h"
#include "exeelf.h"
#include "linuxcomm.h"

u_short                 flatCS;
u_short                 flatDS;
pid_t                   pid;
long                    orig_eax;
long                    last_eip;

static pid_t            OrigPGrp;
static int              attached;
static int              last_sig;
static int              at_end;
static struct r_debug   rdebug;         /* Copy of debuggee's r_debug (if present) */
static struct r_debug   *dbg_rdebug;    /* Ptr to r_debug in debuggee's space */
static int              have_rdebug;    /* Flag indicating valid r_debug */
static Elf32_Dyn        *dbg_dyn;       /* VA of debuggee's dynamic section (if present) */
static bp_t             old_ld_bp;


unsigned ReqChecksum_mem( void )
{
    char                buf[256];
    addr_off            offv;
    u_short             length;
    u_short             size;
    int                 i;
    u_short             amount;
    u_long              sum;
    checksum_mem_req    *acc;
    checksum_mem_ret    *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    sum = 0;
    if( pid != 0 ) {
        length = acc->len;
        offv = acc->in_addr.offset;
        for( ;; ) {
            if( length == 0 )
                break;
            size = (length > sizeof( buf )) ? sizeof( buf ) : length;
            amount = ReadMem( pid, buf, offv, size );
            for( i = amount; i != 0; --i )
                sum += buf[ i - 1 ];
            offv += amount;
            length -= amount;
            if( amount != size ) break;
        }
    }
    ret->result = sum;
    return( sizeof( *ret ) );
}

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 );
}

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 ) );
}

#if defined( MD_x86 )
static int GetFlatSegs( u_short *cs, u_short *ds )
{
    user_regs_struct    regs;

    if( ptrace( PTRACE_GETREGS, pid, NULL, &regs ) == 0 ) {
        *cs = regs.cs;
    *ds = regs.ds;
    return( TRUE );
    }
    return( FALSE );
}
#endif

static pid_t RunningProc( char *name, char **name_ret )
{
    pid_t       pidd;
    char        ch;
    char        *start;

    start = name;

    for( ;; ) {
        ch = *name;
        if( ch != ' ' && ch != '\t' ) break;
        ++name;
    }
    if( name_ret != NULL ) *name_ret = name;
    pidd = 0;
    for( ;; ) {
        if( *name < '0' || *name > '9' ) break;
        pidd = (pidd * 10) + (*name - '0');
        ++name;
    }
    if( *name != '\0') return( 0 );
    return( pidd );
}

static int GetExeNameFromPid( pid_t pid, char *buffer, int max_len )
{
    char        procfile[24];
    int         len;

    sprintf( procfile, "/proc/%d/exe", pid );
    len = readlink( procfile, buffer, max_len );
    if( len < 0 )
        len = 0;
    buffer[len] = '\0';
    return( len );
}

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 );
}

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 ) );
}

unsigned ReqSet_break( void )
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -