init.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 866 行 · 第 1/2 页
C
866 行
/****************************************************************************
*
* 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: Standalone disassembler initialization routines.
*
****************************************************************************/
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined( __WATCOMC__ )
#include <process.h>
#endif
#include "dis.h"
#include "init.h"
#include "buffer.h"
#include "memfuncs.h"
#include "hashtabl.h"
#include "publics.h"
#include "args.h"
#include "print.h"
#include "labproc.h"
#include "refproc.h"
#include "msg.h"
#include "main.h"
#include "identsec.h"
#include "fini.h"
#include "formasm.h"
struct recognized_struct {
char *name;
section_type type;
};
typedef struct recognized_struct recognized_struct;
#define SEC_NAME_LEN 8
#define OBJ_FILE_FLAGS O_RDONLY | O_BINARY
#define LIST_FILE_FLAGS O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU
#define HANDLE_TO_SECTION_TABLE_SIZE 53
#define HANDLE_TO_LIST_TABLE_SIZE 53
#define SYMBOL_TO_LABEL_TABLE_SIZE 53
#define RECOGNITION_TABLE_SIZE 29
#define CPP_COMMENT_STRING "// "
#define MASM_COMMENT_STRING "; "
char *CommentString = CPP_COMMENT_STRING;
extern wd_options Options;
extern char LabelChar;
extern char QuoteChar;
extern int OutputDest;
extern char * ListFileName;
extern orl_handle ORLHnd;
extern orl_file_handle ObjFileHnd;
extern char * ObjFileName;
extern dis_handle DHnd;
extern hash_table HandleToSectionTable;
extern hash_table HandleToLabelListTable;
extern hash_table HandleToRefListTable;
extern hash_table SymbolToLabelTable;
extern hash_table NameRecognitionTable;
extern hash_table SkipRefTable;
extern section_list_struct Sections;
extern publics_struct Publics;
extern orl_sec_handle debugHnd;
// sections that require name-checking should be inserted in this array
recognized_struct RecognizedName[] = {
{".pdata", SECTION_TYPE_PDATA}, {".drectve", SECTION_TYPE_DRECTVE},
{".bss", SECTION_TYPE_BSS}, {".text", SECTION_TYPE_TEXT},
{".debug_line", SECTION_TYPE_LINES},
};
static char *intelSkipRefList[] = { "FIWRQQ", // boundary relocs
"FIDRQQ",
"FIERQQ",
"FICRQQ",
"FISRQQ",
"FIARQQ",
"FIFRQQ",
"FIGRQQ",
"FJCRQQ", // boundary + 1 relocs
"FJSRQQ",
"FJARQQ",
"FJFRQQ",
"FJGRQQ",
NULL };
#define NUM_ELTS( a ) (sizeof(a) / sizeof((a)[0]))
static orl_sec_handle symbolTable;
static orl_sec_handle drectveSection;
static orl_funcs oFuncs;
static section_list_struct relocSections;
static char * objFileBuf;
static unsigned long objFilePos;
static unsigned long objFileLen;
int IsIntelx86( void )
{
switch( GetMachineType() ) {
case( ORL_MACHINE_TYPE_I386 ):
case( ORL_MACHINE_TYPE_I8086 ):
return( 1 );
default:
return( 0 );
}
}
orl_file_format GetFormat( void )
{
return( ORLFileGetFormat( ObjFileHnd ) );
}
static orl_return nopCallBack( char *str, void *cookie )
{
str = str;
cookie = cookie;
return( ORL_OKAY );
}
static orl_return scanTabCallBack( orl_sec_handle sh, orl_sec_offset start,
orl_sec_offset end, void *cookie )
{
section_ptr sec;
hash_data *dp;
scantab_ptr sp;
scantab_ptr tmp;
scantab_struct senitel;
cookie = cookie;
if( !sh ) return( ORL_OKAY );
if( start >= end ) return( ORL_OKAY );
dp = HashTableQuery( HandleToSectionTable, (hash_value) sh );
if( !dp ) return( ORL_OKAY );
sec = (section_ptr) *dp;
if( !sec ) return( ORL_OKAY );
sp = MemAlloc( sizeof( scantab_struct ) );
if( !sp ) return( ORL_OUT_OF_MEMORY );
memset( sp, 0, sizeof( scantab_struct ) );
sp->start = start;
sp->end = end;
senitel.next = sec->scan;
tmp = &senitel;
while( tmp->next && ( tmp->next->end < start ) ) {
tmp = tmp->next;
}
if( tmp->next ) {
if( end < tmp->next->start ) {
sp->next = tmp->next;
tmp->next = sp;
} else {
// The two records will be merged into one
if( end > tmp->next->end ) {
tmp->next->end = end;
}
if( start < tmp->next->start ) {
tmp->next->start = start;
}
MemFree( sp );
// check if we must do additional merging
sp = tmp->next;
while( sp->next && ( sp->end > sp->next->start ) ) {
if( sp->end < sp->next->end ) {
sp->end = sp->next->end;
}
tmp = sp->next;
sp->next = tmp->next;
MemFree( tmp );
}
}
} else {
tmp->next = sp;
}
// restore the list
sec->scan = senitel.next;
return( ORL_OKAY );
}
static return_val processDrectveSection( orl_sec_handle shnd )
{
orl_return o_error;
orl_note_callbacks cb;
if( !shnd ) return( OKAY );
cb.export_fn = nopCallBack;
cb.deflib_fn = nopCallBack;
cb.entry_fn = nopCallBack;
cb.scantab_fn = scanTabCallBack;
o_error = ORLNoteSecScan( shnd, &cb, NULL );
if( o_error != ORL_OKAY ) {
if( o_error == ORL_OUT_OF_MEMORY ) {
return( OUT_OF_MEMORY );
} else {
return( ERROR );
}
}
return( OKAY );
}
static return_val addRelocSection( orl_sec_handle shnd )
{
section_ptr sec;
if( relocSections.first && ( GetFormat() == ORL_OMF ) ) return( ORL_OKAY );
sec = MemAlloc( sizeof( section_struct ) );
if( sec ) {
memset( sec, 0, sizeof( section_struct ) );
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( OUT_OF_MEMORY );
}
return( OKAY );
}
static return_val registerSec( orl_sec_handle shnd, section_type type )
{
section_ptr sec;
return_val error;
sec = MemAlloc( sizeof( section_struct ) );
if( sec ) {
error = HashTableInsert( HandleToSectionTable, (hash_value) shnd, (hash_data) sec );
if( error == OKAY ) {
memset( sec, 0, sizeof( section_struct ) );
sec->shnd = shnd;
sec->name = ORLSecGetName( shnd );
sec->type = type;
sec->next = NULL;
if( Sections.first ) {
Sections.last->next = sec;
Sections.last = sec;
} else {
Sections.first = sec;
Sections.last = sec;
}
} else {
MemFree( sec );
return( OUT_OF_MEMORY );
}
} else {
return( OUT_OF_MEMORY );
}
return( OKAY );
}
static return_val addListToPublics( label_list list )
{
label_list_ptr list_ptr;
list_ptr = (label_list_ptr) MemAlloc( sizeof( label_list_ptr_struct ) );
if( list_ptr ) {
list_ptr->list = list;
if( Publics.label_lists == NULL ) {
list_ptr->next = NULL;
Publics.label_lists = list_ptr;
} else {
list_ptr->next = Publics.label_lists;
Publics.label_lists = list_ptr;
}
} else {
return( OUT_OF_MEMORY );
}
return( OKAY );
}
static return_val createLabelList( orl_sec_handle shnd )
{
label_list list;
return_val error;
list = MemAlloc( sizeof( label_list_struct ) );
if( list ) {
list->first = NULL;
list->last = NULL;
error = HashTableInsert( HandleToLabelListTable, (hash_value) shnd, (hash_data) list );
if( error == OKAY ) {
if( (Options & PRINT_PUBLICS) && shnd != 0 ) {
error = addListToPublics( list );
if( error != OKAY ) {
MemFree( list );
}
}
} else {
MemFree( list );
}
} else {
error = OUT_OF_MEMORY;
}
return( error );
}
static return_val createRefList( orl_sec_handle shnd )
{
ref_list list;
return_val error;
list = MemAlloc( sizeof( ref_list_struct ) );
if( list ) {
list->first = NULL;
list->last = NULL;
error = HashTableInsert( HandleToRefListTable, (hash_value) shnd, (hash_data) list );
if( error != OKAY ) {
MemFree( list );
}
} else {
error = OUT_OF_MEMORY;
}
return( error );
}
static return_val textOrDataSectionInit( orl_sec_handle shnd )
{
return_val error;
orl_sec_handle reloc_sec;
error = createLabelList( shnd );
if( error == OKAY ) {
error = createRefList( shnd );
if( error == OKAY ) {
reloc_sec = ORLSecGetRelocTable( shnd );
if( reloc_sec ) {
error = addRelocSection( reloc_sec );
}
}
}
return( error );
}
static orl_return sectionInit( orl_sec_handle shnd )
{
section_type type;
return_val error = OKAY;
type = IdentifySec( shnd );
switch( type ) {
case SECTION_TYPE_SYM_TABLE:
symbolTable = shnd;
// Might have a label or relocation in symbol section
error = registerSec( shnd, type );
if( error == OKAY ) {
error = createLabelList( shnd );
}
break;
case SECTION_TYPE_DRECTVE:
if( GetFormat() == ORL_OMF ) {
drectveSection = shnd;
break;
} // else fall through
case SECTION_TYPE_BSS:
error = registerSec( shnd, type );
if( error == OKAY ) {
error = createLabelList( shnd );
}
break;
case SECTION_TYPE_RELOCS:
// Ignore OMF relocs section
break;
case SECTION_TYPE_LINES:
debugHnd = shnd;
type = SECTION_TYPE_DATA;
// fall through
case SECTION_TYPE_TEXT:
case SECTION_TYPE_PDATA:
case SECTION_TYPE_DATA:
default: // Just in case we get a label or relocation in these sections
error = registerSec( shnd, type );
if( error == OKAY ) {
error = textOrDataSectionInit( shnd );
}
break;
}
switch( error ) {
case OUT_OF_MEMORY:
return( ORL_OUT_OF_MEMORY );
case ERROR:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?