init.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 866 行 · 第 1/2 页
C
866 行
return( ORL_ERROR );
}
return( ORL_OKAY );
}
static void openError( char * file_name ) {
// TODO: merge again when Linux clib supports perror()
#ifdef __LINUX__
printf( "File Open Error: %s\n", file_name );
#else
perror( file_name );
#endif
exit( 1 );
}
static void openFiles( void )
{
int objhdl;
objhdl = open( ObjFileName, OBJ_FILE_FLAGS );
if( objhdl != -1 ) {
if( ListFileName ) {
OutputDest = open( ListFileName, LIST_FILE_FLAGS, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP );
if( OutputDest == -1 ) openError( ListFileName );
ChangePrintDest( OutputDest );
} else {
OutputDest = STDOUT_FILENO;
}
objFileLen = filelength( objhdl );
if( objFileLen == 0 ) {
LeaveProgram( OKAY, WHERE_OBJ_ZERO_LEN );
}
objFileBuf = MemAlloc( objFileLen );
objFilePos = 0;
if( read( objhdl, objFileBuf, objFileLen ) == -1 ) {
openError( ObjFileName );
}
close( objhdl );
} else {
openError( ObjFileName );
}
}
static void * objRead( void *hdl, size_t len )
/*****************************************/
{
void * retval;
hdl = hdl;
if( objFilePos + len > objFileLen ) return NULL;
retval = objFileBuf + objFilePos;
objFilePos += len;
return retval;
}
static long objSeek( void *hdl, long pos, int where )
/***************************************************/
{
hdl = hdl;
if( where == SEEK_SET ) {
objFilePos = pos;
} else if( where == SEEK_CUR ) {
objFilePos += pos;
} else {
objFilePos = objFileLen - pos;
}
return objFilePos;
}
extern void CloseObjFile( void )
/******************************/
{
MemFree( ObjFileName );
MemFree( objFileBuf );
}
static void initGlobals( void )
{
Sections.first = NULL;
Sections.last = NULL;
Publics.label_lists = NULL;
Publics.public_symbols = NULL;
Publics.number = 0;
}
static return_val createHashTables( void )
{
HandleToSectionTable = HashTableCreate( HANDLE_TO_SECTION_TABLE_SIZE, HASH_NUMBER, NumberCmp );
if( HandleToSectionTable ) {
HandleToLabelListTable = HashTableCreate( HANDLE_TO_LIST_TABLE_SIZE, HASH_NUMBER, NumberCmp );
if( HandleToLabelListTable ) {
HandleToRefListTable = HashTableCreate( HANDLE_TO_LIST_TABLE_SIZE, HASH_NUMBER, NumberCmp );
if( HandleToRefListTable ) {
SymbolToLabelTable = HashTableCreate( SYMBOL_TO_LABEL_TABLE_SIZE, HASH_NUMBER, NumberCmp );
if( SymbolToLabelTable ) {
NameRecognitionTable = HashTableCreate( RECOGNITION_TABLE_SIZE, HASH_STRING, (hash_table_comparison_func) stricmp );
if( !NameRecognitionTable ) {
HashTableFree( HandleToSectionTable );
HashTableFree( HandleToSectionTable );
HashTableFree( HandleToLabelListTable );
HashTableFree( HandleToRefListTable );
HashTableFree( SymbolToLabelTable );
return( OUT_OF_MEMORY );
}
} else {
HashTableFree( HandleToSectionTable );
HashTableFree( HandleToLabelListTable );
HashTableFree( HandleToRefListTable );
return( OUT_OF_MEMORY );
}
} else {
HashTableFree( HandleToSectionTable );
HashTableFree( HandleToLabelListTable );
return( OUT_OF_MEMORY );
}
} else {
HashTableFree( HandleToSectionTable );
return( OUT_OF_MEMORY );
}
} else {
return( OUT_OF_MEMORY );
}
return( OKAY );
}
static return_val initHashTables( void )
{
int loop;
return_val error;
error = createHashTables();
if( error == OKAY ) {
for( loop = 0; loop < NUM_ELTS( RecognizedName ); loop++ ) {
HashTableInsert( NameRecognitionTable, (hash_value) RecognizedName[loop].name, RecognizedName[loop].type );
}
}
return( error );
}
orl_machine_type GetMachineType( void )
{
return( ORLFileGetMachineType( ObjFileHnd ) );
}
/*
* Functions to convert data from the file format to the host format where the data may be byte swapped.
* If the ORL file is not marked as the opposite endianness as that of the host, then the data will
* not be byte swapped. This may not always be the correct behaviour, but if the data is not marked as
* a particular endianness, what are we to do about it?
*/
#ifdef __BIG_ENDIAN__
#define ENDIANNESS_TEST ORL_FILE_FLAG_LITTLE_ENDIAN
#else
#define ENDIANNESS_TEST ORL_FILE_FLAG_BIG_ENDIAN
#endif
unsigned_16 FileU16toHostU16(unsigned_16 value)
{
orl_file_flags flags = ORLFileGetFlags( ObjFileHnd );
if( flags & ENDIANNESS_TEST )
return ( SWAPNC_16( value ) );
return value;
}
unsigned_32 FileU32toHostU32(unsigned_32 value)
{
orl_file_flags flags = ORLFileGetFlags( ObjFileHnd );
if( flags & ENDIANNESS_TEST )
return ( SWAPNC_32( value ) );
return value;
}
unsigned_64 FileU64toHostU64(unsigned_64 value)
{
orl_file_flags flags = ORLFileGetFlags( ObjFileHnd );
if( flags & ENDIANNESS_TEST ){
unsigned_64 new_value;
new_value.u._64[0] = SWAPNC_64( value.u._64[0] );
return new_value;
}
return value;
}
static return_val initORL( void )
{
orl_file_flags flags;
orl_machine_type machine_type;
orl_return error = OKAY;
orl_file_format type;
bool byte_swap;
oFuncs.alloc = &MemAlloc;
oFuncs.free = &MemFree;
oFuncs.read = &objRead;
oFuncs.seek = &objSeek;
ORLHnd = ORLInit( &oFuncs );
if( ORLHnd ) {
type = ORLFileIdentify( ORLHnd, NULL );
if( type == ORL_UNRECOGNIZED_FORMAT ) {
PrintErrorMsg( OKAY, WHERE_NOT_COFF_ELF );
return( ERROR );
}
ObjFileHnd = ORLFileInit( ORLHnd, NULL, type );
if( ObjFileHnd ) {
// check byte order
flags = ORLFileGetFlags( ObjFileHnd );
byte_swap = FALSE;
#ifdef __BIG_ENDIAN__
if( flags & ORL_FILE_FLAG_LITTLE_ENDIAN ) {
byte_swap = TRUE;
}
#else
if( flags & ORL_FILE_FLAG_BIG_ENDIAN ) {
byte_swap = TRUE;
}
#endif
// check intended machine type
machine_type = GetMachineType();
switch( machine_type ) {
// If there's no machine specific code, the CPU we choose shouldn't
// matter; there are some object files like this.
case ORL_MACHINE_TYPE_NONE:
case ORL_MACHINE_TYPE_ALPHA:
if( DisInit( DISCPU_axp, &DHnd, byte_swap ) != DR_OK ) {
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
break;
case ORL_MACHINE_TYPE_PPC601:
if( DisInit( DISCPU_ppc, &DHnd, byte_swap ) != DR_OK ) {
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
// PAS assembler expects "", not \" for quotes.
if( !(Options & METAWARE_COMPATIBLE) ) {
QuoteChar = '\"';
}
break;
case ORL_MACHINE_TYPE_R3000:
case ORL_MACHINE_TYPE_R4000:
if( DisInit( DISCPU_mips, &DHnd, byte_swap ) != DR_OK ) {
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
break;
case ORL_MACHINE_TYPE_I386:
case ORL_MACHINE_TYPE_I8086:
if( DisInit( DISCPU_x86, &DHnd, byte_swap ) != DR_OK ) {
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
break;
case ORL_MACHINE_TYPE_AMD64:
if( DisInit( DISCPU_x64, &DHnd, byte_swap ) != DR_OK ) {
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
break;
case ORL_MACHINE_TYPE_SPARC:
if( DisInit( DISCPU_sparc, &DHnd, byte_swap ) != DR_OK ) {
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
break;
default:
ORLFini( ORLHnd );
PrintErrorMsg( OKAY, WHERE_UNSUPPORTED_PROC );
return( ERROR );
}
} else {
error = ORLGetError( ORLHnd );
// An "out of memory" error is not necessarily what it seems.
// The ORL returns this error when encountering a bad or
// unrecognized object file record.
if( error == ORL_OUT_OF_MEMORY ) {
PrintErrorMsg( OUT_OF_MEMORY, WHERE_OPENING_ORL );
} else {
PrintErrorMsg( ERROR, WHERE_OPENING_ORL );
}
}
if( error != OKAY ) {
ORLFini( ORLHnd );
}
} else {
error = OUT_OF_MEMORY;
}
return( error );
}
static return_val initServicesUsed( void )
{
return( initORL() );
}
static return_val initSectionTables( void )
{
return_val error;
orl_return o_error;
section_ptr sec;
// list for references to external functions, etc.
error = createLabelList( 0 );
if( error == OKAY ) {
o_error = ORLFileScan( ObjFileHnd, NULL, §ionInit );
if( o_error == ORL_OKAY && symbolTable ) {
o_error = DealWithSymbolSection( symbolTable );
if( o_error == ORL_OKAY ) {
sec = relocSections.first;
while( sec ) {
o_error = DealWithRelocSection( sec->shnd );
if( o_error != ORL_OKAY ) {
if( o_error == ORL_OUT_OF_MEMORY ) {
return( OUT_OF_MEMORY );
} else {
return( ERROR );
}
}
relocSections.first = sec->next;
MemFree( sec );
sec = relocSections.first;
}
error = processDrectveSection( drectveSection );
} else {
if( o_error == ORL_OUT_OF_MEMORY ) {
return( OUT_OF_MEMORY );
} else {
return( ERROR );
}
}
}
}
return( error );
}
void PrintErrorMsg( return_val exit_code, int where )
{
ChangePrintDest( STDERR_FILENO );
if( exit_code == OUT_OF_MEMORY ) {
BufferMsg( OUT_OF_MEMORY );
} else if( exit_code == ERROR ) {
BufferMsg( ERROR_OCCURRED );
}
BufferMsg( where );
BufferConcatNL();
BufferPrint();
ChangePrintDest( OutputDest );
}
void LeaveProgram( return_val exit_code, int message )
{
PrintErrorMsg( exit_code, message );
exit( exit_code );
}
void Init( void )
{
char cmd_line[ CMD_LINE_LEN ];
return_val error;
char **list;
relocSections.first = NULL;
relocSections.last = NULL;
if( !MsgInit() ) {
// MsgInit does its own error message printing
exit( -1 );
}
MemOpen();
getcmd( cmd_line );
HandleArgs( cmd_line );
openFiles();
initGlobals();
error = initHashTables();
if( error == OKAY ) {
error = initServicesUsed();
if( error == OKAY ) {
error = initSectionTables();
if( error != OKAY ) {
// free hash tables and services
MemClose();
LeaveProgram( error, WHERE_CREATE_SEC_TABLES );
}
} else {
// free hash tables
CloseFiles();
FreeHashTables();
// initServicesUsed does its own error message printing
exit( error );
}
} else {
CloseFiles();
MemClose();
LeaveProgram( error, WHERE_INIT_HASH_TABLES );
}
if( Options & PRINT_PUBLICS ) {
CreatePublicsArray();
}
if( IsMasmOutput() ) {
CommentString = MASM_COMMENT_STRING;
}
if( IsIntelx86() ) {
SkipRefTable = HashTableCreate( RECOGNITION_TABLE_SIZE, HASH_STRING,
(hash_table_comparison_func) stricmp );
if( SkipRefTable ) {
list = intelSkipRefList;
while( *list ) {
error = HashTableInsert( SkipRefTable, (hash_value) *list,
(hash_data) *list );
if( error != OKAY ) break;
list++;
}
}
}
if( !LabelChar ) {
if( IsMasmOutput() ) {
LabelChar = 'L';
} else {
LabelChar = 'X';
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?