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

📄 linuxcore.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:  Linux core file debug support.
*
****************************************************************************/


#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "trpimp.h"
#include "exeelf.h"
//#include "linuxcomm.h"
//#include "misc7386.h"
#include "mad.h"
#include "madregs.h"

extern unsigned FindFilePath( int exe, char *name, char *result );

#ifdef __BIG_ENDIAN__
    #define SWAP_16     CONV_LE_16
    #define SWAP_32     CONV_LE_32
#else
    #define SWAP_16     CONV_BE_16
    #define SWAP_32     CONV_BE_32
#endif

#define NO_FILE         (-1)

enum {
    MH_NONE,
    MH_DEBUGGEE,
    MH_SLIB,
    MH_PROC
};

struct user_regs_struct {
    unsigned_32     ebx;
    unsigned_32     ecx;
    unsigned_32     edx;
    unsigned_32     esi;
    unsigned_32     edi;
    unsigned_32     ebp;
    unsigned_32     eax;
    unsigned_16     ds;
    unsigned_16     __ds;
    unsigned_16     es;
    unsigned_16     __es;
    unsigned_16     fs;
    unsigned_16     __fs;
    unsigned_16     gs;
    unsigned_16     __gs;
    unsigned_32     orig_eax;
    unsigned_32     eip;
    unsigned_16     cs;
    unsigned_16     __cs;
    unsigned_32     eflags;
    unsigned_32     esp;
    unsigned_16     ss;
    unsigned_16     __ss;
};


struct {
    unsigned                    loaded                  : 1;
    unsigned                    ignore_timestamp        : 1;
    unsigned                    read_gdts               : 1;
    unsigned                    dbg32                   : 1;
    unsigned                    mapping_shared          : 1;
    unsigned                    swap_bytes              : 1;
    int                         err_no;
    int                         fd;
    Elf32_Ehdr                  *e_hdr;
    Elf32_Phdr                  *e_phdr;
//    struct      _dumper_hdr     hdr;
} core_info;

#if 0
static void Out( char *str )
{
    write( 1, str, strlen( str ) );
}

static void OutNum( unsigned i )
{
    char numbuff[10];
    char *ptr;

    ptr = numbuff+10;
    *--ptr = '\0';
    do {
        *--ptr = ( i % 10 ) + '0';
        i /= 10;
    } while( i != 0 );
    Out( ptr );
}
#endif


/* Initially it was thought that we could use the ORL to deal with ELF core
 * files. Unfortunately ELF core dumps may not have any sections (just segments),
 * and the ORL is entirely unsuitable for dealing with that as it is all based
 * around the concept of sections. Therefore we have simple ELF parsing code
 * right here - we'd only need a very very small subset of ORL anyway.
 */

/* Read ELF header and check if it's roughly what we're expecting */
int elf_read_hdr( int fd, Elf32_Ehdr *e_hdr )
{
//    Elf32_Phdr  phdr;
//    size_t      i;
    int     result = FALSE;

    lseek( fd, 0, SEEK_SET );
    if( read( fd, e_hdr, sizeof( *e_hdr ) ) >= sizeof( *e_hdr ) &&
        memcmp( e_hdr->e_ident, ELF_SIGNATURE, 4 ) == 0 &&
        e_hdr->e_ident[EI_CLASS] == ELFCLASS32) {
#ifdef __BIG_ENDIAN__
        if( e_hdr->e_ident[EI_DATA] == ELFDATA2LSB )
            core_info.swap_bytes = TRUE;
#else
        if( e_hdr->e_ident[EI_DATA] == ELFDATA2MSB )
            core_info.swap_bytes = TRUE;
#endif
        if( core_info.swap_bytes ) {
            SWAP_16( e_hdr->e_type );
            SWAP_16( e_hdr->e_machine );
            SWAP_32( e_hdr->e_version );
            SWAP_32( e_hdr->e_entry );
            SWAP_32( e_hdr->e_phoff );
            SWAP_32( e_hdr->e_shoff );
            SWAP_32( e_hdr->e_flags );
            SWAP_16( e_hdr->e_ehsize );
            SWAP_16( e_hdr->e_phentsize );
            SWAP_16( e_hdr->e_phnum );
            SWAP_16( e_hdr->e_shentsize );
            SWAP_16( e_hdr->e_shnum );
            SWAP_16( e_hdr->e_shstrndx );
        }
        if( e_hdr->e_phoff != 0 && e_hdr->e_phentsize >= sizeof( Elf32_Phdr ) ) {
            result = TRUE;
        }
    }
    return( result );
}

/* Read ELF program headers */
int elf_read_phdr( int fd, Elf32_Ehdr *e_hdr, Elf32_Phdr **pp_hdr )
{
    Elf32_Phdr      *e_phdr;
    int             i;
    int             result = FALSE;

    *pp_hdr = malloc( sizeof( *e_phdr ) * e_hdr->e_phnum );
    if( *pp_hdr != NULL ) {
        int         error = FALSE;

        e_phdr = *pp_hdr;
        if( lseek( fd, e_hdr->e_phoff, SEEK_SET ) == e_hdr->e_phoff ) {
            for( i = 0; i < e_hdr->e_phnum; i++ ) {
                if( read( fd, e_phdr, sizeof( *e_phdr ) ) < sizeof( *e_phdr ) ) {
                    error = TRUE;
                    break;
                }
                /* Skip any extra bytes that might be present */
                if( lseek( fd, e_hdr->e_phentsize - sizeof( *e_phdr ), SEEK_CUR ) < 0 ) {
                    error = TRUE;
                    break;
                }
                if( core_info.swap_bytes ) {
                    SWAP_32( e_phdr->p_type );
                    SWAP_32( e_phdr->p_offset );
                    SWAP_32( e_phdr->p_vaddr );
                    SWAP_32( e_phdr->p_paddr );
                    SWAP_32( e_phdr->p_filesz );
                    SWAP_32( e_phdr->p_memsz );
                    SWAP_32( e_phdr->p_flags );
                    SWAP_32( e_phdr->p_align );
                }
                e_phdr++;
            }
        }
        if( !error )
            result = TRUE;
    }
    return( result );
}

unsigned ReqGet_sys_config( void )
{
    get_sys_config_ret  *ret;

    ret = GetOutPtr(0);
    ret->sys.mad = MAD_X86;
    ret->sys.os  = OS_LINUX;
    ret->sys.osmajor = 1;
    ret->sys.osminor = 0;
    ret->sys.fpu = X86_387;
    ret->sys.cpu = X86_686;
    ret->sys.huge_shift = 3;
    return( sizeof( *ret ) );
}

unsigned ReqMap_addr( void )
{
    map_addr_req        *acc;
    map_addr_ret        *ret;
    unsigned            index;
    unsigned            seg;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    ret->lo_bound = 0;
    ret->hi_bound = ~(addr48_off)9;

    seg = acc->in_addr.segment;
    switch( seg ) {
    case MAP_FLAT_CODE_SELECTOR:
        seg = 0x04;
        break;
    case MAP_FLAT_DATA_SELECTOR:
        seg = 0x0c;
        break;
    }

    ret->out_addr.offset = acc->in_addr.offset;
    switch( acc->handle ) {
    case MH_DEBUGGEE:
        if( acc->in_addr.segment == MAP_FLAT_DATA_SELECTOR ) {
            index = 0;
        } else {
            index = seg >> 3;
        }
#if 0
        if( core_info.loaded ) {
            ret->out_addr.offset += core_info.segs[ index ].mem_off;
        }
#endif
        break;
    case MH_SLIB:
#if 0
        slib = GetSLibTable( core_info.dbg32 );
        seg += slib.segment - 4;
#endif
        break;
    case MH_PROC:
        seg += 0xE0 - 4;
        break;
    }
    ret->out_addr.segment = 0;
    return( sizeof( *ret ) );
}


unsigned ReqChecksum_mem( void )
{
    checksum_mem_ret    *ret;

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

unsigned ReqRead_mem( void )
{
    read_mem_req        *acc;
    void                *ret;
    unsigned            i;
    unsigned            len;
    Elf32_Phdr          *e_phdr;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    if( !core_info.loaded ) {
        return( 0 );
    }
    len = acc->len;
    e_phdr = core_info.e_phdr;
    for( i = 0; i < core_info.e_hdr->e_phnum ; ++i, ++e_phdr ) {
        int             read_len;
        Elf32_Off       rel_ofs;    // Relative offset within segment

        if( e_phdr->p_type != PT_LOAD ) continue;
        if( (acc->mem_addr.offset < e_phdr->p_vaddr) ||
            (acc->mem_addr.offset > e_phdr->p_vaddr + e_phdr->p_memsz - 1) ) {
            continue;
        }
        rel_ofs  = acc->mem_addr.offset - e_phdr->p_vaddr;
        /* Adjust length if pointing past end of segment */
        if( (acc->mem_addr.offset + len) > (e_phdr->p_vaddr + e_phdr->p_memsz) ) {
            len = rel_ofs + len - e_phdr->p_memsz;
        }
        read_len = len;
        /* Adjust length to read from file if p_memsz > p_filesz */
        if( (acc->mem_addr.offset + len) > (e_phdr->p_vaddr + e_phdr->p_filesz) ) {
            read_len = e_phdr->p_filesz - rel_ofs;
            if( read_len < 0 )
                read_len = 0;
        }
        if( len != 0 ) {
            if( read_len != 0 ) {
                lseek( core_info.fd, e_phdr->p_offset + rel_ofs, SEEK_SET );
                read_len = read( core_info.fd, ret, read_len );
                if( read_len == -1 ) {
                    return( 0 );
                }
            }
            if( read_len < len ) {
                memset( (unsigned_8 *)ret + read_len, 0, len - read_len );
            }
        }
        return( len );
    }
    return( 0 );
}


unsigned ReqWrite_mem( void )
{
    write_mem_ret       *ret;

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


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


unsigned ReqWrite_io( void )
{
    write_io_ret        *ret;

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

static void ReadCPU( struct x86_cpu *r )
{
    struct user_regs_struct     regs;

    memset( r, 0, sizeof( *r ) );
    if( core_info.loaded ) {
// TODO: correctly determine the offset of the register struct in core file
        lseek( core_info.fd, 0x1ec, SEEK_SET );
        if( read( core_info.fd, &regs, sizeof( regs ) ) == sizeof( regs ) ) {
            r->eax = regs.eax;
            r->ebx = regs.ebx;
            r->ecx = regs.ecx;
            r->edx = regs.edx;
            r->esi = regs.esi;
            r->edi = regs.edi;
            r->ebp = regs.ebp;
            r->esp = regs.esp;
            r->eip = regs.eip;
            r->efl = regs.eflags;
            r->cs  = regs.cs;
            r->ds  = regs.ds;
            r->ss  = regs.ss;
            r->es  = regs.es;

⌨️ 快捷键说明

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