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