📄 orlentry.c
字号:
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "orllevel.h"
#include "orlentry.h"
#include "orlflhnd.h"
orl_handle ORLENTRY ORLInit( orl_funcs * funcs )
{
orl_handle orl_hnd;
orl_hnd = (orl_handle) funcs->alloc( sizeof( orl_handle_struct ) );
if( !orl_hnd ) return( NULL );
orl_hnd->error = ORL_OKAY;
orl_hnd->funcs = funcs;
orl_hnd->elf_hnd = ElfInit( funcs );
if( !(orl_hnd->elf_hnd) ) {
funcs->free( orl_hnd );
return( NULL );
}
orl_hnd->coff_hnd = CoffInit( funcs );
if( !(orl_hnd->coff_hnd) ) {
funcs->free( orl_hnd );
return( NULL );
}
orl_hnd->omf_hnd = OmfInit( funcs );
if( !(orl_hnd->omf_hnd) ) {
funcs->free( orl_hnd );
return( NULL );
}
orl_hnd->first_file_hnd = NULL;
return( orl_hnd );
}
orl_return ORLENTRY ORLGetError( orl_handle orl_hnd ) {
return( orl_hnd->error );
}
orl_return ORLENTRY ORLFini( orl_handle orl_hnd ) {
orl_return error;
if( ( error = ElfFini( orl_hnd->elf_hnd ) ) != ORL_OKAY ) return( error );
if( ( error = CoffFini( orl_hnd->coff_hnd ) ) != ORL_OKAY ) return( error );
if( ( error = OmfFini( orl_hnd->omf_hnd ) ) != ORL_OKAY ) return( error );
while( orl_hnd->first_file_hnd ) {
error = ORLRemoveFileLinks( orl_hnd->first_file_hnd );
if( error != ORL_OKAY ) return( error );
}
orl_hnd->funcs->free( orl_hnd );
return( ORL_OKAY );
}
orl_file_format ORLFileIdentify( orl_handle orl_hnd, void * file )
/****************************************************************/
{
unsigned char * magic;
uint_16 machine_type;
uint_16 offset;
uint_16 len;
unsigned char chksum;
magic = orl_hnd->funcs->read( file, 4 );
if( magic == NULL ) {
return ORL_UNRECOGNIZED_FORMAT;
}
if( orl_hnd->funcs->seek( file, -4, SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
if( magic[0] == 0x7f && magic[1] == 'E' && magic[2] == 'L' &&
magic[3] == 'F' ) {
return ORL_ELF;
}
// See if this is the start of an OMF object file
// the first record must be a THEADR record and we check that it is
// valid, if it is then we assume that this is an OMF object file.
// record header is 0x80 see watcom\h\pcobj.h
if( magic[0] == 0x80 ) {
len = magic[1] | ( magic[2] << 8 );
len -= (unsigned char)(magic[3]);
len -= 2;
if( !len ) {
// This looks good so far, we must now check the record
len = (unsigned char)(magic[3]) + 1;
if( orl_hnd->funcs->seek( file, 4, SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
chksum = magic[0] + magic[1] + magic[2] + magic[3];
magic = orl_hnd->funcs->read( file, len );
if( orl_hnd->funcs->seek( file, -( 4 + len ), SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
if( magic ) {
// Go on to check record checksum
while( len ) {
chksum += (unsigned char)(*magic);
len--;
magic++;
}
magic--;
if( !( *magic ) || !chksum ) {
// seems to be a correct OMF record to start the OBJ
return( ORL_OMF );
}
} else {
magic = orl_hnd->funcs->read( file, 4 );
if( magic == NULL ) {
return ORL_UNRECOGNIZED_FORMAT;
} else if( orl_hnd->funcs->seek( file, -4, SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
}
}
}
machine_type = *( (uint_16 *) magic );
switch( machine_type ) {
case IMAGE_FILE_MACHINE_I860:
case IMAGE_FILE_MACHINE_I386:
case IMAGE_FILE_MACHINE_R3000:
case IMAGE_FILE_MACHINE_R4000:
case IMAGE_FILE_MACHINE_ALPHA:
case IMAGE_FILE_MACHINE_POWERPC:
case IMAGE_FILE_MACHINE_AMD64:
case IMAGE_FILE_MACHINE_UNKNOWN:
return ORL_COFF;
}
// Is it PE?
if( magic[0] == 'M' && magic[1] == 'Z' ) {
if( orl_hnd->funcs->seek( file, 0x3c, SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
magic = orl_hnd->funcs->read( file, 0x4 );
if( magic == NULL ) {
return ORL_UNRECOGNIZED_FORMAT;
}
offset = *( (uint_16 *) magic );
if( orl_hnd->funcs->seek( file, offset-0x40, SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
magic = orl_hnd->funcs->read( file, 4 );
if( magic == NULL ) {
return ORL_UNRECOGNIZED_FORMAT;
}
if( magic[0]=='P' && magic[1] == 'E' && magic[2] == '\0' && magic[3] == '\0' ) {
magic = orl_hnd->funcs->read( file, 4 );
if( magic == NULL ) {
return ORL_UNRECOGNIZED_FORMAT;
}
if( orl_hnd->funcs->seek( file, -offset-8, SEEK_CUR ) == -1 ) {
return ORL_UNRECOGNIZED_FORMAT;
}
machine_type = *( (uint_16 *) magic );
switch( machine_type ) {
case IMAGE_FILE_MACHINE_I860:
case IMAGE_FILE_MACHINE_I386:
case IMAGE_FILE_MACHINE_R3000:
case IMAGE_FILE_MACHINE_R4000:
case IMAGE_FILE_MACHINE_ALPHA:
case IMAGE_FILE_MACHINE_POWERPC:
case IMAGE_FILE_MACHINE_AMD64:
return ORL_COFF;
}
}
}
return ORL_UNRECOGNIZED_FORMAT;
}
orl_file_handle ORLENTRY ORLFileInit( orl_handle orl_hnd, void * file, orl_file_format type )
{
orl_file_handle orl_file_hnd;
switch( type ) {
case( ORL_ELF ):
orl_file_hnd = (orl_file_handle) orl_hnd->funcs->alloc( sizeof( orl_file_handle_struct ) );
if( !orl_file_hnd ) {
orl_hnd->error = ORL_OUT_OF_MEMORY;
return( NULL );
}
orl_file_hnd->type = ORL_ELF;
orl_file_hnd->file_hnd.elf = ElfFileInit( orl_hnd->elf_hnd, file );
if( orl_file_hnd->file_hnd.elf == NULL ) {
orl_hnd->error = ORL_OUT_OF_MEMORY;
orl_hnd->funcs->free( orl_file_hnd );
return( NULL );
}
ORLAddFileLinks( orl_hnd, orl_file_hnd );
return( orl_file_hnd );
case( ORL_COFF ):
orl_file_hnd = (orl_file_handle) orl_hnd->funcs->alloc( sizeof( orl_file_handle_struct ) );
if( !orl_file_hnd ) return( NULL );
orl_file_hnd->type = ORL_COFF;
orl_file_hnd->file_hnd.coff = CoffFileInit( orl_hnd->coff_hnd, file );
if( orl_file_hnd->file_hnd.coff == NULL ) {
orl_hnd->error = ORL_OUT_OF_MEMORY;
orl_hnd->funcs->free( orl_file_hnd );
return( NULL );
}
ORLAddFileLinks( orl_hnd, orl_file_hnd );
return( orl_file_hnd );
case( ORL_OMF ):
orl_file_hnd = (orl_file_handle) orl_hnd->funcs->alloc( sizeof( orl_file_handle_struct ) );
if( !orl_file_hnd ) {
orl_hnd->error = ORL_OUT_OF_MEMORY;
return( NULL );
}
orl_file_hnd->type = ORL_OMF;
orl_file_hnd->file_hnd.omf = OmfFileInit( orl_hnd->omf_hnd, file );
if( orl_file_hnd->file_hnd.omf == NULL ) {
orl_hnd->error = ORL_OUT_OF_MEMORY;
orl_hnd->funcs->free( orl_file_hnd );
return( NULL );
}
ORLAddFileLinks( orl_hnd, orl_file_hnd );
return( orl_file_hnd );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( NULL );
}
orl_return ORLENTRY ORLFileFini( orl_file_handle orl_file_hnd )
{
orl_return error = ORL_ERROR;
/* jump table replace: */
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
error = ElfFileFini( orl_file_hnd->file_hnd.elf );
break;
case( ORL_COFF ):
error = CoffFileFini( orl_file_hnd->file_hnd.coff );
break;
case( ORL_OMF ):
error = OmfFileFini( orl_file_hnd->file_hnd.omf );
break;
default: break;//ORL_UNRECOGNIZED_FORMAT
}
if( error != ORL_OKAY ) return( error );
return( ORLRemoveFileLinks( orl_file_hnd ) );
}
unsigned long ORLENTRY ORLExportTableRVA(orl_file_handle orl_file_hnd)
{
unsigned long rva = 0L;
if (orl_file_hnd->type == ORL_COFF) {
rva = CoffExportTableRVA(orl_file_hnd->file_hnd.coff);
}
return rva;
}
orl_return ORLENTRY ORLFileScan( orl_file_handle orl_file_hnd, char *desired, orl_sec_return_func return_func )
{
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
return( ElfFileScan( orl_file_hnd->file_hnd.elf, desired, return_func ) );
case( ORL_COFF ):
return( CoffFileScan( orl_file_hnd->file_hnd.coff, desired, return_func ) );
case( ORL_OMF ):
return( OmfFileScan( orl_file_hnd->file_hnd.omf, desired, return_func ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( ORL_ERROR );
}
orl_machine_type ORLENTRY ORLFileGetMachineType( orl_file_handle orl_file_hnd )
{
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
return( ElfFileGetMachineType( orl_file_hnd->file_hnd.elf ) );
case( ORL_COFF ):
return( CoffFileGetMachineType( orl_file_hnd->file_hnd.coff ) );
case( ORL_OMF ):
return( OmfFileGetMachineType( orl_file_hnd->file_hnd.omf ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( 0 );
}
orl_file_flags ORLENTRY ORLFileGetFlags( orl_file_handle orl_file_hnd )
{
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
return( ElfFileGetFlags( orl_file_hnd->file_hnd.elf ) );
case( ORL_COFF ):
return( CoffFileGetFlags( orl_file_hnd->file_hnd.coff ) );
case( ORL_OMF ):
return( OmfFileGetFlags( orl_file_hnd->file_hnd.omf ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( 0 );
}
orl_file_size ORLENTRY ORLFileGetSize( orl_file_handle orl_file_hnd )
{
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
return( ElfFileGetSize( orl_file_hnd->file_hnd.elf ) );
case( ORL_COFF ):
return( CoffFileGetSize( orl_file_hnd->file_hnd.coff ) );
case( ORL_OMF ):
return( OmfFileGetSize( orl_file_hnd->file_hnd.omf ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( 0 );
}
orl_file_flags ORLENTRY ORLFileGetType( orl_file_handle orl_file_hnd )
{
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
return( ElfFileGetType( orl_file_hnd->file_hnd.elf ) );
case( ORL_COFF ):
return( CoffFileGetType( orl_file_hnd->file_hnd.coff ) );
case( ORL_OMF ):
return( OmfFileGetType( orl_file_hnd->file_hnd.omf ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( 0 );
}
orl_file_format ORLENTRY ORLFileGetFormat( orl_file_handle orl_file_hnd )
{
return( orl_file_hnd->type );
}
orl_sec_handle ORLENTRY ORLFileGetSymbolTable( orl_file_handle orl_file_hnd )
{
switch( orl_file_hnd->type ) {
case( ORL_ELF ):
return( (orl_sec_handle) ElfFileGetSymbolTable( orl_file_hnd->file_hnd.elf ) );
case( ORL_COFF ):
return( (orl_sec_handle) CoffFileGetSymbolTable( orl_file_hnd->file_hnd.coff ) );
case( ORL_OMF ):
return( (orl_sec_handle) OmfFileGetSymbolTable( orl_file_hnd->file_hnd.omf ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( NULL );
}
char * ORLENTRY ORLSecGetName( orl_sec_handle orl_sec_hnd )
{
switch( orl_sec_hnd->type ) {
case( ORL_ELF ):
return( ElfSecGetName( (elf_sec_handle) orl_sec_hnd ) );
case( ORL_COFF ):
return( CoffSecGetName( (coff_sec_handle) orl_sec_hnd ) );
case( ORL_OMF ):
return( OmfSecGetName( (omf_sec_handle) orl_sec_hnd ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( NULL );
}
orl_sec_offset ORLENTRY ORLSecGetBase( orl_sec_handle orl_sec_hnd )
{
switch( orl_sec_hnd->type ) {
case( ORL_ELF ):
return( ElfSecGetBase( (elf_sec_handle) orl_sec_hnd ) );
case( ORL_COFF ):
return( CoffSecGetBase( (coff_sec_handle) orl_sec_hnd ) );
case( ORL_OMF ):
return( OmfSecGetBase( (omf_sec_handle) orl_sec_hnd ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( 0 );
}
orl_sec_size ORLENTRY ORLSecGetSize( orl_sec_handle orl_sec_hnd )
{
switch( orl_sec_hnd->type ) {
case( ORL_ELF ):
return( ElfSecGetSize( (elf_sec_handle) orl_sec_hnd ) );
case( ORL_COFF ):
return( CoffSecGetSize( (coff_sec_handle) orl_sec_hnd ) );
case( ORL_OMF ):
return( OmfSecGetSize( (omf_sec_handle) orl_sec_hnd ) );
default: break;//ORL_UNRECOGNIZED_FORMAT
}
return( 0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -