pass2.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 652 行 · 第 1/2 页
C
652 行
if( (*r_entry)->no_val == 0 && !( GetMachineType() == ORL_MACHINE_TYPE_AMD64 ) ) {
nvalue -= ins_size;
}
referenceString( *r_entry, sec_size, "", "", "", buff, flags );
break;
case ORL_RELOC_TYPE_TOCREL_14:
nvalue &= ~0x3;
case ORL_RELOC_TYPE_TOCREL_16:
referenceString( *r_entry, sec_size, "[toc]", "[toc]", "@toc",
buff, flags );
break;
case ORL_RELOC_TYPE_TOCVREL_14:
nvalue &= ~0x3;
case ORL_RELOC_TYPE_TOCVREL_16:
referenceString( *r_entry, sec_size, "[tocv]", "[tocv]", "@tocv",
buff, flags );
break;
case ORL_RELOC_TYPE_GOT_16:
referenceString( *r_entry, sec_size, "", "", "@got", buff, flags );
break;
case ORL_RELOC_TYPE_GOT_16_HI:
referenceString( *r_entry, sec_size, "", "", "@got@h", buff, flags );
break;
case ORL_RELOC_TYPE_GOT_16_HA:
referenceString( *r_entry, sec_size, "", "", "@got@ha", buff, flags );
break;
case ORL_RELOC_TYPE_GOT_16_LO:
referenceString( *r_entry, sec_size, "", "", "@got@l", buff, flags );
break;
case ORL_RELOC_TYPE_PLTREL_24:
case ORL_RELOC_TYPE_PLTREL_32:
case ORL_RELOC_TYPE_PLT_32:
referenceString( *r_entry, sec_size, "", "", "@plt", buff, flags );
break;
case ORL_RELOC_TYPE_PLT_16_HI:
referenceString( *r_entry, sec_size, "", "", "@plt@h", buff, flags );
break;
case ORL_RELOC_TYPE_PLT_16_HA:
referenceString( *r_entry, sec_size, "", "", "@plt@ha", buff, flags );
break;
case ORL_RELOC_TYPE_PLT_16_LO:
referenceString( *r_entry, sec_size, "", "", "@plt@l", buff, flags );
break;
default:
continue;
}
// LTYP_UNNAMED labels are always at the correct location
// if( nvalue != 0 && (*r_entry)->label->type != LTYP_UNNAMED ) {
// not so - BBB Oct 28, 1996
if(( (*r_entry)->no_val == 0 ) && ( nvalue != 0 )) {
p = &buff[strlen(buff)];
if( nvalue < 0 ) {
*p++ = '-';
nvalue = -nvalue;
} else {
*p++ = '+';
}
FmtHexNum( p, 0, nvalue );
}
}
return( strlen( buff ) );
}
static void FmtSizedHexNum( char *buff, dis_dec_ins *ins, unsigned op_num )
{
unsigned size;
unsigned len;
unsigned i;
int is_sparc = GetMachineType()==ORL_MACHINE_TYPE_SPARC;
static const unsigned long mask[] = {
0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
};
if( is_sparc ) {
size = 4;
switch( ins->op[op_num].ref_type ) {
case DRT_SPARC_BYTE: size = 1; break;
case DRT_SPARC_HALF: size = 2; break;
case DRT_SPARC_WORD:
case DRT_SPARC_SFLOAT: size = 4; break;
case DRT_SPARC_DWORD:
case DRT_SPARC_DFLOAT: size = 8; break;
default: break;
}
} else {
switch( ins->op[op_num].ref_type ) {
case DRT_X86_BYTE: size = 1; break;
case DRT_X86_WORD: size = 2; break;
case DRT_X86_DWORD:
case DRT_X86_DWORDF: size = 4; break;
default: size = 0;
for ( i = 0; i < ins->num_ops; i++ ) {
switch( ins->op[i].ref_type ) {
case DRT_X86_BYTE: len = 1; break;
case DRT_X86_WORD: len = 2; break;
case DRT_X86_DWORD:
case DRT_X86_DWORDF: len = 4; break;
default: len = 0;
}
if ( len > size ) {
size = len;
}
}
if ( size == 0 ) {
size = 4;
}
break;
}
}
FmtHexNum( buff, size * 2, mask[size] & ins->op[op_num].value );
}
unsigned DisCliValueString( void *d, dis_dec_ins *ins, unsigned op_num,
char *buff )
{
struct pass2 *pd = d;
unsigned len;
dis_operand *op;
ref_flags rf;
buff[0] = '\0';
rf = RFLAG_DEFAULT;
op = &ins->op[op_num];
switch( op->type & DO_MASK ) {
case DO_RELATIVE:
case DO_MEMORY_REL:
case DO_ABSOLUTE:
case DO_MEMORY_ABS:
if( pd->r_entry != NULL ) {
/* if there is an override we must avoid the frame
*/
if( ( ins->flags & DIS_X86_SEG_OR ) && IsIntelx86() ) {
rf |= RFLAG_NO_FRAME;
}
len = HandleAReference( op->value, ins->size, rf,
pd->loop + op->op_position, pd->size, &pd->r_entry,
buff );
if( len != 0 ) return( len );
}
switch( op->type & DO_MASK ) {
case DO_RELATIVE:
case DO_MEMORY_REL:
op->value += pd->loop;
break;
}
if( op->base == DR_NONE && op->index == DR_NONE ) {
FmtSizedHexNum( buff, ins, op_num );
} else if( op->value > 0 ) {
FmtHexNum( buff, 0, op->value );
} else if( op->value < 0 ) {
buff[0] = '-';
FmtHexNum( &buff[1], 0, -op->value );
}
break;
case DO_IMMED:
if( pd->r_entry != NULL ) {
rf |= RFLAG_IS_IMMED;
len = HandleAReference( op->value, ins->size, rf,
pd->loop + op->op_position, pd->size, &pd->r_entry,
buff );
if( len != 0 ) return( len );
}
FmtSizedHexNum( buff, ins, op_num );
break;
}
return( strlen( buff ) );
}
static void processDataInCode( section_ptr sec, char *contents, struct pass2 *data,
orl_sec_size size, label_entry *l_entry )
{
orl_sec_size offset;
offset = data->loop + size;
if( DFormat & DFF_ASM ) {
DumpASMDataFromSection( contents, data->loop, offset, l_entry,
&(data->r_entry), sec );
BufferPrint();
} else {
DumpDataFromSection( contents, data->loop, offset, l_entry,
&(data->r_entry), sec );
}
while( data->r_entry && ( data->r_entry->offset < offset ) ) {
data->r_entry = data->r_entry->next;
}
data->loop = offset;
}
num_errors DoPass2( section_ptr sec, char *contents, orl_sec_size size,
label_list sec_label_list, ref_list sec_ref_list )
// perform pass 2 on one section
{
struct pass2 data;
label_entry l_entry;
dis_dec_ins decoded;
char name[ MAX_INS_NAME ];
char ops[ MAX_OBJ_NAME + 24 ]; // at most 1 label/relocation per instruction, plus room for registers, brackets and other crap
unsigned flags;
scantab_ptr st;
int is_intel;
routineBase = 0;
st = sec->scan;
data.size = size;
if( sec_label_list != NULL ) {
l_entry = sec_label_list->first;
}
if( sec_ref_list != NULL ) {
data.r_entry = sec_ref_list->first;
} else {
data.r_entry = NULL;
}
data.disassembly_errors = 0;
if( source_mix ) {
GetSourceFile( sec );
}
PrintHeader( sec );
if( size && sec_label_list )
PrintAssumeHeader( sec );
flags = 0;
if( GetMachineType() == ORL_MACHINE_TYPE_I386 ) {
if( ( GetFormat() != ORL_OMF ) ||
( ORLSecGetFlags( sec->shnd ) & ORL_SEC_FLAG_USE_32 ) ) {
flags = DIF_X86_USE32_FLAGS;
}
is_intel = 1;
} else {
is_intel = IsIntelx86();
}
for( data.loop = 0; data.loop < size; data.loop += decoded.size ) {
// process data in code segment
while( st && ( data.loop > st->end ) ) {
st = st->next;
}
if( st && ( data.loop >= st->start ) ) {
decoded.size = 0;
processDataInCode( sec, contents, &data, st->end - data.loop, &l_entry );
st = st->next;
continue;
}
// data may not be listed in scan table, but a fixup at this offset will
// give it away
while( data.r_entry &&
( (data.r_entry->offset < data.loop) || SkipRef(data.r_entry)) ) {
data.r_entry = data.r_entry->next;
}
if( data.r_entry && ( data.r_entry->offset == data.loop ) ) {
if( is_intel || IsDataReloc( data.r_entry ) ) {
// we just skip the data
decoded.size = 0;
processDataInCode( sec, contents, &data, RelocSize( data.r_entry ),
&l_entry );
continue;
}
}
if( source_mix ) {
MixSource( data.loop );
}
DisDecodeInit( &DHnd, &decoded );
decoded.flags |= flags;
DisDecode( &DHnd, &contents[data.loop], &decoded );
if( sec_label_list ) {
l_entry = handleLabels( sec->name, data.loop, data.loop + decoded.size, l_entry, size );
if( ( l_entry != NULL )
&& ( l_entry->offset > data.loop )
&& ( l_entry->offset < data.loop + decoded.size ) ) {
/*
If we have a label planted in the middle of this
instruction (see inline memchr for example), put
out a couple of data bytes, and then restart decode
and label process from offset of actual label.
*/
decoded.size = 0;
processDataInCode( sec, contents, &data, l_entry->offset - data.loop, &l_entry );
continue;
}
}
DisFormat( &DHnd, &data, &decoded, DFormat, name, ops );
if( !(DFormat & DFF_ASM) ) {
static unsigned_64 *tmp_64;
static unsigned_32 *tmp_32;
static unsigned_16 *tmp_16;
tmp_64 = (unsigned_64 *)(contents+data.loop);
tmp_32 = (unsigned_32 *)(contents+data.loop);
tmp_16 = (unsigned_16 *)(contents+data.loop);
if( DHnd.need_bswap ) {
switch( DisInsSizeInc( &DHnd ) ) {
//case 8: SWAP_64(*tmp_64); break;
case 4: SWAP_32(*tmp_32); break;
case 2: SWAP_16(*tmp_16); break;
default: break;
}
}
PrintLinePrefix( contents, data.loop, size,
DisInsSizeInc( &DHnd ), decoded.size );
}
BufferStore( " %*s %s", -DisInsNameMax( &DHnd ), name, ops );
BufferStore("\n");
BufferPrint();
}
if( sec_label_list ) {
l_entry = handleLabels( sec->name, size, -1, l_entry, size );
}
if( !(DFormat & DFF_ASM) ) {
routineSize = data.loop - routineBase;
BufferConcatNL();
BufferMsg( ROUTINE_SIZE );
BufferStore(" %d ", routineSize );
BufferMsg( BYTES );
BufferConcat(", ");
BufferMsg( ROUTINE_BASE );
BufferStore(" %s + %04X\n\n", sec->name, routineBase );
BufferPrint();
}
if( source_mix ) {
EndSourceMix();
}
PrintTail( sec );
return( data.disassembly_errors );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?