objomf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,112 行 · 第 1/3 页
C
1,112 行
case LDIR_OPT_FAR_CALLS:
seg = (segnode *)FindNode( SegNodes, GetIdx() );
seg->entry->canfarcall = TRUE;
seg->entry->iscode = TRUE;
break;
case LDIR_FLAT_ADDRS:
CurrMod->modinfo |= MOD_FLATTEN_DBI;
break;
case LDIR_OPT_UNSAFE:
ObjFormat |= FMT_UNSAFE_FIXUPP;
break;
}
}
static void ReadName( length_name *ln_name )
/******************************************/
{
ln_name->len = *(unsigned char *)ObjBuff;
ObjBuff += sizeof( unsigned char );
ln_name->name = ObjBuff;
ObjBuff += ln_name->len;
}
#define EXPDEF_ORDINAL 0x80
static void ProcExportKeyword( void )
/***********************************/
{
unsigned_8 flags;
length_name intname;
length_name expname;
unsigned ordinal;
flags = *ObjBuff++;
ReadName( &expname );
ReadName( &intname );
ordinal = 0;
if( flags & EXPDEF_ORDINAL ) {
ordinal = GET_U16_UN(ObjBuff);
}
HandleExport( &expname, &intname, flags, ordinal );
}
static void ProcImportKeyword( void )
/***********************************/
{
length_name intname;
length_name modname;
length_name extname;
unsigned_8 info;
info = *(unsigned char *)ObjBuff;
ObjBuff += sizeof( unsigned char );
ReadName( &intname );
ReadName( &modname );
if( info == DLL_RELOC_NAME ) {
if( *ObjBuff == 0 ) { /* use internal name */
HandleImport( &intname, &modname, &intname, NOT_IMP_BY_ORDINAL );
} else {
ReadName( &extname );
HandleImport( &intname, &modname, &extname, NOT_IMP_BY_ORDINAL );
}
} else {
HandleImport(&intname, &modname, &extname, GET_U16_UN(ObjBuff) );
}
}
static void DoMSOMF( void )
/***********************************/
/* Figure out debug info type and handle it accordingly later. */
{
if (ObjBuff == EOObjRec)
CurrMod->omfdbg = OMF_DBG_CODEVIEW; /* Assume MS style */
else {
unsigned_8 version;
char *dbgtype;
version = *ObjBuff++;
dbgtype = ObjBuff;
ObjBuff += 2;
if( strncmp( dbgtype, "CV", 2 ) == 0 ) {
CurrMod->omfdbg = OMF_DBG_CODEVIEW;
} else if( strncmp( dbgtype, "HL", 2 ) == 0 ) {
CurrMod->omfdbg = OMF_DBG_HLL;
}
else {
CurrMod->omfdbg = OMF_DBG_UNKNOWN;
}
}
}
static void Comment( void )
/*************************/
/* Process a comment record. */
{
unsigned char attribute;
unsigned char class;
int proc;
unsigned char which;
attribute = *(unsigned char *)ObjBuff;
ObjBuff += sizeof( unsigned char );
class = *(unsigned char *)ObjBuff;
ObjBuff += sizeof( unsigned char );
switch( class ) {
case CMT_DLL_ENTRY:
which = *ObjBuff;
ObjBuff += sizeof( unsigned char );
switch( which ) {
case MOMF_IMPDEF:
case MOMF_EXPDEF:
SeenDLLRecord();
if( which == MOMF_EXPDEF ) {
ProcExportKeyword();
} else {
ProcImportKeyword();
}
break;
case MOMF_PROT_LIB:
if( FmtData.type & MK_WINDOWS ) {
FmtData.u.os2.is_private_dll = TRUE;
}
break;
}
break;
case CMT_WAT_PROC_MODEL:
case CMT_MS_PROC_MODEL:
proc = GET_U8_UN( ObjBuff ) - '0';
if( proc > FmtData.cpu_type ) FmtData.cpu_type = proc;
break;
case CMT_DOSSEG:
LinkState |= DOSSEG_FLAG;
break;
case CMT_DEFAULT_LIBRARY:
AddCommentLib( ObjBuff, EOObjRec - ObjBuff, 0xfe );
break;
case CMT_LINKER_DIRECTIVE:
LinkDirective();
break;
case CMT_WKEXT:
DoLazyExtdef( TRUE );
break;
case CMT_LZEXT:
DoLazyExtdef( FALSE );
break;
case CMT_EASY_OMF:
if( memcmp( ObjBuff, EASY_OMF_SIGNATURE, 5 ) == 0 ) {
ObjFormat |= FMT_EASY_OMF;
}
break;
case CMT_SOURCE_NAME:
DBIComment();
break;
case CMT_MS_OMF:
DoMSOMF();
break;
case 0x80: /* Code Gen used to put bytes out in wrong order */
if( attribute == CMT_SOURCE_NAME ) { /* no longer generated */
DBIComment();
} else if( attribute == CMT_LINKER_DIRECTIVE ) { /* linker directive */
LinkDirective();
}
break;
}
}
static void ProcAlias( void )
/***************************/
/* process a symbol alias directive */
{
char * alias;
int aliaslen;
char * target;
int targetlen;
symbol * sym;
while( ObjBuff < EOObjRec ) {
aliaslen = *ObjBuff;
ObjBuff++;
alias = ObjBuff;
ObjBuff += aliaslen;
targetlen = *ObjBuff;
ObjBuff++;
sym = SymXOp( ST_FIND | ST_NOALIAS, alias, aliaslen );
if( !sym || !(sym->info & SYM_DEFINED) ) {
_ChkAlloc( target, targetlen + 1 );
memcpy( target, ObjBuff, targetlen );
target[targetlen] = '\0';
MakeSymAlias( alias, aliaslen, target, targetlen );
}
ObjBuff += targetlen;
}
}
static void ProcModuleEnd( void )
/*******************************/
{
byte frame;
byte target;
unsigned targetidx;
segnode * seg;
extnode * ext;
bool hasdisp;
if( StartInfo.user_specd ) return;
if( *ObjBuff & 0x40 ) {
ObjBuff++;
if( ObjBuff == EOObjRec ) return; /* CSet/2 stupidity */
frame = (*ObjBuff >> 4) & 0x7;
target = *ObjBuff & 0x3;
hasdisp = (*ObjBuff & 0x4) == 0;
ObjBuff++;
if( frame <= 2 ) { /* frame requires an index */
SkipIdx();
}
targetidx = GetIdx();
switch( target ) {
case TARGET_SEGWD:
if( StartInfo.type != START_UNDEFED ) {
LnkMsg( LOC+ERR+MSG_MULT_START_ADDRS, NULL );
return; // <-------- NOTE: premature return
}
seg = (segnode *)FindNode( SegNodes, targetidx );
StartInfo.type = START_IS_SDATA;
StartInfo.targ.sdata= seg->entry;
if( seg->info & SEG_CODE && LinkFlags & STRIP_CODE ) {
RefSeg( (segdata *) seg->entry );
}
StartInfo.mod = CurrMod;
break;
case TARGET_EXTWD:
ext = (extnode *) FindNode( ExtNodes, targetidx );
SetStartSym( ext->entry->name );
break;
case TARGET_ABSWD:
case TARGET_GRPWD:
BadObject(); // no one does these, right???
break;
}
if( hasdisp ) {
if( ObjFormat & FMT_32BIT_REC ) {
_TargU32toHost( _GetU32UN( ObjBuff ), StartInfo.off );
} else {
_TargU16toHost( _GetU16UN( ObjBuff ), StartInfo.off );
}
}
}
}
static void AddNames( void )
/**************************/
/* Process NAMES record */
{
int name_len;
list_of_names ** entry;
DEBUG(( DBG_OLD, "AddNames()" ));
while( ObjBuff < EOObjRec ) {
name_len = ( (obj_name UNALIGN *) ObjBuff )->len;
entry = AllocNode( NameNodes );
*entry = MakeListName( ((obj_name UNALIGN *)ObjBuff)->name, name_len );
ObjBuff += name_len + sizeof( byte );
}
}
static void ProcSegDef( void )
/****************************/
/* process a segdef record */
{
segdata * sdata;
segnode * snode;
list_of_names * clname;
list_of_names * name;
byte acbp;
unsigned comb;
DEBUG(( DBG_OLD, "ProcSegDef()" ));
sdata = AllocSegData();
acbp = *ObjBuff;
++ObjBuff;
comb = (acbp >> 2) & 7;
if( comb == COMB_INVALID || comb == COMB_BAD ) {
sdata->combine = COMBINE_INVALID;
} else if( comb == COMB_COMMON ) {
sdata->combine = COMBINE_COMMON;
} else {
sdata->combine = COMBINE_ADD;
}
sdata->align = OMFAlignTab[acbp >> 5];
if( ObjFormat & FMT_EASY_OMF ) { // set USE_32 flag.
sdata->is32bit = TRUE;
} else if( acbp & 1 ) {
sdata->is32bit = TRUE;
}
switch( acbp >> 5 ) {
case ALIGN_ABS:
_TargU16toHost( _GetU16UN( ObjBuff ), sdata->a.frame );
sdata->isabs = TRUE;
ObjBuff += sizeof( unsigned_16 );
ObjBuff += sizeof( byte );
break;
case ALIGN_LTRELOC:
// in 32 bit object files, ALIGN_LTRELOC is actually ALIGN_4KPAGE
if( ObjFormat & FMT_32BIT_REC ) break;
sdata->align = OMFAlignTab[ALIGN_PARA];
ObjBuff += 5; /* step over ltldat, max_seg_len, grp_offs fields */
break;
}
if( ObjFormat & FMT_32BIT_REC ) {
if( acbp & 2 ) {
BadObject(); // we can't handle 4 GB segments properly
return;
}
_TargU32toHost( _GetU32UN( ObjBuff ), sdata->length );
ObjBuff += sizeof( unsigned_32 );
} else {
if( acbp & 2 ) {
sdata->length = 65536; // 64k segment
} else {
_TargU16toHost( _GetU16UN( ObjBuff ), sdata->length );
}
ObjBuff += sizeof( unsigned_16 );
}
name = FindName( GetIdx() );
sdata->u.name = name->name;
clname = FindName( GetIdx() );
if( ObjFormat & FMT_EASY_OMF ) {
SkipIdx(); // skip overlay name index
if( ObjBuff < EOObjRec ) { // the optional attribute field present
if( !(*ObjBuff & 0x4) ) { // if USE32 bit not set;
sdata->is32bit = FALSE;
}
}
}
sdata->iscode = IsCodeClass( clname->name, strlen(clname->name) );
snode = AllocNode( SegNodes );
snode->entry = sdata;
AllocateSegment( snode, clname->name );
}
static void DefineGroup( void )
/*****************************/
/* Define a group. */
{
int num_segs;
byte * anchor;
segnode * seg;
list_of_names * grp_name;
grpnode * newnode;
group_entry * group;
grp_name = FindName( GetIdx() );
DEBUG(( DBG_OLD, "DefineGroup() - %s", grp_name->name ));
anchor = ObjBuff;
num_segs = 0;
for(;;) {
if( ObjBuff >= EOObjRec ) break;
if( *ObjBuff != GRP_SEGIDX ) {
BadObject();
return;
}
++ObjBuff;
SkipIdx();/* skip segment index */
++num_segs;
}
newnode = AllocNode( GrpNodes );
group = SearchGroups( grp_name->name );
if( group == NULL ) {
if( num_segs == 0 ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?