cmdos2.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,220 行 · 第 1/3 页
C
1,220 行
/****************************************************************************
*
* 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: Processing of linker options for OS/2 and Windows formats.
*
****************************************************************************/
#include <string.h>
#include <ctype.h>
#include "linkstd.h"
#include "alloc.h"
#include "command.h"
#include "cmdos2.h"
#include "exeos2.h"
#include "exepe.h"
#include "loados2.h"
#include "loadpe.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "objfree.h"
#include "cmdline.h"
#include "fileio.h"
#include "impexp.h"
#include "objpass1.h"
static void ParseVersion( void );
static bool GetWlibImports( void );
static bool getimport( void );
static bool getexport( void );
static bool getsegflags( void );
extern bool ProcOS2Import( void )
/*******************************/
{
return( ProcArgList( &getimport, 0 ) );
}
extern bool ProcOS2Export( void )
/*******************************/
{
bool retval;
if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
retval = GetWlibImports();
} else {
retval = ProcArgList( &getexport, 0 );
}
return( retval );
}
extern bool ProcAnonExport( void )
/********************************/
{
bool retval;
CmdFlags |= CF_ANON_EXPORT;
retval = ProcOS2Export();
CmdFlags &= ~CF_ANON_EXPORT;
return( retval );
}
extern bool ProcOS2Segment( void )
/********************************/
{
return( ProcArgList( &getsegflags, TOK_INCLUDE_DOT ) );
}
static bool GetWlibImports( void )
/********************************/
/* read in a wlib command file, get the import directives, and treat them
* as exports (hey man, GO asked for it ...... ) */
{
char * fname;
char * symname;
char * internal;
f_handle handle;
unsigned_16 ordinal;
entry_export * exp;
fname = FileName( Token.this, Token.len, E_LBC, FALSE );
handle = QOpenR( fname );
SetCommandFile( handle, fname );
Token.locked = TRUE; /* make sure only this file parsed */
while( GetToken( SEP_SPACE, 0 ) ) {
if( Token.len <= 2 ) continue;
if( (Token.this[0] == '+') && (Token.this[1] == '+') ) {
Token.this += 2;
Token.len -= 2;
if( Token.this[0] == '\'' ) {
Token.thumb = REJECT;
if( !GetToken( SEP_QUOTE, 0 ) ) {
LnkMsg( LOC+LINE+ERR+MSG_BAD_WLIB_IMPORT, NULL );
RestoreCmdLine(); /* get rid of this file */
return( TRUE );
}
}
symname = tostring();
internal = NULL;
if( !GetToken( SEP_DOT_EXT, 0 ) ) {
LnkMsg( LOC+LINE+ERR+MSG_BAD_WLIB_IMPORT, NULL );
_LnkFree( symname );
RestoreCmdLine(); /* get rid of this file */
return( TRUE );
}
ordinal = 0;
if( GetToken( SEP_DOT_EXT, 0 ) ) {
if( getatoi( &ordinal ) != ST_IS_ORDINAL ) {
if( Token.len > 0 ) {
internal = symname;
symname = tostring();
}
if( GetToken( SEP_DOT_EXT, 0 )
&& getatoi( &ordinal ) != ST_IS_ORDINAL ) {
if( GetToken( SEP_DOT_EXT, 0 ) ) {
getatoi( &ordinal );
}
}
}
}
exp = AllocExport( symname, strlen(symname) );
exp->isanonymous = (CmdFlags & CF_ANON_EXPORT) != 0;
if( internal != NULL ) {
exp->sym = RefISymbol( internal );
_LnkFree( internal );
} else {
exp->sym = RefISymbol( symname );
}
exp->sym->info |= SYM_DCE_REF; // make sure it isn't removed
exp->ordinal = ordinal;
if( ordinal == 0 ) {
exp->isresident = TRUE; // no ord spec'd so must be resident
}
AddToExportList( exp );
}
}
Token.locked = FALSE;
return( TRUE );
}
static bool getimport( void )
/***************************/
{
length_name intname;
length_name modname;
length_name extname;
unsigned_16 ordinal;
ord_state state;
intname.name = tostring();
intname.len = strlen( intname.name );
if( !GetToken( SEP_NO, 0 ) ) {
_LnkFree( intname.name );
return( FALSE );
}
modname.name = tostring();
modname.len = strlen( modname.name );
state = ST_INVALID_ORDINAL; // assume to extname or ordinal.
if( GetToken( SEP_PERIOD, TOK_INCLUDE_DOT ) ) {
state = getatoi( &ordinal );
if( state == ST_NOT_ORDINAL ) {
extname.name = tostring();
extname.len = strlen( extname.name );
} else if( state == ST_INVALID_ORDINAL ) {
LnkMsg( LOC+LINE+MSG_IMPORT_ORD_INVALID + ERR, NULL );
_LnkFree( intname.name );
_LnkFree( modname.name );
return( TRUE );
}
}
if( state == ST_IS_ORDINAL ) {
HandleImport( &intname, &modname, &intname, ordinal );
} else {
if( state == ST_NOT_ORDINAL ) {
HandleImport( &intname, &modname, &extname, NOT_IMP_BY_ORDINAL );
_LnkFree( extname.name );
} else {
HandleImport( &intname, &modname, &intname, NOT_IMP_BY_ORDINAL );
}
}
_LnkFree( intname.name );
_LnkFree( modname.name );
return( TRUE );
}
static bool getexport( void )
/***************************/
{
entry_export * exp;
unsigned_16 value;
exp = AllocExport( Token.this, Token.len );
exp->isanonymous = (CmdFlags & CF_ANON_EXPORT) != 0;
if( GetToken( SEP_PERIOD, TOK_INCLUDE_DOT ) ) {
if( getatol( &exp->ordinal ) != ST_IS_ORDINAL ) {
LnkMsg( LOC+LINE+ERR + MSG_EXPORT_ORD_INVALID, NULL );
_LnkFree( exp );
GetToken( SEP_EQUALS, TOK_INCLUDE_DOT );
return( TRUE );
}
}
if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
exp->sym = SymXOp( ST_CREATE|ST_REFERENCE, Token.this, Token.len );
if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
exp->impname = tostring();
}
} else {
exp->sym = RefISymbol( exp->name );
}
exp->sym->info |= SYM_DCE_REF; //make sure it is not removed
if( exp->ordinal == 0 ) {
exp->isresident = TRUE; // no ordinal spec'd so must be kept resident
}
exp->next = FmtData.u.os2.exports; // put in the front of the list for
FmtData.u.os2.exports = exp; // now so ProcResidant can get to it.
while( ProcOne( Exp_Keywords, SEP_NO, FALSE ) ) {} // handle misc options
FmtData.u.os2.exports = exp->next; // take it off the list
exp->iopl_words = 0;
if(!(FmtData.type & (MK_WINDOWS|MK_PE)) &&GetToken(SEP_NO,TOK_INCLUDE_DOT)) {
if( getatoi( &value ) == ST_IS_ORDINAL ) {
if( value > 63 ) {
LnkMsg( LOC+LINE+MSG_TOO_MANY_IOPL_WORDS+ ERR, NULL );
} else {
exp->iopl_words = value;
}
} else {
Token.thumb = REJECT; // reprocess the token.
}
}
AddToExportList( exp );
return( TRUE );
}
extern bool ProcExpResident( void )
/*********************************/
{
FmtData.u.os2.exports->isresident = TRUE;
return( TRUE );
}
extern bool ProcPrivate( void )
/******************************/
{
FmtData.u.os2.exports->isprivate = TRUE;
return( TRUE );
}
extern bool ProcOS2Alignment( void )
/**********************************/
/* process Alignment option */
{
ord_state ret;
unsigned_32 value;
if( !HaveEquals(0) ) return( FALSE );
ret = getatol( &value );
if( ret != ST_IS_ORDINAL || value == 0 ) {
return( FALSE );
}
FmtData.u.os2.segment_shift = blog_32( value - 1 ) + 1; //round up.
return( TRUE );
}
extern bool ProcObjAlign( void )
/******************************/
/* process ObjAlign option */
{
ord_state ret;
unsigned_32 value;
if( !HaveEquals(0) ) return( FALSE );
ret = getatol( &value );
if( ret != ST_IS_ORDINAL || value == 0 ) {
return( FALSE );
} /* value not a power of 2 */
if( value < 16 || value > (256*1024UL*1024) || (value & (value-1)) ) {
LnkMsg( LOC+LINE+WRN+MSG_VALUE_INCORRECT, "s", "objalign" );
value = 64*1024;
}
FmtData.objalign = value;
ChkBase(value);
return( TRUE );
}
extern bool ProcModName( void )
/*****************************/
{
if( !HaveEquals(TOK_INCLUDE_DOT) ) return( FALSE );
FmtData.u.os2.res_module_name = totext();
return( TRUE );
}
extern bool ProcNewFiles( void )
/******************************/
{
FmtData.u.os2.flags |= LONG_FILENAMES;
return( TRUE );
}
extern bool ProcProtMode( void )
/******************************/
{
FmtData.u.os2.flags |= PROTMODE_ONLY;
return( TRUE );
}
extern bool ProcOldLibrary( void )
/********************************/
{
if( !HaveEquals(TOK_INCLUDE_DOT | TOK_IS_FILENAME) ) return( FALSE );
FmtData.u.os2.old_lib_name = FileName( Token.this, Token.len, E_DLL, FALSE );
return( TRUE );
}
extern bool ProcOS2HeapSize( void )
/*********************************/
{
ord_state ret;
unsigned_32 value;
if( !HaveEquals(0) ) return( FALSE );
ret = getatol( &value );
if( ret != ST_IS_ORDINAL || value == 0 ) {
LnkMsg( LOC+LINE+WRN+MSG_VALUE_INCORRECT, "s", "heapsize" );
} else {
FmtData.u.os2.heapsize = value;
}
return( TRUE );
}
extern bool ProcDescription( void )
/*********************************/
{
if( !GetToken( SEP_NO, TOK_INCLUDE_DOT ) ) {
return( FALSE );
}
FmtData.u.os2.description = tostring();
return( TRUE );
}
extern bool ProcCommitStack( void )
/*********************************/
{
return( GetLong( &FmtData.u.pe.stackcommit ) );
}
extern bool ProcCommitHeap( void )
/********************************/
{
return( GetLong( &FmtData.u.pe.heapcommit ) );
}
static bool AddCommit( void )
/***************************/
{
Token.thumb = REJECT;
if( ProcOne( CommitKeywords, SEP_NO, FALSE ) == FALSE ) return( FALSE );
return( TRUE );
}
extern bool ProcCommit( void )
/****************************/
// set NT stack commit and heap sizes.
{
return( ProcArgList( AddCommit, TOK_INCLUDE_DOT ) );
}
extern bool ProcRWRelocCheck( void )
/**********************************/
// check for segment relocations pointing to read/write data segments
{
FmtData.u.os2.chk_seg_relocs = TRUE;
return( TRUE );
}
extern bool ProcSelfRelative( void )
/**********************************/
{
FmtData.u.os2.gen_rel_relocs = TRUE;
return( TRUE );
}
extern bool ProcInternalRelocs( void )
/************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?