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

📄 elfcore.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        read_len = 0;
        while( read_len < phdr->p_filesz ) {
            lseek( fd, phdr->p_offset + read_len, SEEK_SET );
            if( read( fd, note, sizeof( Elf_Note ) ) != sizeof( Elf_Note ) ) {
                break;
            }
            read_len += sizeof( Elf_Note );
            if( swap ) {
                SWAP_32( note->n_namesz );
                SWAP_32( note->n_descsz );
                SWAP_32( note->n_type );
            }
            if( note->n_type == ntype ) {
                /* Found our note, allocate memory for name and read it */
                name = malloc( note->n_namesz );
                if( name ) {
                    read( fd, name, note->n_namesz );
                    /* Skip over padding so that caller can read note data */
                    skip = ((note->n_namesz + ELF_ROUND) & ~ELF_ROUND) - note->n_namesz;
                    lseek( fd, skip, SEEK_CUR );
                }
                break;
            }
            /* Skip over note contents */
            read_len += (note->n_namesz + ELF_ROUND) & ~ELF_ROUND;
            read_len += (note->n_descsz + ELF_ROUND) & ~ELF_ROUND;
        }
    }
    return( name );
}


static int load_elf_header( const char *core_name, Elf32_Ehdr *ehdr, Elf32_Phdr **pphdr )
{
    int         fd;

    fd = open( core_name, O_RDONLY | O_BINARY );
    if( fd < 0 ) {
        return( NO_FILE );
    }
    if( !elf_read_hdr( fd, ehdr ) ) {
        close( fd );
        fd = NO_FILE;
    } else {
        if( !elf_read_phdr( fd, ehdr, pphdr ) ) {
            close( fd );
            fd = NO_FILE;
        }
    }
    return( fd );
}


static int init_platform_driver( int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr )
{
    void        *ctx;
    int         result = FALSE;
    plat_drv_t  **drv;

    for( drv = drivers; *drv; ++drv ) {
        ctx = (*drv)->init( fd, ehdr, phdr );
        if( ctx ) {
            Core.plat = *drv;
            Core.ctx = ctx;
            result = TRUE;
            break;
        }
    }
    return( result );
}


static void close_platform_driver( void )
{
    if( Core.plat ) {
        Core.plat->done( Core.ctx );
        Core.ctx = NULL;
        Core.plat = NULL;
    }
}


unsigned ReqProg_load( void )
{
    prog_load_req       *acc;
    prog_load_ret       *ret;
    char                *argv;

    Core.mapping_shared = FALSE;
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    argv = GetInPtr( sizeof( *acc ) );
    ret->mod_handle = MH_DEBUGGEE;
    ret->task_id = 0;

    if( argv[0] == '\0' ) {
        ret->err = ENOENT;
        return( sizeof( *ret ) );
    }
    Core.err_no = 0;
    Core.fd = load_elf_header( argv, Core.c_ehdr, &Core.c_phdr );
    if( (Core.fd == NO_FILE) || !init_platform_driver( Core.fd, Core.c_ehdr, Core.c_phdr ) ) {
        ret->err = ENOENT;
        return( sizeof( *ret ) );
    }
    ret->flags = LD_FLAG_IS_STARTED | LD_FLAG_IS_PROT;
    /* Tell debugger to ignore segment values when comparing pointers */
    ret->flags |= LD_FLAG_IS_32 | LD_FLAG_IGNORE_SEGMENTS;
    ret->err = Core.err_no;
    ret->task_id = Core.plat->qpid( Core.ctx );
    if( Core.err_no == 0 ) {
        size_t      len;

        Core.loaded = TRUE;
        /* If we have core, try setting up the executable file */
        len = Core.plat->name( Core.ctx, Core.exe_name, MAX_FULLPATH_LEN );
        if( len ) {
            Core.x_fd = load_elf_header( Core.exe_name, Core.x_ehdr, &Core.x_phdr );
        }
    } else {
        close( Core.fd );
        Core.fd = NO_FILE;
    }
    return( sizeof( *ret ) );
}

unsigned ReqProg_kill( void )
{
    prog_kill_ret       *ret;

    if( Core.loaded ) {
        Core.loaded = FALSE;
        close_platform_driver();
        close( Core.fd );
        if( Core.x_fd != NO_FILE ) {
            close( Core.x_fd );
            Core.x_fd = NO_FILE;
        }
        if( Core.c_phdr ) free( Core.c_phdr );
        if( Core.x_phdr ) free( Core.x_phdr );
        Core.fd = NO_FILE;
    }
    Core.mapping_shared = FALSE;
    ret = GetOutPtr( 0 );
    ret->err = 0;
    return( sizeof( *ret ) );
}

unsigned ReqSet_break( void )
{
    set_break_ret       *ret;

    ret = GetOutPtr( 0 );
    ret->old = 0;
    return( sizeof( *ret ) );
}

unsigned ReqClear_break( void )
{
    return( 0 );
}

unsigned ReqSet_watch( void )
{
    set_watch_ret       *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    ret->multiplier = USING_DEBUG_REG | 1;
    return( sizeof( *ret ) );
}

unsigned ReqClear_watch( void )
{
    return( 0 );
}


unsigned ReqProg_go( void )
{
    prog_go_ret     *ret;

    ret = GetOutPtr( 0 );
    /* Say the process is terminated, which will prevent
     * the debugger from trying anything funny.
     */
    ret->conditions = COND_TERMINATE;
    return( sizeof( *ret ) );
}

unsigned ReqProg_step( void )
{
    return( ReqProg_go() );
}


unsigned ReqGet_message_text( void )
{
    get_message_text_ret    *ret;
    char                    *err_txt;

    ret = GetOutPtr( 0 );
    err_txt = GetOutPtr( sizeof( *ret ) );
    err_txt[0] = '\0';
    ret->flags = MSG_NEWLINE | MSG_ERROR;
    return( sizeof( *ret ) + 1 );
}

unsigned ReqRedirect_stdin( void )
{
    redirect_stdin_ret      *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    return( sizeof( *ret ) );
}

unsigned ReqRedirect_stdout( void )
{
    return( ReqRedirect_stdin() );
}

unsigned ReqFile_string_to_fullpath( void )
{
    unsigned_16                 len;
    char                        *name;
    char                        *fullname;
    file_string_to_fullpath_req *acc;
    file_string_to_fullpath_ret *ret;
    int                         fd;
    Elf32_Ehdr                  ehdr;
    Elf32_Phdr                  *phdr;


    acc  = GetInPtr( 0 );
    name = GetInPtr( sizeof( *acc ) );
    ret  = GetOutPtr( 0 );
    fullname = GetOutPtr( sizeof( *ret ) );
    fullname[0] = '\0';
    len = 0;
    if( acc->file_type != TF_TYPE_EXE ) {
        len = FindFilePath( FALSE, name, fullname );
    } else if( Core.mapping_shared ) {
        len = FindFilePath( TRUE, name, fullname );
    } else {
        fd = load_elf_header( name, &ehdr, &phdr );
        if( (fd != NO_FILE) && init_platform_driver( fd, &ehdr, phdr ) ) {
            len = Core.plat->name( Core.ctx, fullname, MAX_FULLPATH_LEN );
            if( !len ) {
                strcpy( fullname, "unknown" );
                len = strlen( fullname );
            } else {
#if 0
                struct stat     chk;

                name = "/foo/bar"; //Core.hdr.psdata.un.proc.name;
                if( stat( name, &chk ) != 0 ) {
                    chk.st_mtime = 0;
                }
                if( Core.ignore_timestamp || chk.st_mtime == Core.hdr.cmdtime ) {
                    len = StrCopy( name, fullname ) - fullname;
                } else {
                    /* Executable and core file timestaps don't match */
                    len = 0;
                }
#endif
            }
            close( fd );
        }
    }
    if( len == 0 ) {
        ret->err = ENOENT;      /* File not found */
    } else {
        ret->err = 0;
    }
    return( sizeof( *ret ) + len + 1 );
}

unsigned ReqAddr_info( void )
{
    addr_info_req       *acc;
    addr_info_ret       *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->is_32 = TRUE;
    return( sizeof( *ret ) );
}

unsigned ReqMachine_data( void )
{
    machine_data_req    *acc;
    machine_data_ret    *ret;
    unsigned_8          *data;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    data = GetOutPtr( sizeof( *ret ) );
    ret->cache_start = 0;
    ret->cache_end = ~(addr_off)0;
    *data = X86AC_BIG;
    return( sizeof( *ret ) + sizeof( *data ) );
}

unsigned ReqGet_lib_name( void )
{
    get_lib_name_req    *acc;
    get_lib_name_ret    *ret;
    char                *name;

    // TODO: we ought to figure out what shared libs were loaded
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    name = GetOutPtr( sizeof( *ret ) );
    switch( acc->handle ) {
    case MH_NONE:
    case MH_DEBUGGEE:
        ret->handle = MH_SLIB;
        strcpy( name, "/boot/sys/Slib32" );
        break;
    case MH_SLIB:
        ret->handle = MH_PROC;
        strcpy( name, "/boot/sys/Proc32" );
        break;
    default:
        ret->handle = MH_NONE;
        name[0] = '\0';
        break;
    }
    return( sizeof( *ret ) + 1 + strlen( name ) );
}

#if 0
unsigned ReqThread_get_next( void )
{
    thread_get_next_req     *req;
    thread_get_next_ret     *ret;

    req = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    if( req->thread == 0 ) {
        ret->thread = Core.hdr.psdata.pid;
        ret->state = THREAD_THAWED;
    } else {
        ret->thread = 0;
    }
    return( sizeof( *ret ) );
}

unsigned ReqThread_set( void )
{
    thread_set_ret      *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    ret->old_thread = Core.hdr.psdata.pid;
    return( sizeof( *ret ) );
}

unsigned ReqThread_freeze( void )
{
    thread_freeze_ret   *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    return( sizeof( *ret ) );
}

unsigned ReqThread_thaw( void )
{
    thread_thaw_ret     *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    return( sizeof( *ret ) );
}

unsigned ReqThread_get_extra( void )
{
    char                 *ret;

    ret = GetOutPtr( 0 );
    ret[0] = '\0';
    return( strlen( ret ) + 1 );
}
#endif


unsigned ReqGet_err_text( void )
{
    get_err_text_req    *acc;
    char                *err_txt;

    // TODO: get platform specific messages for signals
    err_txt = GetOutPtr( 0 );
    acc = GetInPtr( 0 );
    strcpy( err_txt, "Unknown error" );
    return( strlen( err_txt ) + 1 );
}


trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
    trap_version    ver;

    remote = remote;
    Core.fd   = NO_FILE;
    Core.x_fd = NO_FILE;
    Core.c_ehdr = malloc( sizeof( Elf32_Ehdr ) );
    Core.x_ehdr = malloc( sizeof( Elf32_Ehdr ) );
    if( parm != NULL ) {
        while( *parm != '\0' ) {
            switch( *parm ) {
            case 'I':
            case 'i':
                Core.ignore_timestamp = TRUE;
                break;
            }
            ++parm;
        }
    }
    err[0] = '\0'; /* all ok */
    ver.major = TRAP_MAJOR_VERSION;
    ver.minor = TRAP_MINOR_VERSION;
    ver.remote = FALSE;
    return( ver );
}


void TRAPENTRY TrapFini( void )
{
    if( Core.c_ehdr ) free( Core.c_ehdr );
    if( Core.x_ehdr ) free( Core.x_ehdr );
}

⌨️ 快捷键说明

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