objorl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 329 行
C
329 行
/****************************************************************************
*
* 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 <stdlib.h>
#include <string.h>
#include "wdismsg.h"
#include "disasm.h"
#include "orl.h"
#include "hashtabl.h"
#define SYMBOL_TO_TARGET_TABLE_SIZE 53
#define SYMBOL_TO_EXPORT_TABLE_SIZE 53
#define SECTION_TO_SEGMENT_TABLE_SIZE 29
typedef FILE *file_handle;
typedef struct buf_list {
struct buf_list *next;
char buf[1];
} buf_list;
typedef struct {
file_handle hdl;
buf_list *buflist;
} buffer_info;
typedef struct section_entry {
orl_sec_handle shnd;
struct section_entry *next;
} section_entry;
typedef struct section_entry *section_ptr;
typedef struct section_list {
section_ptr first;
section_ptr last;
} section_list;
bool UseORL;
char *ModNameORL;
orl_handle ORLHnd;
orl_file_handle ORLFileHnd;
// SymbolToTargetTable keeps all the symbols that the program imports
// (we might export that also). Table is queried with an orl_sym_handle.
hash_table SymbolToTargetTable;
// Keeps track of all the symbols that the object exports.
hash_table SymbolToExportTable;
// Translation table from an orl_sec_handle to its correspinding segment.
hash_table SectionToSegmentTable;
static orl_funcs oFuncs;
static buffer_info fileBuff;
static orl_sec_handle symbolTable;
static section_list relocSections;
static void *buffRead( buffer_info *file, int len )
//*************************************************
{
buf_list *buf;
buf = AllocMem( len + sizeof(buf_list) - 1 );
if( fread( buf->buf, 1, len, file->hdl ) != len ) {
FreeMem( buf );
return NULL;
}
buf->next = file->buflist;
file->buflist = buf;
return( buf->buf );
}
static long buffSeek( buffer_info *file, long pos, int where )
//************************************************************
{
return( fseek( file->hdl, pos, where ) );
}
static void initBuffer( buffer_info *file, file_handle hdl )
//**********************************************************
{
file->hdl = hdl;
file->buflist = NULL;
}
static void finiBuffer( buffer_info *file )
//*****************************************
{
buf_list *list;
buf_list *next;
list = file->buflist;
while( list != NULL ) {
next = list->next;
FreeMem( list );
list = next;
}
}
static int numberCmp( hash_value n1, hash_value n2 )
//**************************************************
{
return( n1 - n2 );
}
static void createHashTables( void )
//**********************************
{
SymbolToTargetTable = HashTableCreate( SYMBOL_TO_TARGET_TABLE_SIZE, HASH_NUMBER, numberCmp );
if( !SymbolToTargetTable ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
SymbolToExportTable = HashTableCreate( SYMBOL_TO_EXPORT_TABLE_SIZE, HASH_NUMBER, numberCmp );
if( !SymbolToExportTable ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
SectionToSegmentTable = HashTableCreate( SECTION_TO_SEGMENT_TABLE_SIZE, HASH_NUMBER, numberCmp );
if( !SectionToSegmentTable ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
}
static void destroyHashTables( void )
//***********************************
{
if( SymbolToTargetTable ) HashTableFree( SymbolToTargetTable );
if( SymbolToExportTable ) HashTableFree( SymbolToExportTable );
if( SectionToSegmentTable ) HashTableFree( SectionToSegmentTable );
}
bool InitORL( void )
//******************
// Try and see if we will use ORL. Returns TRUE if we'll use it.
{
orl_file_flags o_flags;
orl_file_format o_format;
orl_machine_type o_machine_type;
ORLFileHnd = NULL;
oFuncs.alloc = AllocMem;
oFuncs.free = FreeMem;
oFuncs.read = (void * (*) ( void *, int ))buffRead;
oFuncs.seek = (long int (*) ( void *, long int, int ))buffSeek;
ORLHnd = ORLInit( &oFuncs );
if( !ORLHnd ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
initBuffer( &fileBuff, ObjFile );
o_format = ORLFileIdentify( ORLHnd, &fileBuff );
if( o_format != ORL_ELF && o_format != ORL_COFF ) {
ORLFini( ORLHnd );
finiBuffer( &fileBuff );
ORLHnd = NULL;
return( FALSE ); // Will use ParseObjectOMF
}
ORLFileHnd = ORLFileInit( ORLHnd, &fileBuff, o_format );
if( !ORLFileHnd ) {
ORLFini( ORLHnd );
finiBuffer( &fileBuff );
SysError( ERR_OUT_OF_MEM, FALSE );
}
o_machine_type = ORLFileGetMachineType( ORLFileHnd );
if( o_machine_type != ORL_MACHINE_TYPE_I386 ) {
FiniORL();
Error( ERR_ORL_INV_MACHINE_TYPE, TRUE );
exit( 1 );
}
o_flags = ORLFileGetFlags( ORLFileHnd );
if( !(o_flags & ORL_FILE_FLAG_LITTLE_ENDIAN) ) {
FiniORL();
Error( ERR_ORL_INV_BYTE_ORDER, TRUE );
exit( 1 );
}
UseORL = TRUE;
createHashTables();
return( TRUE ); // Success: will use ORL
}
void FiniORL( void )
//******************
{
if( ORLFileHnd ) {
ORLFileFini( ORLFileHnd );
ORLFini( ORLHnd );
}
destroyHashTables();
finiBuffer( &fileBuff );
}
static bool addRelocSection( orl_sec_handle shnd )
//************************************************
{
section_ptr sec;
sec = AllocMem( sizeof( struct section_entry ) );
if( sec ) {
sec->shnd = shnd;
sec->next = NULL;
if( relocSections.first ) {
relocSections.last->next = sec;
relocSections.last = sec;
} else {
relocSections.first = sec;
relocSections.last = sec;
}
} else {
return( FALSE );
}
return( TRUE );
}
static void registerSegment( orl_sec_handle o_shnd )
//**************************************************
{
orl_sec_flags sec_flags;
orl_sec_handle reloc_section;
orl_sec_alignment alignment;
char * content;
int ctr;
segment *seg;
seg = NewSegment();
seg->name = ORLSecGetName( o_shnd );
seg->size = ORLSecGetSize( o_shnd );
seg->start = 0;
seg->use_32 = 1; // only 32-bit object files use ORL
seg->attr = ( 2 << 2 ); // (?) combine public
alignment = ORLSecGetAlignment( o_shnd );
// FIXME: Need better alignment translation.
switch( alignment ) {
case 0:
seg->attr |= ( 1 << 5 ); break;
case 1:
seg->attr |= ( 2 << 5 ); break;
case 3:
case 4:
seg->attr |= ( 3 << 5 ); break;
case 8:
seg->attr |= ( 4 << 5 ); break;
case 2:
seg->attr |= ( 5 << 5 ); break;
case 12:
seg->attr |= ( 6 << 5 ); break;
default:
// fprintf( stderr, "NOTE! 'Strange' alignment (%d) found. Using byte alignment.\n", alignment );
seg->attr |= ( 1 << 5 ); break;
}
sec_flags = ORLSecGetFlags( o_shnd );
if( !( sec_flags & ORL_SEC_FLAG_EXEC ) ) {
seg->data_seg = TRUE;
}
if( seg->size > 0 && ORLSecGetContents( o_shnd, &content ) == ORL_OKAY ) {
Segment = seg;
// Putting contents into segment struct.
for( ctr = 0; ctr < seg->size; ctr++ ) {
PutSegByte( ctr, content[ctr] );
}
}
if( !HashTableInsert( SectionToSegmentTable, (hash_value)o_shnd, (hash_data)seg ) ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
reloc_section = ORLSecGetRelocTable( o_shnd );
if( reloc_section ) {
if( !addRelocSection( reloc_section ) ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
}
}
static orl_return processSection( orl_sec_handle o_shnd )
//*******************************************************
{
orl_sec_type sec_type;
sec_type = ORLSecGetType( o_shnd );
switch( sec_type ) {
/* List the section types that you don't want to disassemble
case ORL_SEC_TYPE_WHICHEVER_YOU_DO_NOT_WANT_LIKE_THE_ONES_BELOW:
case ORL_SEC_TYPE_LINK_INFO:
*/
case ORL_SEC_TYPE_STR_TABLE:
case ORL_SEC_TYPE_RELOCS:
// printf( "Skipping section: %s\n", ORLSecGetName( o_shnd ) );
break;
case ORL_SEC_TYPE_SYM_TABLE:
symbolTable = o_shnd;
break;
default:
registerSegment( o_shnd );
break;
}
return( ORL_OKAY );
}
static import_sym *addExtDef( char *name, bool public, bool exported, export_sym *exp )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?