static void set_dwarf( unsigned_32 start ) /****************************************/ { Elf32_Shdr elf_sec; unsigned_32 offset; char *string_table; int i; uint sect; unsigned_32 sectsizes[DR_DEBUG_NUM_SECTS]; unsigned_32 sections[DR_DEBUG_NUM_SECTS]; // grab the string table, if it exists if( !Elf_head.e_shstrndx ) { return; // no strings no dwarf } if( Elf_head.e_shnum == 0 ) { return; // no sections no dwarf } memset( sections, 0, DR_DEBUG_NUM_SECTS * sizeof( unsigned_32 ) ); memset( sectsizes, 0, DR_DEBUG_NUM_SECTS * sizeof( unsigned_32 ) ); 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 ); for( i = 0; i < Elf_head.e_shnum; i++ ) { Wlseek( Elf_head.e_shoff + i * Elf_head.e_shentsize + start ); Wread( &elf_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &elf_sec ); if( elf_sec.sh_type == SHT_PROGBITS ) { sect = Lookup_section_name( &string_table[elf_sec.sh_name] ); if ( sect < DW_DEBUG_MAX ) { sections[sect] = elf_sec.sh_offset + start; sectsizes[sect] = elf_sec.sh_size; } } } free( string_table ); for( i = 0; i < DR_DEBUG_NUM_SECTS; i += 1 ) { Sections[i].cur_offset = 0; Sections[i].max_offset = sectsizes[i]; if( sectsizes[i] != 0 ) { Wlseek( sections[i] ); Sections[i].data = Wmalloc( sectsizes[i] ); if( Sections[i].data == NULL ) { Wdputslc( "Not enough memory\n" ); exit( 1 ); } Wread( Sections[i].data, sectsizes[i] ); } } }
/* * Dump public entry (export) table. */ static void dmp_public_entry( void ) /**********************************/ { unsigned_32 i; unsigned_8 len; char *name; unsigned_32 addr; if( Nlm_head.numberOfPublics == 0 ) { return; } Wdputslc( "\n" ); Wlseek( Nlm_head.publicsOffset ); Banner( "Public Entry (Export) Table" ); Wdputslc( "80000000H = symbol is in code\n" ); Wdputslc( " Address Name\n" ); Wdputslc( " ======= ====\n" ); for( i = 0; i < Nlm_head.numberOfPublics; i++ ) { Wread( &len, sizeof( unsigned_8 ) ); name = Wmalloc( len ); Wread( name, len ); name[len] = '\0'; Wread( &addr, sizeof( unsigned_32 ) ); Wdputs( " " ); Puthex( addr, 8 ); Wdputs( " " ); Wdputs( name ); Wdputslc( "\n" ); } }
/* * Dump Segment Table */ void Dmp_seg_tab( void ) /**********************/ { unsigned_16 num_segs; struct segment_record *segtab; unsigned_16 segtabsize; unsigned_16 segnum; Banner( "Segment Table" ); num_segs = Os2_head.segments; if( num_segs == 0 ) { return; } Wlseek( New_exe_off + Os2_head.segment_off ); segtabsize = sizeof( struct segment_record ) * num_segs; segtab = Wmalloc( segtabsize ); Wread( segtab, segtabsize ); Int_seg_tab = segtab; ++num_segs; Wdputslc( "seg fileoff len alloc prior priv flag\n" ); Wdputslc( "==== ======== ==== ==== ==== ==== ====\n" ); for( segnum = 1; segnum != num_segs; segnum++ ) { Puthex( segnum, 4 ); dmp_seg_ent( segtab++ ); } Wdputslc( "\n" ); }
/* * Dump a note section. */ static void dmp_sec_note( unsigned_32 offset, unsigned_32 size ) /**************************************************************/ { Elf_Note note; unsigned_32 read = 0; unsigned_32 skip; char *ptr; Wlseek( offset ); while( read < size ) { Wdputslc( "\n" ); Wread( ¬e, sizeof( note ) ); read += sizeof( note ); if( Byte_swap ) { SWAP_32( note.n_namesz ); SWAP_32( note.n_descsz ); SWAP_32( note.n_type ); } ptr = Wmalloc( note.n_namesz ); Wread( ptr, note.n_namesz ); Wdputs( " note name: " ); Wdputs( ptr ); Wdputslc( "\n" ); Wdputs( " descriptor length: " ); Puthex( note.n_descsz, 8 ); Wdputslc( "H\n" ); Wdputs( " note type: " ); switch( note.n_type ) { case NT_PRSTATUS: Wdputs( "process status" ); break; case NT_FPREGSET: Wdputs( "floating-point registers" ); break; case NT_PRPSINFO: Wdputs( "process info" ); break; default: Wdputs( "unknown (" ); Puthex( note.n_type, 8 ); Wdputs( "H)" ); } Wdputslc( "\n" ); free( ptr ); /* Calculate rounded up note name length */ skip = (note.n_namesz + ELF_ROUND) & ~ELF_ROUND; read += skip; Wlseek( offset + read ); /* Calculate rounded up note descriptor length */ skip = (note.n_descsz + ELF_ROUND) & ~ELF_ROUND; read += skip; Wlseek( offset + read ); } }
/* * get a resource type name */ static char *get_resrc_nam( unsigned_16 offset ) /**********************************************/ { unsigned_8 num_chars; char *name; Wlseek( New_exe_off + Os2_head.resource_off + offset ); Wread( &num_chars, sizeof( unsigned_8 ) ); name = Wmalloc( num_chars + 1 ); Wread( name, num_chars ); name[ num_chars ] = '\0'; return( name ); }
static void ScopePush( scope_stack * stack, uint_32 entry ) /************************************************************/ { if( stack->stack == NULL ) { stack->stack = Wmalloc( SCOPE_GUESS * sizeof( uint_32 ) ); } if( stack->free >= stack->size ) { stack->size += SCOPE_GUESS; stack->stack = realloc( stack->stack, stack->size * sizeof( uint_32 ) ); } stack->stack[ stack->free ] = entry; stack->free += 1; }
/* * Dump a progbits section. */ static void dmp_sec_progbits( char *name, unsigned_32 offset, unsigned_32 size ) /****************************************/ { const uint_8 *ptr; uint sect; if( name == NULL ) { Dmp_seg_data( offset, size ); } else { ptr = Wmalloc( size ); Wlseek( offset ); Wread( (char *)ptr, size ); sect = Lookup_section_name( name ); Dump_specific_section( sect, ptr, size ); free( (void *)ptr ); } }
static void load_string_table( coff_file_header *header ) /*******************************************************/ { unsigned_32 string_pos; unsigned_32 table_size; string_pos = Coff_off + header->sym_table + header->num_symbols * sizeof( coff_symbol ); Wlseek( string_pos ); Wread( &table_size, sizeof( table_size ) ); if( table_size > 4 ){ table_size -= sizeof(unsigned_32); String_table = Wmalloc( table_size ); Wread( String_table, table_size ); } else { String_table = NULL; } }
/* * Dump external reference (import) table. */ static void dmp_external_ref( void ) /**********************************/ { unsigned_32 i,j; unsigned_8 len; char *name; unsigned_32 num; unsigned_32 reloc; if( Nlm_head.numberOfExternalReferences == 0 ) { return; } Wdputslc( "\n" ); Wlseek( Nlm_head.externalReferencesOffset ); Banner( "External Reference (Import) Table" ); Wdputslc( "80000000H = relocation not relative to current position\n" ); Wdputslc( "40000000H = relocation to code segment\n" ); for( i = 0; i < Nlm_head.numberOfExternalReferences; i++ ) { Wread( &len, sizeof( unsigned_8 ) ); name = Wmalloc( len ); Wread( name, len ); name[len] = '\0'; Wdputs( name ); Wdputs( ", relocations:" ); Wdputslc( "\n" ); Wread( &num, sizeof( unsigned_32 ) ); Wdputs( " " ); for( j = 0; j < num; j++ ) { Wread( &reloc, sizeof( unsigned_32 ) ); if( j != 0 ) { if( (j) % 4 == 0 ) { Wdputslc( "\n " ); } else { Wdputs( " " ); } } Putdecl( j, 2 ); Wdputc( ':' ); Puthex( reloc, 8 ); } Wdputslc( "\n" ); } }
/* * dump some resource entries */ static void dmp_resrc_ent( unsigned_16 num_resources ) /****************************************************/ { struct resource_record *res_ent_tab; struct resource_record *res_ent; unsigned_16 res_group_size; unsigned_16 res_num; if( num_resources == 0 ) { return; } res_group_size = num_resources * sizeof( struct resource_record ); res_ent = res_ent_tab = Wmalloc( res_group_size ); Wread( res_ent_tab, res_group_size ); for( res_num = 0; res_num != num_resources; res_num++ ) { Wdputs( " # " ); Putdec( res_num + 1 ); dmp_resrc_desc( res_ent++ ); } free( res_ent_tab ); }
/* * Dump module dependency table. */ static void dmp_module_dep( void ) /********************************/ { unsigned_32 i; unsigned_8 len; char *name; if( Nlm_head.numberOfModuleDependencies == 0 ) { return; } Wdputslc( "\n" ); Wlseek( Nlm_head.moduleDependencyOffset ); Banner( "Module Dependency Table" ); for( i = 0; i < Nlm_head.numberOfModuleDependencies; i++ ) { Wread( &len, sizeof( unsigned_8 ) ); name = Wmalloc( len ); Wread( name, len ); name[len] = '\0'; Wdputs( " " ); Wdputs( name ); Wdputslc( "\n" ); } }
/* * Dump the string table section. */ static void dmp_sec_strtab( unsigned_32 offset, unsigned_32 size ) /****************************************************************/ { char *string_table, *ptr; string_table = Wmalloc( size ); Wlseek( offset ); Wread( string_table, size ); ptr = string_table; while( ptr < (string_table + size) ) { if( *ptr ) { Puthex( ptr - string_table, 8 ); Wdputslc( ": " ); Wdputs( ptr ); Wdputslc( "\n" ); ptr += strlen( ptr ); } else { ptr++; } } free( string_table ); }
/* * 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 ); } }
extern void dump_abbrevs( const uint_8 *input, uint length ) /**********************************************************/ { const uint_8 *p; uint_32 tmp; uint_32 attr; uint_32 abbr_off; // bool start; if( Sections[ DW_DEBUG_ABBREV ].data == 0 ) { Sections[ DW_DEBUG_ABBREV ].data = Wmalloc( length ); Sections[ DW_DEBUG_ABBREV ].max_offset = length; memcpy( Sections[ DW_DEBUG_ABBREV ].data, input, length ); } p = input; for( ;; ) { if( p > input + length ) break; abbr_off = tmp = p - input; p = DecodeULEB128( p, &tmp ); if( tmp == 0 ) { Wdputslc( "End_CU\n" ); // start = true; continue; /* compile unit separator */ } Wdputs( "Offset: " ); Puthex( abbr_off, 8 ); Wdputs( " Code: " ); Puthex( tmp, 8 ); Wdputslc( "\n" ); if( p >= input + length ) break; if( tmp == 0 ) continue; /* compile unit separator */ p = DecodeULEB128( p, &tmp ); Wdputs( " " ); getTAG( tmp ); Wdputslc( "\n" ); if( *p == DW_CHILDREN_yes ) { Wdputslc( "has children\n" ); } else { Wdputslc( "childless\n" ); } p++; for( ;; ) { if( p > input + length ) break; p = DecodeULEB128( p, &attr ); if( p > input + length ) break; p = DecodeULEB128( p, &tmp ); if( attr == 0 && tmp == 0 ) { Wdputslc( " End_form\n" ); break; } Wdputs( " " ); getAT( attr ); Wdputs( " " ); getFORM( tmp ); Wdputslc( "\n" ); if( attr == 0 ) { break; } } } }
static void dmp_symtab( unsigned long offset, unsigned long num_syms ) /********************************************************************/ { coff_symbol *symtab; coff_symbol *start; char * strtab; unsigned_32 strsize; unsigned_32 symidx; unsigned num_aux; char * name; char buff[9]; if( num_syms == 0 ) { Wdputslc( "No symbols in object file\n" ); Wdputslc( "\n" ); return; } Wlseek( Coff_off + offset ); Banner( "Symbol Table" ); start = Wmalloc( num_syms * sizeof(coff_symbol) ); symtab = start; Wread( start, num_syms * sizeof(coff_symbol) ); Wread( &strsize, sizeof(unsigned_32) ); if( strsize != 0 ) { strsize -= sizeof(unsigned_32); } if( strsize != 0 ) { strtab = Wmalloc( strsize ); Wread( strtab, strsize ); } else { strtab = NULL; } buff[8] = '\0'; for( symidx = 0; symidx < num_syms; symidx++ ) { if( symtab->name.non_name.zeros == 0 ) { name = strtab + symtab->name.non_name.offset - 4; } else if( symtab->name.name_string[8] == '\0' ) { name = symtab->name.name_string; } else { memcpy( buff, symtab->name.name_string, 8 ); name = buff; } Wdputs( "Idx: " ); Puthex( symidx, 8 ); Wdputs( " Name: " ); Wdputs( name ); Wdputslc( "\n" ); Wdputs( "Value: " ); Puthex( symtab->value, 8 ); Wdputs( " Sec #: " ); Puthex( symtab->sec_num, 4 ); Wdputs( " Type: " ); Puthex( symtab->type, 4 ); Wdputs( " Class: " ); Puthex( symtab->storage_class, 2 ); Wdputs( " # Aux Syms: " ); Putdec( symtab->num_aux ); Wdputslc( "\n" ); num_aux = symtab->num_aux; symtab++; if( num_aux > 0 ) { dmp_mult_data_line((char *)symtab, 0, num_aux * sizeof(coff_symbol)); symtab += num_aux; symidx += num_aux; } Wdputslc( "\n" ); } Wdputslc( "\n" ); if( strsize != 0 ) { Banner( "String Table" ); dmp_mult_data_line( strtab, 0, strsize ); Wdputslc( "\n" ); } free( start ); free( strtab ); }