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 + -
显示快捷键?