elfexe.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 786 行 · 第 1/2 页
C
786 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: ELF dumping routines.
*
****************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
#include "wdglb.h"
#include "wdfunc.h"
#ifdef __BIG_ENDIAN__
#define NATIVE_ENDIAN 2
#else
#define NATIVE_ENDIAN 1
#endif
static char *elf_exe_msg[] = {
"2file type (i.e. object, executable file) = ",
"2required architecture = ",
"4version of the file = ",
"4program entry point = ",
"4program header offset = ",
"4section header offset = ",
"4processor specific flags = ",
"2ELF header size = ",
"2program header entry size = ",
"2number of program header entries = ",
"2section header entry size = ",
"2number of section header entries = ",
"2section name string table index = ",
NULL
};
static char *elf_prog_msg[] = {
"4type of segment = ",
"4offset of segment from beginning of file = ",
"4segment virtual address = ",
"4segment physical address = ",
"4size of segment in file = ",
"4size of segment in memory = ",
"4flags = ",
"4segment align value (in mem & file) = ",
NULL
};
static char *elf_sec_msg[] = {
"4name of the section = ",
"4section type = ",
"4flags = ",
"4starting address of section in image = ",
"4start of section in file = ",
"4size of section in file = ",
"4section header table index link = ",
"4extra information = ",
"4address alignment = ",
"4entry size for sects with fixed sized ents = ",
NULL
};
/*
* Dump the segment type.
*/
static void dmp_hdr_type( unsigned_16 type )
/******************************************/
{
Wdputs( "file type: " );
switch( type ) {
case ET_NONE:
Wdputs( "No file type" );
break;
case ET_REL:
Wdputs( "Relocatable file" );
break;
case ET_EXEC:
Wdputs( "Executable file" );
break;
case ET_DYN:
Wdputs( "Shared object file" );
break;
case ET_CORE:
Wdputs( "Core file" );
break;
case ET_LOPROC:
Wdputs( "Processor specific" );
break;
}
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 );
}
#define ELF_ROUND (sizeof( Elf32_Word ) - 1)
/*
* 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 );
}
}
/*
* Dump a progbits section.
*/
static void dmp_sec_progbits( char *name,
unsigned_32 offset, unsigned_32 size )
/****************************************/
{
const char *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 );
}
}
/*
* Dump the segment type.
*/
static void dmp_prog_type( unsigned_32 type )
/*******************************************/
{
Wdputs( "segment type: " );
switch( type ) {
case PT_NULL:
Wdputs( "unused segment" );
break;
case PT_LOAD:
Wdputs( "loadable segment" );
break;
case PT_DYNAMIC:
Wdputs( "dynamic linking info" );
break;
case PT_INTERP:
Wdputs( "program interpreter" );
break;
case PT_NOTE:
Wdputs( "comments & auxiliary info" );
break;
case PT_SHLIB:
Wdputs( "unspecified semantics" );
break;
case PT_PHDR:
Wdputs( "address of progam header" );
break;
case PT_LOPROC:
Wdputs( "processor specific" );
break;
}
Wdputslc( "\n" );
}
/*
* Dump the section type.
*/
static void dmp_sec_type( unsigned_32 type )
/******************************************/
{
Wdputs( "section type: " );
switch( type ) {
case SHT_NULL:
Wdputs( "inactive" );
break;
case SHT_PROGBITS:
Wdputs( "defined by program" );
break;
case SHT_SYMTAB:
Wdputs( "symbol table" );
break;
case SHT_STRTAB:
Wdputs( "string table" );
break;
case SHT_RELA:
Wdputs( "reloc entries with explicit addends" );
break;
case SHT_HASH:
Wdputs( "symbol hash table" );
break;
case SHT_DYNAMIC:
Wdputs( "dynamic linking info" );
break;
case SHT_NOTE:
Wdputs( "comment info" );
break;
case SHT_NOBITS:
Wdputs( "no space in file" );
break;
case SHT_REL:
Wdputs( "reloc entries" );
break;
case SHT_SHLIB:
Wdputs( "reserved (SHT_SHLIB)" );
break;
case SHT_DYNSYM:
Wdputs( "dynamic link symbol table" );
break;
case SHT_LOPROC:
Wdputs( "processor specific" );
break;
}
Wdputslc( "\n" );
}
/*
* dump the program flag word
*/
static void dmp_prog_flgs( unsigned_32 flags )
/********************************************/
{
char name[128];
name[0] = 0;
if( flags & PF_X ) {
strcat( name, " EXECUTABLE |" );
}
if( flags & PF_W ) {
strcat( name, " WRITABLE |" );
}
if( flags & PF_R ) {
strcat( name, " READABLE |" );
}
if( name[strlen(name)-1] == '|' ) {
name[strlen(name)-1] = 0;
}
Wdputs( "flags = " );
Wdputs( name );
Wdputslc( "\n" );
}
/*
* dump the section flag word
*/
static void dmp_sec_flgs( unsigned_32 flags )
/*******************************************/
{
char name[128];
name[0] = 0;
if( flags & SHF_WRITE ) {
strcat( name, " WRITABLE |" );
}
if( flags & SHF_ALLOC ) {
strcat( name, " ALLOC_SPACE |" );
}
if( flags & SHF_EXECINSTR ) {
strcat( name, " EXEC_INSTR |" );
}
if( name[strlen(name)-1] == '|' ) {
name[strlen(name)-1] = 0;
}
Wdputs( "flags = " );
Wdputs( name );
Wdputslc( "\n" );
}
/*
* byte swap ELF section header
*/
static void swap_shdr( Elf32_Shdr *elf_sec )
/******************************************/
{
if( Byte_swap ) {
SWAP_32( elf_sec->sh_name );
SWAP_32( elf_sec->sh_type );
SWAP_32( elf_sec->sh_flags );
SWAP_32( elf_sec->sh_addr );
SWAP_32( elf_sec->sh_offset );
SWAP_32( elf_sec->sh_size );
SWAP_32( elf_sec->sh_link );
SWAP_32( elf_sec->sh_info );
SWAP_32( elf_sec->sh_addralign );
SWAP_32( elf_sec->sh_entsize );
}
}
/*
* byte swap ELF program header
*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?