Beispiel #1
0
/*
 * Given a set of object and library files, prepare to use fuzzy linking.
 * If symbols cannot be collected from a file, 'callback' will be called
 * with the name of the offending file.
 */
void InitFuzzy( const char *objs[], const char *libs[],
                const char *libpaths[], FuzzyInitCallback callback )
/******************************************************************/
{
    unsigned            count;
    orl_handle          o_hnd;
    int                 rc = 1;
    DllToolCallbacks    dllcallbacks;
    ORLSetFuncs( orl_cli_funcs, obj_read, obj_seek, AllocMem, FreeMem );

    /*** Create a hash table ***/
    hashtable = InitHash( HASH_TABLE_SIZE, hash_symbol_name, hash_compare );

    /*** Collect all external symbols from the specified object files ***/
    if( objs != NULL ) {
        /*** Initialize ORL ***/
        o_hnd = ORLInit( &orl_cli_funcs );
        if( o_hnd == NULL ) {
            FatalError( "Got NULL orl_handle." );
        }

        /*** Scan the file(s) ***/
        for( count=0; objs[count]!=NULL; count++ ) {
            if( !handle_obj_file( objs[count], o_hnd ) ) {
                rc = (*callback)( objs[count] );
                if( !rc )  break;
            }
        }

        /*** Tell ORL to go away ***/
        if( ORLFini( o_hnd ) != ORL_OKAY ) {
            Warning( "Error calling ORLFini." );
        }
        free_list( bufflist );
    }
    if( !rc )  return;

    /*** Collect all external symbols from the specified library files ***/
    if( libs != NULL ) {
        /*** Load the WLIB DLL ***/
        dllcallbacks.printmessage = NULL;
        dllcallbacks.printmessageCRLF = print_message_crlf;
        dllcallbacks.printwithinfo2 = print_with_info2;
        dllcallbacks.printwithinfo = print_with_info;
        dllcallbacks.cookie = NULL;
        dllhandle = InitDllTool( DLLTOOL_WLIB, &dllcallbacks );
        if( dllhandle == NULL ) {
            Warning( "Cannot load WLIB DLL -- fuzzy name matching may not work" );
        } else {
            /*** Scan the file(s) ***/
            for( count=0; libs[count]!=NULL; count++ ) {
                if( !handle_lib_file( libs[count], libpaths ) ) {
                    rc = (*callback)( libs[count] );
                    if( !rc )  break;
                }
            }
            FiniDllTool( dllhandle );
        }
    }
}
Beispiel #2
0
static return_val initORL( void )
{
    orl_file_flags      flags;
    orl_machine_type    machine_type;
    orl_return          o_error = ORL_OKAY;
    orl_file_format     type;
    bool                byte_swap;
    ORLSetFuncs( orl_cli_funcs, objRead, objSeek, MemAlloc, MemFree );

    ORLHnd = ORLInit( &orl_cli_funcs );
    if( ORLHnd != ORL_NULL_HANDLE ) {
        type = ORLFileIdentify( ORLHnd, NULL );
        if( type == ORL_UNRECOGNIZED_FORMAT ) {
            PrintErrorMsg( RC_OKAY, WHERE_NOT_COFF_ELF );
            return( RC_ERROR );
        }
        ObjFileHnd = ORLFileInit( ORLHnd, NULL, type );
        if( ObjFileHnd != ORL_NULL_HANDLE ) {
            // check byte order
            flags = ORLFileGetFlags( ObjFileHnd );
            byte_swap = false;
#ifdef __BIG_ENDIAN__
            if( flags & ORL_FILE_FLAG_LITTLE_ENDIAN ) {
                byte_swap = true;
            }
#else
            if( flags & ORL_FILE_FLAG_BIG_ENDIAN ) {
                byte_swap = true;
            }
#endif

            // check intended machine type
            machine_type = GetMachineType();
            switch( machine_type ) {
            // If there's no machine specific code, the CPU we choose shouldn't
            // matter; there are some object files like this.
            case ORL_MACHINE_TYPE_NONE:
            case ORL_MACHINE_TYPE_ALPHA:
                if( DisInit( DISCPU_axp, &DHnd, byte_swap ) != DR_OK ) {
                    ORLFini( ORLHnd );
                    PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                    return( RC_ERROR );
                }
                break;
            case ORL_MACHINE_TYPE_PPC601:
                if( DisInit( DISCPU_ppc, &DHnd, byte_swap ) != DR_OK ) {
                    ORLFini( ORLHnd );
                    PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                    return( RC_ERROR );
                }
                // PAS assembler expects "", not \" for quotes.
                if( (Options & METAWARE_COMPATIBLE) == 0 ) {
                    QuoteChar = '\"';
                }
                break;
            case ORL_MACHINE_TYPE_R3000:
            case ORL_MACHINE_TYPE_R4000:
                if( DisInit( DISCPU_mips, &DHnd, byte_swap ) != DR_OK ) {
                    ORLFini( ORLHnd );
                    PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                    return( RC_ERROR );
                }
                break;
            case ORL_MACHINE_TYPE_I386:
            case ORL_MACHINE_TYPE_I8086:
                if( DisInit( DISCPU_x86, &DHnd, byte_swap ) != DR_OK ) {
                    ORLFini( ORLHnd );
                    PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                    return( RC_ERROR );
                }
                break;
            case ORL_MACHINE_TYPE_AMD64:
                if( DisInit( DISCPU_x64, &DHnd, byte_swap ) != DR_OK ) {
                    ORLFini( ORLHnd );
                    PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                    return( RC_ERROR );
                }
                break;
            case ORL_MACHINE_TYPE_SPARC:
            case ORL_MACHINE_TYPE_SPARCPLUS:
                if( DisInit( DISCPU_sparc, &DHnd, byte_swap ) != DR_OK ) {
                    ORLFini( ORLHnd );
                    PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                    return( RC_ERROR );
                }
                break;
            default:
                ORLFini( ORLHnd );
                PrintErrorMsg( RC_OKAY, WHERE_UNSUPPORTED_PROC );
                return( RC_ERROR );
            }
            return( RC_OKAY );
        } else {
            o_error = ORLGetError( ORLHnd );
            ORLFini( ORLHnd );
            // An "out of memory" error is not necessarily what it seems.
            // The ORL returns this error when encountering a bad or
            // unrecognized object file record.
            if( o_error == ORL_OUT_OF_MEMORY ) {
                PrintErrorMsg( RC_OUT_OF_MEMORY, WHERE_OPENING_ORL );
                return( RC_OUT_OF_MEMORY );
            } else {
                PrintErrorMsg( RC_ERROR, WHERE_OPENING_ORL );
                return( RC_ERROR );
            }
        }
    } else {
        return( RC_OUT_OF_MEMORY );
    }
}
Beispiel #3
0
int main( int argc, char *argv[] )
/********************************/
{
    orl_handle                  o_hnd;
    orl_file_handle             o_fhnd;
    orl_file_format             type;
    orl_file_flags              o_flags;
    FILE                        *fp;
    int                         c;
    char                        *secs[MAX_SECS];
    int                         num_secs = 0;
    ORLSetFuncs( orl_cli_funcs, objRead, objSeek, TRMemAlloc, TRMemFree );

    if( argc < 2 ) {
        printf( "Usage:  dwdump <file>\n" );
        printf( "Where <file> is a COFF, ELF or OMF object file\n" );
        printf( "dwdump reads and dumps DWARF debugging information\n" );
        return( EXIT_SUCCESS );
    }

    dump.sections++;

    fp = fopen( argv[1], "rb" );
    if( fp == NULL ) {
        printf( "Error opening file.\n" );
        return( EXIT_FAILURE );
    }
    TRMemOpen();
    o_hnd = ORLInit( &orl_cli_funcs );
    if( o_hnd == NULL ) {
        printf( "Got NULL orl_handle.\n" );
        return( EXIT_FAILURE );
    }
    type = ORLFileIdentify( o_hnd, fp );
    if( type == ORL_UNRECOGNIZED_FORMAT ) {
        printf( "The object file is not in either ELF, COFF or OMF format." );
        return( EXIT_FAILURE );
    }
    switch( type ) {
    case ORL_OMF:
        printf( "OMF" );
        break;
    case ORL_ELF:
        printf( "ELF" );
        break;
    case ORL_COFF:
        printf( "COFF" );
        break;
    default:
        printf( "Unknown" );
        break;
    }
    printf( " object file.\n" );
    o_fhnd = ORLFileInit( o_hnd, fp, type );
    if( o_fhnd == NULL ) {
        printf( "Got NULL orl_file_handle.\n" );
        return( EXIT_FAILURE );
    }

    o_flags = ORLFileGetFlags( o_fhnd );

#ifdef __BIG_ENDIAN__
    if( o_flags & ORL_FILE_FLAG_LITTLE_ENDIAN ) {
        byte_swap = true;
    }
#else
    if( o_flags & ORL_FILE_FLAG_BIG_ENDIAN ) {
        byte_swap = true;
    }
#endif

    if( num_secs ) {
        for( c = 0; c < num_secs; c++ ) {
            sectionFound = 0;
            if( ORLFileScan( o_fhnd, secs[c], &DoSection ) != ORL_OKAY ) {
                printf( "Error occured in scanning section '%s'.\n", secs[c] );
            }
            if( !sectionFound ) {
                printf( "Section '%s' not found in object.\n", secs[c] );
            }
        }
    } else {
        if( ORLFileScan( o_fhnd, NULL, &DoSection ) != ORL_OKAY ) {
            printf( "Error occured in scanning file.\n" );
            return( EXIT_FAILURE );
        }
    }

    setSects( o_fhnd );

    if( ORLFileFini( o_fhnd ) != ORL_OKAY ) {
        printf( "Error calling ORLFileFini.\n" );
        return( EXIT_FAILURE );
    }
    if( fclose( fp ) ) {
        printf( "Error closing file.\n" );
        return( EXIT_FAILURE );
    }
    if( ORLFini( o_hnd ) != ORL_OKAY ) {
        printf( "Error calling ORLFini.\n" );
    }

    DumpSections();

    freeBuffList();
#ifdef TRMEM
    TRMemPrtList();
#endif
    TRMemClose();
    return( EXIT_SUCCESS );
}