formasm.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 889 行 · 第 1/2 页
C
889 行
}
HandleAReference(*((long *)data), 0, RFLAG_DEFAULT | RFLAG_IS_IMMED, r_entry->offset,
r_entry->offset + rv, &r_entry, buff );
BufferConcat( buff );
break;
case 4:
if( asmLabels ) {
BufferConcat( types[rv] );
}
HandleAReference(*((long *)data), 0, RFLAG_DEFAULT | RFLAG_IS_IMMED, r_entry->offset,
r_entry->offset + rv, &r_entry, buff );
BufferConcat( buff );
break;
case 2:
if( asmLabels ) {
BufferConcat( types[rv] );
}
HandleAReference(*((short*)data), 0, RFLAG_DEFAULT | RFLAG_IS_IMMED, r_entry->offset,
r_entry->offset + rv, &r_entry, buff );
BufferConcat( buff );
break;
case 1:
if( asmLabels ) {
BufferConcat( types[rv] );
}
HandleAReference(*((char *)data), 0, RFLAG_DEFAULT | RFLAG_IS_IMMED, r_entry->offset,
r_entry->offset + rv, &r_entry, buff );
BufferConcat( buff );
break;
case 8:
if( asmLabels ) {
BufferConcat( types[rv] );
}
HandleAReference( 0, 0, RFLAG_DEFAULT | RFLAG_IS_IMMED, r_entry->offset,
r_entry->offset + rv, &r_entry, buff );
BufferConcat( buff );
if( *((long *)data)!=0 || *((long *)data+4)!=0 ) {
BufferConcat("+");
if( *((long *)data+4)!=0 ) {
BufferStore("0x%x", *((long *)data+4) );
BufferStore("%08x", *((long *)data) );
} else {
BufferStore("0x%x", *((long *)data) );
}
}
break;
}
return( rv );
}
static void printOut( char *string, orl_sec_offset offset, orl_sec_size size)
{
char * string_left = string;
orl_sec_offset curr_pos = 0;
int ascii;
ascii = !IsMasmOutput();
while( 1 ) {
if( string_left < ( string + size ) ) {
if( ascii && printableString( string_left ) &&
strlen( string_left ) > 0 ) {
if( strlen( string_left ) < ( size - curr_pos ) ) {
BufferConcat( " .asciiz\t" );
curr_pos = printString( string_left, ASCIZ );
} else {
BufferConcat( " .ascii\t" );
curr_pos = printString( string_left, ASCII );
}
string_left += curr_pos;
} else {
printRest( string_left, size - (int)( string_left - string ) );
break;
}
} else {
break;
}
BufferConcatNL();
BufferPrint();
}
}
static label_entry dumpAsmLabel( label_entry l_entry, section_ptr sec,
orl_sec_offset curr_pos, orl_sec_offset end,
char *contents, char *buffer )
{
int raw;
int is_masm;
raw = buffer && contents;
is_masm = IsMasmOutput();
while( l_entry != NULL
&& ( l_entry->type == LTYP_ABSOLUTE || l_entry->offset <= curr_pos ) ) {
switch( l_entry->type ) {
case( LTYP_ABSOLUTE ):
// no print any absolute label here
break;
case( LTYP_SECTION ):
if( is_masm )
break;
/* fall through */
case( LTYP_NAMED ):
if( strcmp( l_entry->label.name, sec->name ) == 0 )
break;
/* fall through */
case( LTYP_UNNAMED ):
if( raw ) {
strncpy( buffer, (contents + curr_pos), sizeof( unsigned_32 ) );
}
if( l_entry->type == LTYP_UNNAMED ) {
if( !(DFormat & DFF_ASM) ) {
BufferStore( "\t %04X\t%c$%d:", LabelChar, curr_pos,
l_entry->label.number );
if( raw ) {
printRawAndAddress( buffer, curr_pos );
}
} else {
if( l_entry->offset != curr_pos ) {
BufferStore( "%c$%d equ $-%d", LabelChar, l_entry->label.number, curr_pos - l_entry->offset );
} else {
BufferStore( "%c$%d:", LabelChar, l_entry->label.number );
}
}
} else {
if( !(DFormat & DFF_ASM) ) {
BufferStore( "\t %04X\t%s:", curr_pos,
l_entry->label.name );
if( raw ) {
printRawAndAddress( buffer, curr_pos );
}
} else {
if( l_entry->offset != curr_pos ) {
BufferStore( "%s equ $-%d", l_entry->label.name, curr_pos - l_entry->offset );
} else {
BufferStore( "%s:", l_entry->label.name );
}
}
}
BufferConcatNL();
BufferPrint();
}
l_entry = l_entry->next;
}
return( l_entry );
}
return_val DumpASMDataFromSection( char *contents, orl_sec_offset start,
orl_sec_offset end, label_entry *labent,
ref_entry *refent, section_ptr sec )
{
orl_sec_offset curr_pos;
orl_sec_size curr_size;
orl_sec_size tmp_size;
orl_sec_size size;
label_entry l_entry;
ref_entry r_entry;
char * buffer;
l_entry = *labent;
r_entry = *refent;
size = end - start;
if( size < sizeof( unsigned_32 ) ) size = sizeof( unsigned_32 );
buffer = MemAlloc( size + 1 );
if( !buffer ) {
PrintErrorMsg( OUT_OF_MEMORY, WHERE_PRINT_SECTION );
return( OUT_OF_MEMORY );
}
for( curr_pos = start; curr_pos < end; curr_pos += curr_size ) {
/* dump labels
*/
l_entry = dumpAsmLabel( l_entry, sec, curr_pos, end, contents, buffer );
curr_size = end - curr_pos;
if( l_entry != NULL ) {
tmp_size = l_entry->offset - curr_pos;
if( tmp_size < curr_size ) {
curr_size = tmp_size;
}
}
/* Skip over pair relocs */
while( r_entry != NULL
&& (r_entry->type == ORL_RELOC_TYPE_PAIR || r_entry->offset < curr_pos) ) {
r_entry = r_entry->next;
}
if( r_entry != NULL && r_entry->offset < (curr_pos + curr_size) ) {
if( r_entry->offset == curr_pos ) {
BufferConcat(" ");
curr_size = HandleRefInData(r_entry, contents + curr_pos, TRUE);
BufferConcatNL();
BufferPrint();
continue;
} else {
tmp_size = r_entry->offset - curr_pos;
if( tmp_size < curr_size ) {
curr_size = tmp_size;
}
}
}
memcpy( buffer, (contents + curr_pos), curr_size );
buffer[ curr_size ] = 0;
printOut( buffer, curr_pos, curr_size );
}
*labent = l_entry;
*refent = r_entry;
MemFree( buffer );
return( OKAY );
}
return_val DumpASMSection( section_ptr sec, char * contents,
orl_sec_size size, unsigned pass )
{
hash_data * data_ptr;
label_list sec_label_list;
label_entry l_entry;
ref_list sec_ref_list;
ref_entry r_entry;
return_val err;
data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd );
if( data_ptr ) {
sec_label_list = (label_list) *data_ptr;
l_entry = sec_label_list->first;
} else {
sec_label_list = NULL;
l_entry = NULL;
}
data_ptr = HashTableQuery( HandleToRefListTable, (hash_value) sec->shnd );
if( data_ptr ) {
sec_ref_list = (ref_list) *data_ptr;
if( sec_ref_list != NULL ) {
r_entry = sec_ref_list->first;
}
} else {
r_entry = NULL;
}
if( pass == 1 ) {
DoPass1Relocs( contents, r_entry, 0, size );
return( OKAY );
}
if( size == 0 ) {
if( IsMasmOutput() ) {
PrintHeader( sec );
dumpAsmLabel( l_entry, sec, 0, 0, NULL, NULL );
PrintTail( sec );
}
return( OKAY );
}
PrintHeader( sec );
err = DumpASMDataFromSection( contents, 0, size, &l_entry, &r_entry, sec );
if( size > 0 ) {
l_entry = dumpAsmLabel( l_entry, sec, size, size, NULL, NULL );
}
BufferConcatNL();
BufferPrint();
if( err == OKAY ) {
PrintTail( sec );
}
return( err );
}
static return_val bssUnixASMSection( section_ptr sec, orl_sec_size size,
label_entry l_entry )
{
orl_sec_offset dsiz = 0;
char *prefix;
label_entry prev_entry;
if( ( size == 0 ) && ( l_entry == NULL ) )
return( OKAY );
PrintHeader( sec );
prev_entry = NULL;
for( ; l_entry != NULL; l_entry = l_entry->next ) {
if( ( l_entry->type == LTYP_SECTION )
&& ( strcmp( l_entry->label.name, sec->name ) == 0 ) ) {
continue;
} else if( prev_entry == NULL ) {
prev_entry = l_entry;
continue;
} else if( prev_entry->offset > l_entry->offset ) {
continue;
} else if( prev_entry->offset == l_entry->offset ) {
dsiz = 0;
prefix = "";
} else {
dsiz = l_entry->offset - prev_entry->offset;
prefix = " .lcomm\t";
}
switch( prev_entry->type ) {
case LTYP_UNNAMED:
BufferStore( "%s%c$%d", prefix, LabelChar,
prev_entry->label.number );
break;
case LTYP_SECTION:
case LTYP_NAMED:
BufferStore( "%s%s", prefix, prev_entry->label.name );
break;
default:
break;
}
if( dsiz ) {
BufferStore( ", 0x%08x", dsiz );
} else {
BufferConcat( ":" );
}
BufferConcatNL();
BufferPrint();
prev_entry = l_entry;
}
if( prev_entry != NULL ) {
if( prev_entry->offset < size ) {
dsiz = size - prev_entry->offset;
prefix = " .lcomm\t";
} else {
dsiz = 0;
prefix = "";
}
switch( prev_entry->type ) {
case LTYP_UNNAMED:
BufferStore( "%s%c$%d", prefix, LabelChar,
prev_entry->label.number );
break;
case LTYP_SECTION:
case LTYP_NAMED:
BufferStore( "%s%s", prefix, prev_entry->label.name );
break;
default:
break;
}
if( dsiz ) {
BufferStore( ", 0x%08x", dsiz );
} else {
BufferConcat( ":" );
}
BufferConcatNL();
BufferPrint();
}
BufferConcatNL();
BufferPrint();
return( OKAY );
}
static return_val bssMasmASMSection( section_ptr sec, orl_sec_size size,
label_entry l_entry )
{
int offset = -1;
PrintHeader( sec );
for( ; l_entry != NULL; l_entry = l_entry->next ) {
if( l_entry->type != LTYP_SECTION ) {
if( offset != l_entry->offset ) {
BufferStore( " ORG " );
BufferHex( 8, l_entry->offset );
offset = l_entry->offset;
BufferConcatNL();
BufferPrint();
}
switch( l_entry->type ) {
case LTYP_UNNAMED:
BufferStore("%c$%d", LabelChar, l_entry->label.number );
break;
case LTYP_SECTION:
case LTYP_NAMED:
BufferStore("%s", l_entry->label.name );
break;
}
BufferConcat( " LABEL\tBYTE" );
BufferConcatNL();
BufferPrint();
}
}
if( offset == -1 ) {
if( size > 0 ) {
BufferStore( " ORG 0" );
BufferConcatNL();
BufferPrint();
}
offset = 0;
}
if( size > offset ) {
BufferStore( " ORG " );
BufferHex( 8, size );
BufferConcatNL();
BufferPrint();
}
PrintTail( sec );
BufferConcatNL();
BufferPrint();
return( OKAY );
}
return_val BssASMSection( section_ptr sec, orl_sec_size size, unsigned pass )
{
hash_data * data_ptr;
label_list sec_label_list;
if( pass == 1 ) {
return OKAY;
}
/* Obtain the Symbol Table */
data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd );
if( !data_ptr ) {
return OKAY;
}
sec_label_list = (label_list) *data_ptr;
if( IsMasmOutput() ) {
return( bssMasmASMSection( sec, size, sec_label_list->first ) );
} else {
return( bssUnixASMSection( sec, size, sec_label_list->first ) );
}
}
int SkipRef( ref_entry r_entry )
{
if( SkipRefTable && ( r_entry->label->type == LTYP_EXTERNAL_NAMED ) ) {
if( HashTableQuery( SkipRefTable,
(hash_value)(r_entry->label->label.name) ) ) {
return( 1 );
}
}
return( 0 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?