elfexe.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 786 行 · 第 1/2 页
C
786 行
static void swap_phdr( Elf32_Phdr *elf_prog )
/*******************************************/
{
if( Byte_swap ) {
/* Byte swap program header */
SWAP_32( elf_prog->p_type );
SWAP_32( elf_prog->p_offset );
SWAP_32( elf_prog->p_vaddr );
SWAP_32( elf_prog->p_paddr );
SWAP_32( elf_prog->p_filesz );
SWAP_32( elf_prog->p_memsz );
SWAP_32( elf_prog->p_flags );
SWAP_32( elf_prog->p_align );
}
}
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 the section data.
*/
static void dmp_sec_data( char *name,
unsigned_32 type, unsigned_32 offset, unsigned_32 size )
/**********************************************************/
{
if( size == 0 ) {
return;
}
switch( type ) {
case SHT_NULL:
Dmp_seg_data( offset, size );
break;
case SHT_PROGBITS:
dmp_sec_progbits( name, offset, size );
break;
case SHT_SYMTAB:
Dmp_seg_data( offset, size );
break;
case SHT_STRTAB:
dmp_sec_strtab( offset, size );
break;
case SHT_RELA:
Dmp_seg_data( offset, size );
break;
case SHT_HASH:
Dmp_seg_data( offset, size );
break;
case SHT_DYNAMIC:
Dmp_seg_data( offset, size );
break;
case SHT_NOTE:
dmp_sec_note( offset, size );
break;
case SHT_NOBITS:
Dmp_seg_data( offset, size );
break;
case SHT_REL:
Dmp_seg_data( offset, size );
break;
case SHT_SHLIB:
Dmp_seg_data( offset, size );
break;
case SHT_DYNSYM:
Dmp_seg_data( offset, size );
break;
case SHT_LOPROC:
Dmp_seg_data( offset, size );
break;
}
}
/*
* 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 );
}
}
bool Dmp_lib_head( void )
/***********************/
{
char sig[LIBMAG_LEN];
Lib32_Hdr hdr;
long filesize;
unsigned long size;
unsigned long Elf_off;
Wlseek( 0 );
Wread( sig, LIBMAG_LEN );
if( memcmp( sig, LIBMAG, LIBMAG_LEN ) != 0 ) return 0;
filesize = WFileSize();
Elf_off = LIBMAG_LEN + LIB_CLASS_LEN + LIB_DATA_LEN;
Wlseek( Elf_off );
for( ;; ) {
if( Elf_off + LIB_HEADER_SIZE >= filesize ) break;
Wread( &hdr, LIB_HEADER_SIZE );
Elf_off += LIB_HEADER_SIZE;
hdr.lib_date[0]='\0';
Wdputs( "lib name = " );
Wdputs( hdr.lib_name );
Wdputslc( "\n" );
hdr.lib_fmag[0] = '\0';
size = strtoul( hdr.lib_size, NULL, 10 );
if( !Dmp_elf_header( Elf_off ) ) {
if( strcmp( hdr.lib_name, LIB_SYMTAB_NAME ) &&
strcmp( hdr.lib_name, LIB_LFTAB_NAME ) &&
strcmp( hdr.lib_name, LIB_FFTAB_NAME ) ) {
Wdputslc( "archive entry not identified\n" );
}
Dmp_seg_data( Elf_off, size );
Wdputslc( "\n" );
}
if( size & 1 ) {
size++;
}
Elf_off += size;
Wlseek( Elf_off );
}
return 1;
}
/*
* Dump the ELF header, if any.
*/
bool Dmp_elf_header( unsigned_32 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 ELF header, if any.
*/
bool Dmp_elf_head( void )
/***********************/
{
Wlseek( 0 );
return( Dmp_elf_header( 0 ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?