objorl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 935 行 · 第 1/3 页
C
935 行
/****************************************************************************
*
* 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: Object file processing routines specific to ORL.
*
****************************************************************************/
#include <unistd.h>
#include <string.h>
#include "linkstd.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "alloc.h"
#include <orl.h>
#include "specials.h"
#include "obj2supp.h"
#include "objnode.h"
#include "objcache.h"
#include "objio.h"
#include "cmdline.h"
#include "dbgall.h"
#include "objpass1.h"
#include "objpass2.h"
#include "objorl.h"
#include "strtab.h"
#include "carve.h"
#include "wcomdef.h"
#include "permdata.h"
#include "command.h" // NYI: don't want to include this!
#include "impexp.h"
#include "virtmem.h"
#include "loadfile.h"
#include "objstrip.h"
#include "toc.h"
static orl_handle ORLHandle;
static long ORLFilePos;
static long ORLSeek( void *, long, int );
static void * ORLRead( void *, size_t );
static void ClearCachedData( file_list *list );
static orl_funcs ORLFuncs = { ORLRead, ORLSeek, ChkLAlloc, LFree };
static orl_reloc SavedReloc;
static char * ImpExternalName;
static char * ImpModName;
static char * FirstCodeSymName;
static char * FirstDataSymName;
static unsigned_32 ImpOrdinal;
typedef struct readcache READCACHE;
typedef struct readcache {
READCACHE * next;
void * data;
} readcache;
static readcache * ReadCacheList;
extern void InitObjORL( void )
/****************************/
{
ORLHandle = ORLInit( &ORLFuncs );
ReadCacheList = NULL;
}
extern void ObjORLFini( void )
/****************************/
{
ORLFini( ORLHandle );
}
static long ORLSeek( void *_list, long pos, int where )
/*****************************************************/
{
file_list *list = _list;
if( where == SEEK_SET ) {
ORLFilePos = pos;
} else if( where == SEEK_CUR ) {
ORLFilePos += pos;
} else {
ORLFilePos = list->file->len - pos;
}
return ORLFilePos;
}
static void * ORLRead( void *_list, size_t len )
/**********************************************/
{
file_list * list = _list;
void * result;
readcache * cache;
result = CachePermRead( list, ORLFilePos, len );
ORLFilePos += len;
_ChkAlloc( cache, sizeof(readcache) );
cache->next = ReadCacheList;
ReadCacheList = cache;
cache->data = result;
return result;
}
extern bool IsORL( file_list * list, unsigned loc )
/*************************************************/
// return TRUE if this is can be handled by ORL
{
orl_file_format type;
bool isOK;
isOK = TRUE;
ORLSeek( list, loc, SEEK_SET );
type = ORLFileIdentify( ORLHandle, list );
if( type == ORL_ELF ) {
ObjFormat |= FMT_ELF;
} else if( type == ORL_COFF ) {
ObjFormat |= FMT_COFF;
} else {
isOK = FALSE;
}
ClearCachedData( list );
return isOK;
}
static orl_file_handle InitFile( void )
/*************************************/
{
orl_file_format type;
ImpExternalName = NULL;
ImpModName = NULL;
ImpOrdinal = 0;
FirstCodeSymName = NULL;
FirstDataSymName = NULL;
if( IS_FMT_ELF(ObjFormat) ) {
type = ORL_ELF;
} else {
type = ORL_COFF;
}
return ORLFileInit( ORLHandle, CurrMod->f.source, type );
}
static void ClearCachedData( file_list *list )
/********************************************/
{
readcache * cache;
readcache * next;
for( cache = ReadCacheList; cache != NULL; cache = next ) {
next = cache->next;
CacheFree( list, cache->data );
_LnkFree( cache );
}
ReadCacheList = NULL;
}
static void FiniFile( orl_file_handle filehdl, file_list *list )
/**************************************************************/
{
ORLFileFini( filehdl );
ClearCachedData( list );
if( ImpModName != NULL ) {
_LnkFree( ImpModName );
ImpModName = NULL;
}
}
extern void ORLSkipObj( file_list *list, unsigned long *loc )
/***********************************************************/
// skip the object file.
// NYI: add an entry point in ORL for a more efficient way of doing this.
{
orl_file_handle filehdl;
ORLSeek( list, *loc, SEEK_SET );
filehdl = InitFile(); // assumes that entire file is read!
*loc = ORLSeek( list, 0, SEEK_CUR );
FiniFile( filehdl, list );
}
static bool CheckFlags( orl_file_handle filehdl )
/***********************************************/
{
orl_machine_type machtype;
stateflag typemask;
stateflag test;
orl_file_flags flags;
machtype = ORLFileGetMachineType( filehdl );
switch( machtype ) {
case ORL_MACHINE_TYPE_I386:
typemask = HAVE_I86_CODE;
break;
case ORL_MACHINE_TYPE_ALPHA:
typemask = HAVE_ALPHA_CODE;
break;
case ORL_MACHINE_TYPE_PPC601:
typemask = HAVE_PPC_CODE;
break;
case ORL_MACHINE_TYPE_R3000:
typemask = HAVE_MIPS_CODE;
break;
case ORL_MACHINE_TYPE_NONE:
typemask = 0;
break;
default:
typemask = HAVE_MACHTYPE_MASK; // trigger the error
break;
}
test = (typemask | LinkState) & HAVE_MACHTYPE_MASK;
test &= test - 1; // turn off one bit
if( test != 0 ) { // multiple bits were turned on.
LnkMsg( WRN+MSG_MACHTYPE_DIFFERENT, "s", CurrMod->f.source->file->name);
} else {
LinkState |= typemask;
}
if( ORLFileGetType( filehdl ) != ORL_FILE_TYPE_OBJECT ) {
BadObject();
return FALSE;
}
flags = ORLFileGetFlags( filehdl );
#if 0
if( flags & ORL_FILE_FLAG_BIG_ENDIAN ) { // MS lies about this.
LnkMsg( ERR+LOC+MSG_NO_BIG_ENDIAN, NULL );
return FALSE;
}
#endif
if( flags & ORL_FILE_FLAG_16BIT_MACHINE ) {
Set16BitMode();
} else {
Set32BitMode();
}
return TRUE;
}
static orl_return NullFunc( orl_sec_handle dummy )
/************************************************/
// section type is ignored
{
dummy = dummy;
return ORL_OKAY;
}
static orl_return ExportCallback( char *name, void *dummy )
/*********************************************************/
{
length_name lname;
dummy = dummy;
lname.name = name;
lname.len = strlen(name);
HandleExport( &lname, &lname, 0, 0 );
return ORL_OKAY;
}
static orl_return EntryCallback( char *name, void *dummy )
/*********************************************************/
{
if( !StartInfo.user_specd ) {
SetStartSym( name );
}
return ORL_OKAY;
}
static orl_return DeflibCallback( char *name, void *dummy )
/*********************************************************/
{
dummy = dummy;
AddCommentLib( name, strlen(name), 0xfe );
return ORL_OKAY;
}
static orl_return P1Note( orl_sec_handle sec )
/********************************************/
// handle extra object file information records
{
orl_note_callbacks cb;
cb.export_fn = ExportCallback;
cb.deflib_fn = DeflibCallback;
cb.entry_fn = EntryCallback;
ORLNoteSecScan( sec, &cb, NULL );
return ORL_OKAY;
}
static orl_return Unsupported( orl_sec_handle dummy )
/***************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?