예제 #1
0
/*
 * Deals with LX and LE images.
 * We must try grab information from the object table.
 */
static dip_status FindHLLInLXImage( imp_image_handle *ii, unsigned long nh_off )
{
    union  {
        os2_flat_header flat;
        object_record   obj;
    }                   buf;
    dip_status          rc;

    /* read the header */
    rc = DCReadAt( ii->sym_file, &buf.flat, sizeof( buf.flat ), nh_off );
    if( rc & DS_ERR ) {
        return( rc );
    }
    rc = DS_FAIL;
    if( buf.flat.debug_off && buf.flat.debug_len ) {
        ii->is_32bit = 1;
        rc = FoundHLLSign( ii, buf.flat.debug_off, buf.flat.debug_len );
        if( rc == DS_OK ) {
            unsigned i;

            /*
             * Get segment info from the object table.
             */
            if ( DCSeek( ii->sym_file, buf.flat.objtab_off + nh_off, DIG_ORG )
              != buf.flat.objtab_off + nh_off ) {
                return( DS_ERR | DS_FSEEK_FAILED );
            }

            ii->seg_count = buf.flat.num_objects;
            ii->segments = DCAlloc( sizeof( hllinfo_seg ) * ii->seg_count );
            if( ii->segments == NULL ) {
                return( DS_ERR | DS_NO_MEM );
            }

            for( i = 0; i < ii->seg_count; i++ ) {
                if( DCRead( ii->sym_file, &buf.obj, sizeof( buf.obj ) )
                 != sizeof( buf.obj )) {
                    return( DS_ERR | DS_FREAD_FAILED );
                }
                ii->segments[i].is_executable = !!( buf.obj.flags & OBJ_EXECUTABLE );
                ii->segments[i].is_16bit = !( buf.obj.flags & OBJ_BIG );
                ii->segments[i].ovl = 0;
                ii->segments[i].map.offset = 0;
                ii->segments[i].map.segment = i + 1;
                ii->segments[i].size = buf.obj.size;
                ii->segments[i].address = buf.obj.addr;
            }
        }
    }
    return( rc );
}
예제 #2
0
/*
 * Checks if there is a tailing HLL signature in the file.
 *
 * This may work not work on executable images because of file alignments
 * imposed by the linker (ilink at least). However, TryFindInImage will
 * deal with those formats, so it doesn't really matter here.
 */
static dip_status TryFindTrailer( imp_image_handle *ii )
{
    hll_trailer         sig;
    unsigned long       pos;

    pos = DCSeek( ii->sym_file, DIG_SEEK_POSBACK( sizeof( sig ) ), DIG_END );
    if( pos == DIG_SEEK_ERROR ) {
        return( DS_ERR | DS_FSEEK_FAILED );
    }
    if( DCRead( ii->sym_file, &sig, sizeof( sig ) ) != sizeof( sig ) ) {
        return( DS_ERR | DS_FREAD_FAILED );
    }
    if( !IsHllSignature( &sig ) ) {
        return( DS_FAIL );
    }

    pos -= sig.offset - sizeof( sig );
    return( FoundHLLSign( ii, pos, sig.offset - sizeof( sig ) ) );
}
예제 #3
0
/*
 * Tries to find the HLL/CV debug info in a image which format we know.
 * This function knows about LX, LE, PE and watcom symfile images.
 */
static dip_status TryFindInImage( imp_image_handle *ii )
{
    union {
        char            sig[HLL_SIG_SIZE]; /* ASSUMES >= 4 */
        unsigned_16     sig_16;
        unsigned_32     sig_32;
        pe_header       pe;
        pe_object       sh;
        debug_directory dbg_dir;
    }                   buf;
    bool                have_mz_header = FALSE;
    unsigned_32         nh_off;
    dip_status          rc;

    /* Read the image header. */
    rc = DCReadAt( ii->sym_file, &buf.sig, sizeof( buf.sig ), 0 );
    if( rc & DS_ERR ) {
        return( rc );
    }
    nh_off = 0;
    if( buf.sig_16 == DOS_SIGNATURE ) {
        have_mz_header = TRUE;
        /* read the new exe header */
        rc = DCReadAt( ii->sym_file, &nh_off, sizeof( nh_off ), NH_OFFSET );
        if( rc & DS_ERR ) {
            return( rc );
        }
        rc = DCReadAt( ii->sym_file, &buf.sig, sizeof( buf.sig ), nh_off );
        if( rc & DS_ERR ) {
            return( rc );
        }
    }

    /*
     * LE/LX executable - Use the debug_off/len members of the header.
     */
    if( buf.sig_16 == OSF_FLAT_LX_SIGNATURE
     || buf.sig_16 == OSF_FLAT_SIGNATURE ) {
        return( FindHLLInLXImage( ii, nh_off ) );
    }

    /*
     * PE executable - Use or scan the debug directory.
     */
    if( buf.sig_32 == PE_SIGNATURE ) {
        return( FindHLLInPEImage( ii, nh_off ) );
    }

    /*
     * NE and MZ executables do not contain any special information
     * in the header. TryFindTrailer() will have to pick up the debug data.
     */
    if( (buf.sig_16 == OS2_SIGNATURE_WORD) || have_mz_header ) {
        ii->is_32bit = 0;
    }

    /*
     * ELF executable - ??????
     */

    /*
     * A watcom .sym file.
     */
    if( IsHllSignature( &buf ) ) {
        return( FoundHLLSign( ii, nh_off, ~0UL ) );
    }

    /* no idea what this is.. */
    return( DS_FAIL );
}
예제 #4
0
/*
 * Deals with 32-bit PE images.
 */
static dip_status FindHLLInPEImage( imp_image_handle *ii, unsigned long nh_off )
{
    dip_status          rc;
    unsigned_32         debug_rva;
    unsigned_32         debug_len;
    unsigned_32         image_base;
    unsigned            i;
    unsigned_32         sh_off;
    union {
        char            sig[HLL_SIG_SIZE]; /* ASSUMES >= 4 */
        unsigned_16     sig_16;
        unsigned_32     sig_32;
        pe_header       pe;
        pe_object       sh;
        debug_directory dbg_dir;
    }                   buf;

    /* read the header */
    rc = DCReadAt( ii->sym_file, &buf.pe, sizeof( buf.pe ), nh_off );
    if( rc & DS_ERR ) {
        return( rc );
    }

    debug_rva = buf.pe.table[ PE_TBL_DEBUG ].rva;
    debug_len = buf.pe.table[ PE_TBL_DEBUG ].size;
    if( !debug_rva || !debug_len ) {
        return( DS_FAIL );
    }
    ii->is_32bit = 1;
    image_base = buf.pe.image_base;

    /*
     * Translate the rva to a file offset and read necessary
     * segment information at the same time.
     */
    ii->seg_count = buf.pe.num_objects;
    ii->segments = DCAlloc( sizeof( hllinfo_seg ) * buf.pe.num_objects );
    if( ii->segments == NULL ) {
        return( DS_ERR | DS_NO_MEM );
    }

    sh_off = nh_off /* vv -- watcom mixes the headers :-( */
           + offsetof( pe_header, flags ) + sizeof( buf.pe.flags )
           + buf.pe.nt_hdr_size;

    for ( i = 0; i < ii->seg_count; i++, sh_off += sizeof( buf.sh ) ) {
        rc = DCReadAt( ii->sym_file, &buf.sh, sizeof( buf.sh ), sh_off );
        if ( rc & DS_ERR ) {
            return( rc );
        }

        /* collect segment info. */
        ii->segments[i].is_executable = !!( buf.sh.flags & PE_OBJ_CODE );
        ii->segments[i].ovl = 0;
        ii->segments[i].map.offset = 0;
        ii->segments[i].map.segment = i + 1;
        ii->segments[i].size = buf.sh.virtual_size; // FIXME: alignment?
        ii->segments[i].address = buf.sh.rva + image_base;

        /* is the debug directory section? */
        if( !ii->bias
         && debug_rva - buf.sh.rva < buf.sh.virtual_size ) {
            unsigned_32 debug_off;
            int         left;
            debug_off = buf.sh.physical_offset + debug_rva - buf.sh.rva;

            /*
             * The IBM linker screw up here. It will omit the debug
             * directory and put the debug info there instead.
             * So, before scanning we'll have to check for any HLL sign.
             */
            rc = DCReadAt( ii->sym_file, &buf.dbg_dir, sizeof( buf.dbg_dir ), debug_off );
            if( rc & DS_ERR ) {
                return( rc );
            }
            if( IsHllSignature( &buf ) ) {
                rc = FoundHLLSign( ii, debug_off, debug_len );
            } else {
                left = debug_len / sizeof( debug_directory );
                if( left < 16 )
                    left = 16;
                for ( ;; ) {
                    if( buf.dbg_dir.debug_type == DEBUG_TYPE_CODEVIEW ) {
                        /* found something? */
                        rc = FoundHLLSign( ii, buf.dbg_dir.data_seek, buf.dbg_dir.data_seek );
                        if( rc == DS_OK || rc & DS_ERR ) {
                            break;
                        }
                    }

                    /* next */
                    --left;
                    if( left <= 0) {
                        break;
                    }
                    if ( DCRead( ii->sym_file, &buf.dbg_dir, sizeof( buf.dbg_dir ) ) != sizeof( buf.dbg_dir ) ) {
                        break;
                    }
                }
            }
            if( rc & DS_ERR ) {
                return( rc );
            }
        }
    }

    return( ii->bias ? DS_OK : DS_FAIL );
}