objomf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,112 行 · 第 1/3 页
C
1,112 行
/****************************************************************************
*
* 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 OMF.
*
****************************************************************************/
#include <string.h>
#include "linkstd.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "alloc.h"
#include <pcobj.h>
#include "obj2supp.h"
#include "objnode.h"
#include "objcalc.h"
#include "objio.h"
#include "objcache.h"
#include "wcomdef.h"
#include "cmdline.h"
#include "loadfile.h"
#include "dbgall.h"
#include "objpass1.h"
#include "objstrip.h"
#include "omfreloc.h"
#include "carve.h"
#include "strtab.h"
#include "permdata.h"
#include "virtmem.h"
#include "impexp.h"
#include "objomf.h"
/* forward declarations */
static void Pass1Cmd( byte );
static void ProcTHEADR( void );
static void Comment( void );
static void AddNames( void );
static void ProcSegDef( void );
static void ProcPubdef( bool static_sym );
static void UseSymbols( bool static_sym, bool iscextdef );
static void DefineGroup( void );
static void ProcLinnum( void );
static void ProcLxdata( bool islidata );
static void ProcLxdata( bool islidata );
static void ProcModuleEnd( void );
static void ProcAlias( void );
static void DoLazyExtdef( bool isweak );
static void ProcVFTableRecord( bool ispure );
static void ProcVFReference( void );
static void GetObject( segdata * seg, unsigned_32 obj_offset, bool lidata );
byte OMFAlignTab[] = {0,0,1,4,8,2,12};
enum dll_entry_type { DLL_RELOC_NAME, DLL_RELOC_ORDINAL };
void ResetObjOMF( void )
/**********************/
{
ObjBuff = NULL;
EOObjRec = NULL;
}
static unsigned long ProcObj( file_list * file, unsigned long loc,
void (*procrtn)( byte ) )
/****************************************************************/
/* Process an object file. */
{
obj_record * rec;
byte cmd;
unsigned_16 len;
RecNum = 0;
do {
ObjFormat &= ~FMT_MS_386; // assume not a Microsoft 386 .obj file
rec = CacheRead( file, loc, sizeof(obj_record) );
if( rec == NULL ) {
EarlyEOF();
break;
}
loc += sizeof( obj_record );
len = rec->length;
cmd = rec->command;
if( procrtn != NULL ) {
RecNum++;
ObjBuff = CacheRead( file, loc, len );
if( ObjBuff == NULL ) {
EarlyEOF();
break;
}
EOObjRec = ObjBuff + len - 1; // 1 for the checksum.
(*procrtn)( cmd );
if( ObjBuff > EOObjRec ) {
BadObject();
break;
}
}
loc += len;
} while( cmd != CMD_MODEND && cmd != CMD_MODE32 );
return( loc );
}
static void CheckUninit( void *_seg, void *dummy )
/************************************************/
{
segnode *seg = _seg;
dummy = dummy;
if( !(seg->info & SEG_LXDATA_SEEN) ) {
seg->entry->isuninit = TRUE;
if( seg->entry->data != NULL ) {
ReleaseInfo( seg->entry->data );
seg->entry->data = NULL;
}
}
}
extern unsigned long OMFPass1( void )
/***********************************/
// do pass 1 for OMF object files
{
unsigned long retval;
PermStartMod( CurrMod );
if( LinkState & (HAVE_MACHTYPE_MASK & ~HAVE_I86_CODE) ) {
LnkMsg( WRN+MSG_MACHTYPE_DIFFERENT, "s", CurrMod->f.source->file->name);
} else {
LinkState |= HAVE_I86_CODE;
}
CurrMod->omfdbg = OMF_DBG_CODEVIEW; // Assume MS style LINNUM records
retval = ProcObj( CurrMod->f.source, CurrMod->location, &Pass1Cmd );
IterateNodelist( SegNodes, CheckUninit, NULL );
ResolveComdats();
return retval;
}
static void Pass1Cmd( byte cmd )
/******************************/
/* Process an object record for pass 1 */
{
bool isstatic;
isstatic = FALSE;
switch( cmd ) {
case CMD_THEADR:
ProcTHEADR();
break;
case CMD_COMENT:
Comment();
break;
case CMD_LLNAME:
case CMD_LNAMES:
AddNames();
break;
case CMD_SEGD32:
ObjFormat |= FMT_MS_386;
case CMD_SEGDEF:
CurrMod->modinfo |= MOD_NEED_PASS_2;
ProcSegDef();
break;
case CMD_STATIC_PUBD32:
ObjFormat |= FMT_MS_386;
case CMD_STATIC_PUBDEF:
ProcPubdef( TRUE );
break;
case CMD_PUBD32:
ObjFormat |= FMT_MS_386;
case CMD_PUBDEF:
ProcPubdef( FALSE );
break;
case CMD_STATIC_EXTDEF:
case CMD_STATIC_EXTD32:
isstatic = TRUE;
case CMD_EXTDEF:
CurrMod->modinfo |= MOD_NEED_PASS_2;
UseSymbols( isstatic, FALSE );
break;
case CMD_CEXTDF:
CurrMod->modinfo |= MOD_NEED_PASS_2;
UseSymbols( FALSE, TRUE );
break;
case CMD_GRPDEF:
DefineGroup();
break;
case CMD_LINN32:
ObjFormat |= FMT_MS_386;
case CMD_LINNUM:
if (CurrMod->omfdbg == OMF_DBG_CODEVIEW)
ProcLinnum();
break;
case CMD_LINS32:
ObjFormat |= FMT_MS_386;
case CMD_LINSYM:
ProcLinsym();
break;
case CMD_STATIC_COMDEF:
isstatic = TRUE;
case CMD_COMDEF:
CurrMod->modinfo |= MOD_NEED_PASS_2;
ProcComdef( isstatic );
break;
case CMD_COMD32:
ObjFormat |= FMT_MS_386;
case CMD_COMDAT:
CurrMod->modinfo |= MOD_NEED_PASS_2;
ProcComdat();
break;
case CMD_LEDA32:
ObjFormat |= FMT_MS_386;
case CMD_LEDATA:
ProcLxdata( FALSE );
break;
case CMD_LIDA32:
ObjFormat |= FMT_MS_386;
case CMD_LIDATA:
ProcLxdata( TRUE );
break;
case CMD_FIXU32:
ObjFormat |= FMT_MS_386;
case CMD_FIXUP: /* count the fixups for each seg_leader */
CurrMod->modinfo |= MOD_NEED_PASS_2;
DoRelocs();
ObjFormat &= ~FMT_UNSAFE_FIXUPP;
break;
case CMD_MODE32:
ObjFormat |= FMT_MS_386;
case CMD_MODEND:
ProcModuleEnd();
break;
case CMD_ALIAS:
ProcAlias();
break;
case CMD_VERNUM:
case CMD_VENDEXT:
case CMD_BAKPAT:
case CMD_BAKP32:
case CMD_NBKPAT:
case CMD_NBKP32: /* ignore bakpats in pass 1 */
case CMD_LOCSYM:
case CMD_TYPDEF:
case CMD_DEBSYM:
case CMD_BLKDEF:
case CMD_BLKD32:
case CMD_BLKEND:
case CMD_BLKE32:
/* ignore the Intel debugging records */
break;
case CMD_RHEADR:
case CMD_REGINT:
case CMD_REDATA:
case CMD_RIDATA:
case CMD_OVLDEF:
case CMD_ENDREC:
case CMD_LHEADR:
case CMD_PEDATA:
case CMD_PIDATA:
case CMD_LIBHED:
case CMD_LIBNAM:
case CMD_LIBLOC:
case CMD_LIBDIC:
LnkMsg( LOC_REC+WRN+MSG_REC_NOT_DONE, "x", cmd );
break;
default:
CurrMod->f.source->file->flags |= INSTAT_IOERR;
LnkMsg( LOC_REC+ERR+MSG_BAD_REC_TYPE, "x", cmd );
break;
}
}
extern bool IsOMF( file_list * list, unsigned long loc )
/******************************************************/
{
byte * rec;
rec = CacheRead( list, loc, sizeof(unsigned_8) );
return rec != NULL && *rec == CMD_THEADR;
}
extern char * GetOMFName( file_list *list, unsigned long * loc )
/**************************************************************/
{
obj_record *rec;
char * name;
char * newname;
unsigned len;
rec = CacheRead( list, *loc, sizeof(obj_record) );
if( rec == NULL ) return NULL;
*loc += sizeof( obj_record );
len = rec->length;
name = CacheRead( list, *loc, rec->length );
*loc += len;
if( name == NULL ) return NULL;
len = *name; // get actual name length
_ChkAlloc( newname, len + 1 );
memcpy( newname, name + 1, len );
*(newname + len) = '\0';
return newname;
}
extern void OMFSkipObj( file_list *list, unsigned long *loc )
/***********************************************************/
{
*loc = ProcObj( list, *loc, NULL );
}
static void ProcTHEADR( void )
/****************************/
{
}
static void LinkDirective( void )
/*******************************/
{
char directive;
unsigned char priority;
segnode * seg;
directive = *(char *)ObjBuff;
ObjBuff++;
switch( directive ) {
case LDIR_DEFAULT_LIBRARY:
if( ObjBuff + 1 < EOObjRec ) {
priority = *( char * )ObjBuff;
ObjBuff++;
AddCommentLib( ObjBuff, EOObjRec - ObjBuff, priority );
}
break;
case LDIR_SOURCE_LANGUAGE:
DBIP1Source( ObjBuff, EOObjRec );
break;
case LDIR_VF_PURE_DEF:
ProcVFTableRecord( TRUE );
break;
case LDIR_VF_TABLE_DEF:
ProcVFTableRecord( FALSE );
break;
case LDIR_VF_REFERENCE:
ProcVFReference();
break;
case LDIR_PACKDATA:
if( !(LinkFlags & PACKDATA_FLAG) ) {
PackDataLimit = _GetU32UN( ObjBuff );
LinkFlags |= PACKDATA_FLAG;
}
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?