/* * dump_cv_sstModules - dump CV sstModules at 'offset' from 'base' */ static void dump_cv_sstModules( unsigned_32 base, unsigned_32 offset ) /********************************************************************/ { cv3_module_16 mod; cv3_seginfo_16 seg; bool first = true; Wlseek( base + offset ); Wdputs( "==== sstModules at offset " ); Puthex( offset, 8 ); Wdputslc( "\n" ); Wread( &mod, offsetof( cv3_module_16, name_len ) ); Dump_header( &mod, cv_sstModules_msg ); Wdputs( " module name: \"" ); dump_name( 0 ); Wdputslc( "\"\n" ); if( mod.cSeg ) { while( --mod.cSeg ) { if( !first ) { Wdputslc( " ====\n" ); } Wread( &seg, sizeof( seg ) ); Dump_header( &seg, cv_seg_msg ); first = false; } } Wdputslc( "\n" ); }
/* * dump_hll - dump HLL data at offset 'base' from start of file */ static void dump_hll( unsigned_32 base ) /**************************************/ { hll_trailer header; hll_dirinfo dir_info; hll_dir_entry dir_entry; int i; Wlseek( base ); Wread( &header, sizeof( header ) ); if( memcmp( header.sig, HLL_NB04, HLL_SIG_SIZE ) != 0 ) { return; } Wlseek( base + header.offset ); Wread( &dir_info, sizeof( dir_info ) ); Dump_header( &dir_info , hll_dir_info_msg ); Wdputslc( "\n" ); for( i = 0; i < dir_info.cDir; ++i ) { Wlseek( base + header.offset + dir_info.cbDirHeader + i * dir_info.cbDirEntry ); Wread( &dir_entry, sizeof( dir_entry ) ); Dump_header( &dir_entry, hll_dir_entry_msg ); Wdputslc( "\n" ); dump_hll_subsection( base, &dir_entry ); } }
/* * dump_hll_sstModules - dump HLL sstModules at 'offset' from 'base' */ static void dump_hll_sstModules( unsigned_32 base, unsigned_32 offset ) /*********************************************************************/ { hll_module mod; hll_seginfo seg; bool first = true; Wlseek( base + offset ); Wdputs( "==== sstModules at offset " ); Puthex( offset, 8 ); Wdputslc( "\n" ); Wread( &mod, offsetof( hll_module, name_len ) ); Dump_header( &mod, hll_sstModules_msg ); hll_level = mod.Version >> 8; Wdputs( " module name: \"" ); dump_name( 0 ); Wdputslc( "\"\n" ); if( mod.cSeg ) { while( --mod.cSeg ) { if( !first ) { Wdputslc( " ====\n" ); } Wread( &seg, sizeof( seg ) ); Dump_header( &seg, hll_seg_msg ); first = false; } } Wdputslc( "\n" ); }
/* * Dump the Mach-O command list. */ static void dmp_cmd_list( unsigned_32 start, int n ) { int i; unsigned_32 offset; uint32_t cmd, cmdsize; struct segment_command seg; offset = start + sizeof( struct mach_header ); for( i = 0; i < n; ++i ) { Wlseek( offset ); Wread( &cmd, sizeof( cmd ) ); Wread( &cmdsize, sizeof( cmdsize ) ); Wlseek( offset ); switch( cmd ) { case LC_SEGMENT: Wread( &seg, sizeof( seg ) ); Dump_header( &seg, m_segment_msg ); break; default: Wdputs( "\ncmd = " ); Puthex( cmd, 8 ); Wdputs( "H\ncmdsize = " ); Puthex( cmdsize, 8 ); Wdputs( "H" ); } Wdputslc( "\n" ); offset += cmdsize; Wlseek( offset ); } }
/* * dump_hll_sstPublics - dump HLL sstPublics at 'offset' * from 'base 'containing 'size' bytes */ static void dump_hll_sstPublics( unsigned_32 base, unsigned_32 offset, unsigned_32 size ) /********************************************************************/ { hll_public_32 pub32; unsigned_32 read = 0; unsigned_8 name_len; char name[256]; Wlseek( base + offset ); Wdputs( "==== sstPublics at offset " ); Puthex( offset, 8 ); Wdputslc( "\n" ); while( read < size ) { Wread( &pub32, sizeof( pub32 ) ); name_len = pub32.name_len; Dump_header( &pub32, hll_sstPublics_msg ); read += sizeof( pub32 ); Wread( name, name_len ); name[name_len] = '\0'; Wdputs( " symbol name: \"" ); Wdputs( name ); read += name_len; Wdputslc( "\"\n" ); } Wdputslc( "\n" ); }
/* * dump_section - dump the current section */ void Dump_section( void ) /***********************/ { section_dbg_header sdh; Wread( &sdh, sizeof( section_dbg_header ) ); Wdputs( "Section " ); Putdec( sdh.section_id ); Wdputs( " (off=" ); Puthex( Curr_sectoff, 8 ); Wdputslc( ")\n" ); Wdputslc( "=========================\n" ); Dump_header( (char *)&sdh.mod_offset, sdh_msg ); Wdputslc( "\n" ); currSect = sdh.section_id; if( Debug_options & MODULE_INFO ) { dump_module_info( &sdh ); } if( Debug_options & GLOBAL_INFO ) { dump_global_info( &sdh ); } if( Debug_options & ADDR_INFO ) { dump_addr_info( &sdh ); } } /* dump_section */
/* * Dump the coff object, if any. */ bool Dmp_coff_head( void ) /************************/ { coff_file_header header; Wlseek( Coff_off ); Wread( &header, sizeof( coff_file_header ) ); if( header.cpu_type != IMAGE_FILE_MACHINE_I386 && header.cpu_type != IMAGE_FILE_MACHINE_ALPHA && header.cpu_type != IMAGE_FILE_MACHINE_UNKNOWN && header.cpu_type != IMAGE_FILE_MACHINE_POWERPC ) { return 0; } Banner( "COFF object file" ); Wdputs( "file offset = " ); Puthex( Coff_off, 8 ); Wdputslc( "H\n" ); Wdputslc( "\n" ); Dump_header( (char *)&header, coff_hdr_msg ); DumpCoffHdrFlags( header.flags ); load_string_table( &header ); Wlseek( Coff_off + sizeof(coff_file_header) + header.opt_hdr_size ); dmp_objects( header.num_sections ); unload_string_table(); dmp_symtab( header.sym_table, header.num_symbols ); return 1; }
/* * dump_cv_sstSrcLnSeg - dump sstSrcLnSeg at 'offset' from 'base' */ static void dump_cv_sstSrcLnSeg( unsigned_32 base, unsigned_32 offset ) /*********************************************************************/ { cv_linnum_seg src_ln; cv3_linnum_entry_16 lo_16; Wlseek( base + offset ); Wdputs( "==== sstSrcLnSeg at offset " ); Puthex( offset, 8 ); Wdputslc( "\n" ); Wdputs( " source file: \"" ); dump_name( 2 ); Wdputslc( "\"\n" ); Wread( &src_ln, sizeof( src_ln ) ); Dump_header( &src_ln, cv_sstSrcLnSeg_msg ); while( src_ln.cPair-- ) { Wread( &lo_16, sizeof( lo_16 ) ); Dump_header( &lo_16, cv_lnoff16_msg ); } Wdputslc( "\n" ); }
/* * Dump the ELF header, if any. */ bool Dmp_elf_header( unsigned long start ) /****************************************/ { Wread( &Elf_head, sizeof( Elf32_Ehdr ) ); if( memcmp( Elf_head.e_ident, ELF_SIGNATURE, ELF_SIGNATURE_LEN ) ) { return( 0 ); } Banner( "ELF Header" ); if( start != 0 ) { Wdputs( "File Offset:" ); Puthex( start, 8 ); Wdputslc( "\n" ); } Wdputs( "class (1==32-bit objects, 2==64-bit objs) = " ); Puthex( Elf_head.e_ident[EI_CLASS], 2 ); Wdputslc( "H\ndata (1==little-endian, 2==big-endian) = " ); Puthex( Elf_head.e_ident[EI_DATA], 2 ); Wdputslc( "H\nversion = " ); Puthex( Elf_head.e_ident[EI_VERSION], 2 ); Wdputslc( "H\nOS/ABI type (0==unspecified) = " ); Puthex( Elf_head.e_ident[EI_OSABI], 2 ); Wdputslc( "H\nABI version (0==unspecified) = " ); Puthex( Elf_head.e_ident[EI_ABIVERSION], 2 ); Wdputslc( "H\n" ); if( Elf_head.e_ident[EI_DATA] != NATIVE_ENDIAN ) { Byte_swap = TRUE; /* Byte swap ELF header */ SWAP_16( Elf_head.e_type ); SWAP_16( Elf_head.e_machine ); SWAP_32( Elf_head.e_version ); SWAP_32( Elf_head.e_entry ); SWAP_32( Elf_head.e_phoff ); SWAP_32( Elf_head.e_shoff ); SWAP_32( Elf_head.e_flags ); SWAP_16( Elf_head.e_ehsize ); SWAP_16( Elf_head.e_phentsize ); SWAP_16( Elf_head.e_phnum ); SWAP_16( Elf_head.e_shentsize ); SWAP_16( Elf_head.e_shnum ); SWAP_16( Elf_head.e_shstrndx ); } dmp_hdr_type( Elf_head.e_type ); Dump_header( &Elf_head.e_type, elf_exe_msg ); Wdputslc( "\n" ); dmp_prog_sec( start ); return( 1 ); }
/* * Dump the Resource Table. */ void Dmp_resources( void ) /************************/ { resource_dir_header pe_res_type; Data_off = 0; Wlseek( Res_off ); Wread( &pe_res_type, sizeof( resource_dir_header ) ); Banner( "Resource Directory Table" ); Dump_header( (char *)&pe_res_type.flags, pe_resource_msg ); Wdputslc( "\n" ); Wdputslc( "type id/string name id/string language id\n" ); Wdputslc( "============== ============== ===========\n" ); dmp_res_name_id( pe_res_type.num_name_entries, TRUE ); dmp_res_name_id( pe_res_type.num_id_entries, FALSE ); if( Options_dmp & RESRC_DMP ) { dmp_res_dir(); dmp_res_data(); } }
/* * Dump the Fixup Table. */ void Dmp_fixups( void ) /*********************/ { pe_fixup_header pe_fixup; unsigned_32 offset; offset = Fix_off; Wdputslc( "\n" ); Banner( "Fixup Block Tables" ); for( ;; ) { Wlseek( offset ); Wread( &pe_fixup, sizeof( pe_fixup_header ) ); offset += pe_fixup.block_size; if( pe_fixup.block_size == 0 ) break; Dump_header( (char *)&pe_fixup.page_rva, pe_fixup_msg ); if( Options_dmp & FIX_DMP ) { dmp_type_offset( ( pe_fixup.block_size - sizeof( pe_fixup_header ) ) / 2 ); } Wdputslc( "\n" ); } }
/* * dump_cv - dump CV data at offset 'base' from start of file */ static void dump_cv( unsigned_32 base ) /*************************************/ { hll_trailer header; cv3_dir_entry sst_dir_entry; unsigned_16 num_entries; int i; Wlseek( base ); Wread( &header, sizeof( header ) ); if( memcmp( header.sig, HLL_NB02, HLL_SIG_SIZE ) != 0 ) { return; } Wlseek( base + header.offset ); Wread( &num_entries, sizeof( num_entries ) ); for( i = 0; i < num_entries; ++i ) { Wlseek( base + header.offset + 2 + i * sizeof( sst_dir_entry ) ); Wread( &sst_dir_entry, sizeof( sst_dir_entry ) ); Dump_header( &sst_dir_entry, cv_dir_entry_msg ); Wdputslc( "\n" ); dump_cv_subsection( base, &sst_dir_entry ); } }
/* * dump_hll_sstHLLSrc - dump HLL sstHLLSrc at 'offset' from 'base' * containing 'size' bytes */ static void dump_hll_sstHLLSrc( unsigned_32 base, unsigned_32 offset, unsigned_32 size ) /*******************************************************************/ { Wlseek( base + offset ); Wdputs( "==== sstHLLSrc at offset " ); Puthex( offset, 8 ); Wdputslc( "\n" ); #if 0/* FIXME: structure changes broke this. */ if( hll_level >= 0x04 ) { hl4_linnum_first_lines first_entry; unsigned_32 count = 0; while( count < size ) { Wread( &first_entry, sizeof( first_entry ) ); Dump_header( &first_entry, hl4_linnum_first_msg ); count += sizeof( first_entry ); if( first_entry.core.entry_type == 0x03 ) { hl4_filetab_entry ftab_entry; unsigned_32 index; Wread( &ftab_entry, sizeof( ftab_entry ) ); Dump_header( &ftab_entry, hl4_filetab_entry_msg ); count += sizeof( ftab_entry ); for( index = 0; index < ftab_entry.numFiles; ++index ) { Wdputs( " file index: " ); Puthex( index, 4 ); Wdputs( "H name: \"" ); count += dump_name( 0 ); Wdputslc( "\"\n" ); } Wdputslc( "\n" ); } else if( first_entry.core.entry_type == 0x00 ) { hl3_linnum_entry lnum_entry; unsigned_32 index; for( index = 0; index < first_entry.num_line_entries; ++index ) { Wread( &lnum_entry, sizeof( lnum_entry ) ); count += sizeof( lnum_entry ); Dump_header( &lnum_entry, hll_linnum_entry_msg ); } Wdputslc( "\n" ); } else { Wdputslc( "unsupported linnum table entry format\n" ); } } } else { hl2_linnum_first first_entry; unsigned_32 index; Wread( &first_entry, sizeof( first_entry ) ); Dump_header( &first_entry, hl3_linnum_first_msg ); if( first_entry.entry_type == 0x00 ) { hl3_filetab_entry ftab_entry; hl3_linnum_entry lnum_entry; for( index = 0; index < first_entry.num_entries; ++index ) { Wread( &lnum_entry, sizeof( lnum_entry ) ); Dump_header( &lnum_entry, hll_linnum_entry_msg ); } Wread( &ftab_entry, sizeof( ftab_entry ) ); Dump_header( &ftab_entry, hl3_filetab_entry_msg ); for( index = 0; index < ftab_entry.numFiles; ++index ) { Wdputs( " file index: " ); Puthex( index, 4 ); Wdputs( "H name: \"" ); dump_name( 0 ); Wdputslc( "\"\n" ); } Wdputslc( "\n" ); } else { Wdputslc( "unsupported linnum table entry format\n" ); } } #endif }
/* * Dump the Nlm Executable Header, if any. */ bool Dmp_nlm_head( void ) /***********************/ { unsigned_32 offset; nlm_header_3 nlm_head3; nlm_header_4 nlm_head4; bool extend; char nlm_name[256]; Wlseek( 0 ); Wread( &Nlm_head, sizeof( Nlm_head.signature ) ); if( memcmp( Nlm_head.signature, NLM_SIGNATURE, sizeof( NLM_SIGNATURE ) - 1 ) ) { return( 0 ); } Wread( (char *)&Nlm_head + sizeof( Nlm_head.signature ), sizeof( nlm_header ) - sizeof( Nlm_head.signature ) ); Banner( "Novell EXE Header" ); Wdputs( "version number = " ); Puthex( Nlm_head.version, 8 ); Wdputslc( "H\n" ); Wdputs( "module name = " ); memcpy( nlm_name, &Nlm_head.moduleName[1], Nlm_head.moduleName[0] ); nlm_name[ (int)Nlm_head.moduleName[0] ] = '\0'; Wdputs( nlm_name ); Wdputslc( "\n" ); Dump_header( (char *)&Nlm_head.codeImageOffset, nlm_exe_msg ); offset = dmp_nlm_head2(); offset += sizeof( nlm_header ); Wlseek( offset ); Wread( &nlm_head3, sizeof( nlm_header_3 ) ); if( !memcmp( nlm_head3.versionSignature, VERSION_SIGNATURE, VERSION_SIGNATURE_LENGTH ) ) { Dump_header( (char *)&nlm_head3.majorVersion, nlm_date_msg ); offset += sizeof( nlm_header_3 ); } Wlseek( offset ); Wread( &nlm_head4, sizeof( nlm_header_4 ) ); if( !memcmp( nlm_head4.copyrightSignature, COPYRIGHT_SIGNATURE, COPYRIGHT_SIGNATURE_LENGTH ) ) { Wdputs( "copy right string = " ); Wdputs( nlm_head4.copyrightString ); Wdputslc( "\n" ); offset += sizeof( unsigned_8 ) + COPYRIGHT_SIGNATURE_LENGTH; offset += nlm_head4.copyrightLength; } Wlseek( offset ); extend = FALSE; Wread( &Nlm_ext_head, sizeof( extended_nlm_header ) ); if( !memcmp( Nlm_ext_head.stamp, EXTENDED_NLM_SIGNATURE, EXTENDED_NLM_SIGNATURE_LENGTH ) ) { Dump_header( (char *)&Nlm_ext_head.languageID, nlm_ext_msg ); extend = TRUE; } if( Nlm_head.customDataSize != 0 ) { Wdputslc( "\n" ); Banner( "Custom Data" ); Dmp_seg_data( Nlm_head.customDataOffset, Nlm_head.customDataSize ); } dmp_module_dep(); if( Options_dmp & FIX_DMP ) { dmp_reloc_fixup(); } dmp_external_ref(); dmp_public_entry(); Wdputslc( "\n" ); if( extend ) { dmp_extended(); } return( 1 ); }
/* * Dump the program and section headers. */ static void dmp_prog_sec( unsigned_32 start ) /*******************************************/ { Elf32_Phdr elf_prog; Elf32_Shdr elf_sec; unsigned_32 offset; char *string_table; int i; // grab the string table, if it exists if( Options_dmp & DEBUG_INFO ) { set_dwarf( start ); } if( Elf_head.e_shstrndx ) { offset = Elf_head.e_shoff + Elf_head.e_shstrndx * Elf_head.e_shentsize+start; Wlseek( offset ); Wread( &elf_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &elf_sec ); string_table = Wmalloc( elf_sec.sh_size ); Wlseek( elf_sec.sh_offset + start ); Wread( string_table, elf_sec.sh_size ); } else { string_table = 0; } if( Elf_head.e_phnum ) { Banner( "ELF Program Header" ); offset = Elf_head.e_phoff + start; for( i = 0; i < Elf_head.e_phnum; i++ ) { Wdputs( " Program Header #" ); Putdec( i + 1 ); Wdputslc( "\n" ); if( start != 0 ) { Wdputs("File Offset:"); Puthex( offset, 8 ); Wdputslc( "\n"); } Wlseek( offset ); Wread( &elf_prog, sizeof( Elf32_Phdr ) ); swap_phdr( &elf_prog ); // elf_prog.p_offset += start; //Relocate file pos offset += sizeof( Elf32_Phdr ); Data_count++; dmp_prog_type( elf_prog.p_type ); Dump_header( &elf_prog, elf_prog_msg ); dmp_prog_flgs( elf_prog.p_flags ); if( Options_dmp & (DOS_SEG_DMP | OS2_SEG_DMP) ) { if( Segspec == 0 || Segspec == Data_count ) { Dmp_seg_data( elf_prog.p_offset + start, elf_prog.p_filesz ); } } else if( elf_prog.p_type == PT_NOTE ) { dmp_sec_note( elf_prog.p_offset + start, elf_prog.p_filesz ); } Wdputslc( "\n" ); } } if( Elf_head.e_shnum ) { Banner( "ELF Section Header" ); offset = Elf_head.e_shoff+start; for( i = 0; i < Elf_head.e_shnum; i++ ) { Wlseek( offset ); Wread( &elf_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &elf_sec ); // elf_sec.sh_offset += start; // relocate file pos Wdputs( " Section Header #" ); Putdec( i ); if( string_table ) { Wdputs( " \"" ); Wdputs( &(string_table[elf_sec.sh_name]) ); Wdputs( "\"" ); } Wdputslc( "\n" ); if( start != 0 ) { Wdputs( "File Offset:" ); Puthex( offset, 8 ); Wdputslc( "\n" ); } dmp_sec_type( elf_sec.sh_type ); Dump_header( &elf_sec.sh_name, elf_sec_msg ); dmp_sec_flgs( elf_sec.sh_flags ); if( Options_dmp & FIX_DMP ) { if( elf_sec.sh_type==SHT_REL || elf_sec.sh_type==SHT_RELA ) { Elf32_Shdr rel_sec; Elf32_Rela elf_rela; int loc, ctr, rel_size; Wdputs( "relocation information for section #" ); Putdec( elf_sec.sh_info ); Wlseek( Elf_head.e_shoff + start + Elf_head.e_shentsize * elf_sec.sh_info ); Wread( &rel_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &rel_sec ); if( string_table ) { Wdputs( " \"" ); Wdputs( &string_table[rel_sec.sh_name] ); Wdputs( "\"" ); } else { Wdputs( " no_name (no associated string table)" ); } Wdputslc( ":\n" ); Wdputs( "symbol index refers to section #" ); Putdec( elf_sec.sh_link ); Wdputslc( "\n" ); Wdputslc( "Offset Sym Idx Addend Type Offset Sym Idx Addend Type\n" ); rel_size = (elf_sec.sh_type == SHT_REL ? sizeof( Elf32_Rel ) : sizeof( Elf32_Rela )); for( loc = 0, ctr = 0; loc < elf_sec.sh_size; loc += rel_size, ctr++ ) { Wlseek( elf_sec.sh_offset + start + loc ); Wread( &elf_rela, rel_size ); Puthex( elf_rela.r_offset, 8 ); Wdputc( ' ' ); Puthex( ELF32_R_SYM( elf_rela.r_info ), 8 ); Wdputc( ' ' ); if( elf_sec.sh_type == SHT_RELA ) { Puthex( elf_rela.r_addend, 8 ); } else { Wdputs( "n/a " ); } Wdputc( ' ' ); Puthex( ELF32_R_TYPE( elf_rela.r_info ), 2 ); if( ctr % 2 == 1 ) { Wdputslc( "\n" ); } else { Wdputs( " " ); } } if( ctr % 2 != 0 ) { Wdputslc( "\n" ); } } } if( Options_dmp & DEBUG_INFO ) { Wdputslc( "\n" ); if( string_table ) { dmp_sec_data( &(string_table[elf_sec.sh_name]), elf_sec.sh_type, elf_sec.sh_offset+start, elf_sec.sh_size ); } else { dmp_sec_data( NULL, elf_sec.sh_type, elf_sec.sh_offset+start, elf_sec.sh_size ); } } else if( Options_dmp & OS2_SEG_DMP ) { if( elf_sec.sh_size && elf_sec.sh_type != SHT_NOBITS ) { Wdputslc( "Section dump:\n" ); Dmp_seg_data( elf_sec.sh_offset + start, elf_sec.sh_size ); } } Wdputslc( "\n" ); offset += Elf_head.e_shentsize; } } if( string_table ) { free( string_table ); } }