impexp.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 555 行 · 第 1/2 页

C
555
字号
/****************************************************************************
*
*                            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:  Utilities for handling imports and exports.
*
****************************************************************************/


#include <string.h>
#include <ctype.h>
#include "walloca.h"
#include "linkstd.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "specials.h"
#include "fileio.h"
#include "alloc.h"
#include "exeos2.h"
#include "exeflat.h"
#include "exepe.h"
#include "exedos.h"
#include "objstrip.h"
#include "ring.h"
#include "carve.h"
#include "strtab.h"
#include "permdata.h"
#include "loados2.h"
#include "loadpe.h"
#include "impexp.h"

static void ReadOldLib( void );
static void ReadNameTable( f_handle the_file );

static entry_export * FindPlace( entry_export *exp )
/**************************************************/
// finds the correct place to put exp to keep the export list sorted.
{
    entry_export *  place;
    entry_export *  prev;
    entry_export *  ret;

    ret = NULL;
    place = exp->next;
    if( place != NULL && place->ordinal <= exp->ordinal ) {
        for(;;) {
            if( place->ordinal == exp->ordinal ) {
                LnkMsg( WRN + MSG_DUP_EXP_ORDINAL, NULL );
                exp->ordinal = 0;    // if duplicate, assign a new one later
                break;
            } else if ( place->ordinal > exp->ordinal ) {
                ret = exp->next;      //note: this can't happen 1st time
                exp->next = place;
                prev->next = exp;
                break;
            }
            if( place->next == NULL ) {  // no more entries, so put on the
                ret = exp->next;     // end, then break the loop.
                place->next = exp;
                exp->next = NULL;
                break;
            }
            prev = place;
            place = place->next;
        }
    }
    return( ret );
}

static entry_export *FreeAnExport( entry_export *exp )
/****************************************************/
{
    entry_export *  next;

    _LnkFree( exp->impname );
    next = exp->next;
    CarveFree( CarveExportInfo, exp );
    return( next );
}

extern void FreeExportList( void )
/********************************/
{
    entry_export *  exp;

    if( LinkFlags & INC_LINK_FLAG ) return;
    exp = FmtData.u.os2.exports;
    while( exp != NULL ) {
        exp = FreeAnExport( exp );
    }
}

extern void AddToExportList( entry_export *exp )
/**********************************************/
{
    entry_export **     owner;
    entry_export **     place;
    entry_export *      curr;
    size_t              len;
    size_t              currlen;

    place = NULL;
    owner = &FmtData.u.os2.exports;
    len = strlen( exp->name );
    for( ;; ) {
        curr = *owner;
        if( curr == NULL ) break;
        currlen = strlen( curr->name );
        if( currlen == len && CmpRtn( curr->name, exp->name, len ) == 0 ) {
            if( !IS_FMT_INCREMENTAL(ObjFormat) ) {
                if( !IS_SYM_COMDAT(exp->sym) ) {
                    LnkMsg( LOC+WRN+MSG_DUP_EXP_NAME, "s", curr->name );
                }
                FreeAnExport( exp );
            }
            return;
        }
        if( place == NULL ) {
            if( exp->ordinal == 0 ) {
                if( curr->ordinal != 0 ) place = owner;
            } else if( curr->ordinal == exp->ordinal ) {
                LnkMsg( WRN+MSG_DUP_EXP_ORDINAL, NULL );
                exp->ordinal = 0;    // if duplicate, assign a new one later
                place = &FmtData.u.os2.exports;
            } else if ( curr->ordinal > exp->ordinal ) {
                place = owner;
            }
        }
        owner = &curr->next;
    }
    if( IS_SYM_VF_REF( exp->sym ) ) {
        ClearRefInfo( exp->sym );
    }
    exp->sym->e.export = exp;
    exp->sym->info |= SYM_EXPORTED;
    if( place == NULL ) place = owner;
    DEBUG(( DBG_NEW, "%s", exp->name ));
    exp->next = *place;
    *place = exp;
}

static unsigned CheckStdCall( char *name, unsigned len )
/******************************************************/
// check to see if a name is in the stdcall _name@xx format
// this returns the total number of characters to be removed from the name
// including the beginning _
{
    char *      teststr;
    unsigned    chop;

    if( len <= 3 ) return 0;
    chop = 0;
    teststr = name + len - 1;
    if( *name == '_' && isdigit(*teststr) ) {
        teststr--;
        if( *teststr == '@' ) {
            chop = 3;
        } else if( isdigit(*teststr) ) {
            teststr--;
            if( *teststr == '@' ) {
                chop = 4;
            }
        }
    }
    return chop;
}

extern entry_export * AllocExport( char *name, unsigned len )
/***********************************************************/
{
    entry_export *  exp;
    unsigned        chop;

    exp = CarveAlloc( CarveExportInfo );
    exp->isexported = TRUE;
    exp->isprivate = FALSE;
    exp->ismovable = FALSE;
    exp->isresident = FALSE;
    exp->isfree = FALSE;
    if( name == NULL ) {
        exp->name = NULL;
    } else {
        if( FmtData.type & MK_PE && FmtData.u.pe.no_stdcall ) {
            chop = CheckStdCall( name, len );
            if( chop > 0 ) {
                name++;
                len -= chop;
            }
        }
        ReserveStringTable( &PermStrings, len + 1 );
        exp->name = AddStringTable( &PermStrings, name, len );
        CharStringTable( &PermStrings, '\0' );
    }
    exp->impname = NULL;
    exp->iopl_words = 0;
    exp->ordinal = 0;
    return exp;
}

#define EXPDEF_ORDINAL  0x80
#define EXPDEF_RESIDENT 0x40
#define EXPDEF_IOPLMASK 0x1F

extern void MSExportKeyword( length_name *expname, length_name *intname,
                             unsigned flags, unsigned ordinal )
/**********************************************************************/
// Process the Microsoft Export keyword.
{
    entry_export *  exp;

    exp = AllocExport( expname->name, expname->len );
    exp->isanonymous = FALSE;
    exp->iopl_words = flags & EXPDEF_IOPLMASK;
    exp->isresident = (flags & EXPDEF_RESIDENT) != 0;
    if( intname->len != 0 ) {
        exp->sym = SymXOp( ST_CREATE|ST_REFERENCE, intname->name, intname->len);
    } else {
        exp->sym = SymXOp( ST_CREATE|ST_REFERENCE, expname->name, expname->len);
    }
    if( LinkFlags & STRIP_CODE ) {
        DataRef( exp->sym );    // make sure it isn't removed.
    }
    if( flags & EXPDEF_ORDINAL ) {
        exp->ordinal = ordinal;
    } else {
        exp->isresident = TRUE; // no ordinal specd == isresident
    }
    AddToExportList( exp );
}

extern dll_sym_info * AllocDLLInfo( void )
/****************************************/
{
    dll_sym_info * dll;

    dll = CarveAlloc( CarveDLLInfo );
    dll->isfree = FALSE;
    return dll;
}

extern void FreeImport( dll_sym_info * dll )
/******************************************/
{
    CarveFree( CarveDLLInfo, dll );
}

static symbol * GetIATSym( symbol *sym )
/**************************************/
{
    char *      iatname;
    size_t      prefixlen;
    size_t      namelen;
    char *      name;

    name = sym->name;
    if( LinkState & HAVE_PPC_CODE) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?