write.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,166 行 · 第 1/3 页
C
1,166 行
ObjPutIndex( rec, seg_index );
write_record( rec, TRUE );
}
}
}
static void write_lnames( void )
/******************************/
{
obj_rec *objr;
uint total_size = 0;
char *lname = NULL;
objr = ObjNewRec( CMD_LNAMES );
objr->d.lnames.first_idx = 1;
objr->d.lnames.num_names = LnamesIdx;
total_size = GetLnameData( &lname );
if( total_size > 0 ) {
ObjAttachData( objr, lname, total_size );
}
ObjCanFree( objr );
write_record( objr, TRUE );
}
static void write_global( void )
/******************************/
/* turn the globals into either externs or publics as appropriate */
{
GetGlobalData();
}
static dir_node *write_extdef( dir_node *start )
/**********************************************/
{
obj_rec *objr;
dir_node *curr;
uint num;
uint total_size;
uint i;
char name[MAX_EXT_LENGTH];
char buffer[MAX_LINE_LEN];
uint len;
num = 0;
total_size = 0;
i = 0;
objr = ObjNewRec( CMD_EXTDEF );
objr->d.extdef.first_idx = 0;
for( curr = start;
( curr != NULL ) && ( curr->e.extinfo->comm == start->e.extinfo->comm );
curr = curr->next ) {
Mangle( &curr->sym, buffer );
len = strlen( buffer );
if( total_size + len >= MAX_EXT_LENGTH )
break;
total_size += len + 2;
num++;
name[i] = (char)len;
i++;
memcpy( name+i, buffer, len );
i += len;
name[i++] = 0; // for the type index
}
ObjAttachData( objr, name, total_size );
if( num != 0 ) {
objr->d.extdef.num_names = num;
write_record( objr, TRUE );
} else {
ObjKillRec( objr );
}
return( curr );
}
static int opsize( memtype mem_type )
/************************************/
{
switch( mem_type ) {
case MT_EMPTY: return( 0 );
case MT_SBYTE:
case MT_BYTE: return( 1 );
case MT_SWORD:
case MT_WORD: return( 2 );
case MT_SDWORD:
case MT_DWORD: return( 4 );
case MT_FWORD: return( 6 );
case MT_QWORD: return( 8 );
case MT_TBYTE: return( 10 );
case MT_OWORD: return( 16 );
default: return( 0 );
}
}
#define THREE_BYTE_MAX ( (1UL << 24) - 1 )
static int get_number_of_bytes_for_size_in_commdef( unsigned long value )
/****************************************************************/
{
/* The spec allows up to 128 in a one byte size field, but lots
of software has problems with that, so we'll restrict ourselves
to 127.
*/
if( value < 128 ) {
return( 1 ); /* 1 byte value */
} else if( value <= USHRT_MAX ) {
return( 3 ); /* 1 byte flag + 2 byte value */
} else if( value <= THREE_BYTE_MAX ) {
return( 4 ); /* 1 byte flag + 3 byte value */
} else { // if( value <= ULONG_MAX )
return( 5 ); /* 1 byte flag + 4 byte value */
}
}
static dir_node *write_comdef( dir_node *start )
/**********************************************/
{
obj_rec *objr;
dir_node *curr;
uint num = 0;
uint total_size = 0;
uint varsize = 0;
uint symsize;
uint i = 0;
uint j = 0;
char *name;
uint len;
unsigned long value;
char buffer[MAX_LINE_LEN];
char *ptr;
objr = ObjNewRec( CMD_COMDEF );
objr->d.comdef.first_idx = 0;
for( curr = start;
( curr != NULL ) && ( curr->e.extinfo->comm == start->e.extinfo->comm );
curr = curr->next ) {
ptr = Mangle( &curr->sym, buffer );
total_size += 3 + strlen( ptr );
/* 3 = 1 for string len + 1 for type index + 1 for data type */
varsize = opsize( curr->sym.mem_type );
if( curr->e.comminfo->distance == T_FAR ) {
total_size += get_number_of_bytes_for_size_in_commdef( varsize );
total_size += get_number_of_bytes_for_size_in_commdef( curr->e.comminfo->size );
} else {
total_size += get_number_of_bytes_for_size_in_commdef( curr->e.comminfo->size );
}
num++;
}
if( total_size > 0 ) {
name = AsmAlloc( total_size * sizeof( char ) );
for( curr = start;
( curr != NULL ) && ( curr->e.extinfo->comm == start->e.extinfo->comm );
curr = curr->next ) {
ptr = Mangle( &curr->sym, buffer );
len = strlen( ptr );
name[i] = (char)len;
i++;
memcpy( name+i, ptr, len );
i += len;
name[i++] = 0; // for the type index
/* now add the data type & communal length */
if( curr->e.comminfo->distance == T_FAR ) {
name[i++] = COMDEF_FAR;
} else {
name[i++] = COMDEF_NEAR;
}
value = curr->e.comminfo->size;
varsize = get_number_of_bytes_for_size_in_commdef( value );
switch( varsize ) {
case 1:
break;
case 3:
name[i++] = COMDEF_LEAF_2;
break;
case 4:
name[i++] = COMDEF_LEAF_3;
break;
case 5:
name[i++] = COMDEF_LEAF_4;
break;
}
if( varsize > 1 )
varsize--; /* we already output 1 byte */
symsize = opsize( curr->sym.mem_type );
if( curr->e.comminfo->distance != T_FAR ) {
value *= symsize;
}
for( j=0; j < varsize; j++ ) {
name[i++] = value % ( UCHAR_MAX + 1 );
value >>= 8;
}
if( curr->e.comminfo->distance == T_FAR ) {
/* mem type always needs <= 1 byte */
myassert( symsize < UCHAR_MAX );
name[i++] = symsize;
}
}
ObjAttachData( objr, name, total_size );
}
ObjCanFree( objr );
if( num != 0 ) {
objr->d.comdef.num_names = num;
write_record( objr, TRUE );
} else {
ObjKillRec( objr );
}
return( curr );
}
static void write_ext_comm( void )
/********************************/
{
dir_node *next;
for( next = Tables[TAB_EXT].head; next != NULL; ) {
if( next->e.extinfo->comm == 0 ) {
// extdef
next = write_extdef( next );
} else {
// comdef
next = write_comdef( next );
}
}
}
static void write_header( void )
/******************************/
{
obj_rec *objr;
unsigned len;
char *name;
objr = ObjNewRec( CMD_THEADR );
if( Options.module_name != NULL ) {
name = Options.module_name;
} else {
name = ModuleInfo.srcfile->fullname;
}
len = strlen( name );
ObjAllocData( objr, len + 1 );
ObjPutName( objr, name, len );
ObjTruncRec( objr );
write_record( objr, TRUE );
}
static int write_modend( void )
/*****************************/
{
if( ModendRec == NULL ) {
AsmError( UNEXPECTED_END_OF_FILE );
return ERROR;
}
write_record( ModendRec, TRUE );
return NOT_ERROR;
}
static int write_autodep( void )
/******************************/
{
obj_rec *objr;
char buff[2*PATH_MAX + 5];
unsigned int len;
const FNAME *curr;
if( !Options.emit_dependencies )
return NOT_ERROR;
for( curr = FNames; curr != NULL; curr = curr->next ) {
objr = ObjNewRec( CMD_COMENT );
objr->d.coment.attr = 0x80;
objr->d.coment.class = CMT_DEPENDENCY;
len = strlen(curr->name);
*((time_t *)buff) = _timet2dos(curr->mtime);
*(buff + 4) = (unsigned char)len;
strcpy(buff + 5, curr->name);
len += 5;
ObjAttachData( objr, buff, len );
write_record( objr, TRUE );
}
// one NULL dependency record must be on the end
objr = ObjNewRec( CMD_COMENT );
objr->d.coment.attr = 0x80;
objr->d.coment.class = CMT_DEPENDENCY;
ObjAttachData( objr, "", 0 );
write_record( objr, TRUE );
return NOT_ERROR;
}
void AddLinnumDataRef( void )
/***************************/
/* store a reference for the current line at the current address */
{
struct line_num_info *curr;
unsigned long line_num;
if( in_prologue ) {
line_num = CurrProc->line_num;
} else {
line_num = LineNumber;
}
if( line_num < 0x8000 ) {
if( lastLineNumber != line_num ) {
curr = AsmAlloc( sizeof( struct line_num_info ) );
curr->number = line_num;
curr->offset = AsmCodeAddress;
curr->srcfile = get_curr_srcfile();
AddLinnumData( curr );
lastLineNumber = line_num;
}
}
}
static void write_linnum( void )
/******************************/
{
struct linnum_data *ldata;
int count;
obj_rec *objr;
bool need_32;
count = GetLinnumData( &ldata, &need_32 );
if( count == 0 )
return;
if( ldata == NULL ) {
AsmError( NO_MEMORY );
} else {
objr = ObjNewRec( CMD_LINNUM );
objr->is_32 = need_32;
objr->d.linnum.num_lines = count;
objr->d.linnum.lines = ldata;
objr->d.linnum.d.base.grp_idx = GetGrpIdx( GetGrp( &GetCurrSeg()->sym ) ); // fixme ?
objr->d.linnum.d.base.seg_idx = CurrSeg->seg->e.seginfo->segrec->d.segdef.idx;
objr->d.linnum.d.base.frame = 0; // fixme ?
write_record( objr, TRUE );
}
}
#ifdef SEPARATE_FIXUPP_16_32
static void divide_fixup_list( struct fixup **fl16, struct fixup **fl32 ) {
/**********************************************/
/* divide fixup record list to the 16-bit or 32-bit list of a fixup record */
struct fixup *fix;
struct fixup *fix16;
struct fixup *fix32;
fix16 = NULL;
fix32 = NULL;
fix = FixupListHead;
for( fix = FixupListHead; fix != NULL; fix = fix->next ) {
switch( fix->loc_method ) {
case FIX_OFFSET386:
case FIX_POINTER386:
if( fix32 == NULL ) {
*fl32 = fix;
} else {
fix32->next = fix;
}
fix32 = fix;
break;
default:
if( fix16 == NULL ) {
*fl16 = fix;
} else {
fix16->next = fix;
}
fix16 = fix;
break;
}
}
if( fix32 != NULL ) {
fix32->next = NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?