genphar.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 518 行 · 第 1/2 页
C
518 行
/****************************************************************************
*
* 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: PharLap style OMF output routines.
*
****************************************************************************/
#include <string.h>
#include "watcom.h"
#include "womp.h"
#include "objprs.h"
#include "objio.h"
#include "pcobj.h"
#include "memutil.h"
#include "genutil.h"
#include "myassert.h"
#include "lifix.h"
#include "objrec.h"
STATIC lifix_list lifList;
STATIC int writeMisc( obj_rec *objr, pobj_state *state ) {
/*
For 16-bit records which are the same under Intel, PharLap, and MS OMFs
*/
uint_8 *ptr;
uint_16 len;
uint_16 save;
/**/myassert( objr != NULL );
/**/myassert( objr->data != NULL );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
save = ObjRTell( objr );
ObjRSeek( objr, 0 );
len = ObjRemain( objr );
ptr = ObjGet( objr, len );
ObjWriteRec( state->file_out, objr->command, len, ptr );
ObjRSeek( objr, save );
return( 0 );
}
STATIC int writeComent( obj_rec *objr, pobj_state *state ) {
uint_8 *ptr;
uint_16 len;
uint_16 save;
OBJ_WFILE *out;
/**/myassert( objr != NULL );
/**/myassert( objr->data != NULL );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
out = state->file_out;
ObjWBegRec( out, CMD_COMENT );
ObjWrite8( out, objr->d.coment.attr );
ObjWrite8( out, objr->d.coment.class );
save = ObjRTell( objr );
len = ObjRemain( objr );
ptr = ObjGet( objr, len );
ObjWrite( out, ptr, len );
ObjRSeek( objr, save );
ObjWEndRec( out );
return( 0 );
}
STATIC int writeSegdef( obj_rec *objr, pobj_state *state ) {
OBJ_WFILE *out;
uint_8 acbp;
uint_8 align;
char buf[ FIX_GEN_MAX ];
size_t len;
uint_8 access;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_SEGDEF );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
out = state->file_out;
ObjWBegRec( out, CMD_SEGDEF );
acbp = ( objr->d.segdef.combine << 2 );
align = objr->d.segdef.align;
switch( align ) {
case SEGDEF_ALIGN_ABS: acbp |= ALIGN_ABS << 5; break;
case SEGDEF_ALIGN_BYTE: acbp |= ALIGN_BYTE << 5; break;
case SEGDEF_ALIGN_WORD: acbp |= ALIGN_WORD << 5; break;
case SEGDEF_ALIGN_PARA: acbp |= ALIGN_PARA << 5; break;
case SEGDEF_ALIGN_PAGE: acbp |= ALIGN_PAGE << 5; break;
case SEGDEF_ALIGN_DWORD: acbp |= ALIGN_DWORD << 5; break;
case SEGDEF_ALIGN_4KPAGE: acbp |= ALIGN_4KPAGE << 5; break;
default:
/**/ never_reach();
}
/* FIXME no support for 2**32 BIG bit */
ObjWrite8( out, acbp );
if( align == SEGDEF_ALIGN_ABS ) {
len = FixGenPRef( &objr->d.segdef.abs, buf, FIX_GEN_PHARLAP );
ObjWrite( out, buf, len );
}
ObjWrite32( out, objr->d.segdef.seg_length );
ObjWriteIndex( out, objr->d.segdef.seg_name_idx );
ObjWriteIndex( out, objr->d.segdef.class_name_idx );
ObjWriteIndex( out, objr->d.segdef.ovl_name_idx );
if( objr->d.segdef.access_valid || objr->d.segdef.use_32 == 0 ) {
access = objr->d.segdef.use_32 ? EASY_USE32_FIELD : 0;
if( objr->d.segdef.access_valid ) {
access |= objr->d.segdef.access_attr;
} else {
access |= EASY_EXEC_READ;
}
ObjWrite8( out, access );
}
ObjWEndRec( out );
return( 0 );
}
STATIC int writeFixup( obj_rec *objr, pobj_state *state ) {
OBJ_WFILE *out;
fixup *walk;
char buf[ FIX_GEN_MAX ];
size_t len;
size_t len_written;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_FIXUP );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
walk = objr->d.fixup.fixup;
if( walk == NULL ) {
/* huh? this shouldn't really happen... */
return( 0 );
}
out = state->file_out;
/* we don't want to write FIXUP records that are too large, so we limit
our records to approximately 1024 bytes */
do {
len_written = 0;
ObjWBegRec( out, CMD_FIXUP );
while( walk != NULL && len_written < 1024 - FIX_GEN_MAX ) {
walk->loc_offset += LifixDelta( &lifList, walk->loc_offset );
len = FixGenFix( walk, buf, FIX_GEN_PHARLAP );
ObjWrite( out, buf, len );
walk = walk->next;
len_written += len;
}
ObjWEndRec( out );
} while( walk != NULL );
return( 0 );
}
STATIC int writeLedata( obj_rec *objr, pobj_state *state ) {
OBJ_WFILE *out;
uint_16 save;
uint_8 *ptr;
uint_16 len;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_LEDATA );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
LifixDestroy( &lifList );
LifixInit( &lifList );
out = state->file_out;
ObjWBegRec( out, CMD_LEDATA );
ObjWriteIndex( out, objr->d.ledata.idx );
ObjWrite32( out, objr->d.ledata.offset );
save = ObjRTell( objr );
len = ObjRemain( objr );
ptr = ObjGet( objr, len );
/**/myassert( len <= 1024 );
ObjWrite( out, ptr, len );
ObjWEndRec( out );
ObjRSeek( objr, save );
return( 0 );
}
STATIC void id32Block( obj_rec *objr, OBJ_WFILE *out, int_16 *delta,
uint_16 first_block_offset ) {
uint_16 rpt_count;
uint_16 blk_count;
uint_8 data_count;
uint_8 *ptr;
rpt_count = ObjGet32( objr );
if( rpt_count & 0xffff0000 ) {
/* FIXME we could do lots of contortions to remove this fatal msg */
Fatal( MSG_32BIT_RPT_COUNT );
}
ObjWrite16( out, rpt_count );
*delta -= 2; /* ok, everything from here on will be at -2 offset */
LifixAdd( &lifList, ObjRTell( objr ) - first_block_offset, *delta );
blk_count = ObjGet16( objr );
ObjWrite16( out, blk_count );
if( blk_count == 0 ) {
data_count = ObjGet8( objr );
ObjWrite8( out, data_count );
ptr = ObjGet( objr, data_count );
ObjWrite( out, ptr, data_count );
} else {
for( ; blk_count != 0; --blk_count ) {
id32Block( objr, out, delta, first_block_offset );
}
}
}
STATIC int writeLidata( obj_rec *objr, pobj_state *state ) {
OBJ_WFILE *out;
uint_16 save;
uint_8 *ptr;
uint_16 len;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_LIDATA );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
LifixDestroy( &lifList );
LifixInit( &lifList );
out = state->file_out;
save = ObjRTell( objr );
ObjWBegRec( out, CMD_LIDATA );
ObjWriteIndex( out, objr->d.lidata.idx );
ObjWrite32( out, objr->d.lidata.offset );
if( objr->is_phar || !objr->is_32 ) {
/* ok, already in our format */
len = ObjRemain( objr );
ptr = ObjGet( objr, len );
ObjWrite( out, ptr, len );
} else {
int_16 delta;
uint_16 first_block_offset;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?