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