asmsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 707 行 · 第 1/2 页
C
707 行
if( fixup == NULL )
break;
FixupHead = fixup->next;
AsmFree( fixup );
}
#endif
}
#if defined( _STANDALONE_ )
static int compare_fn( const void *p1, const void *p2 )
/*****************************************************/
{
struct asm_sym * const *sym1 = p1;
struct asm_sym * const *sym2 = p2;
return( strcmp( (*sym1)->name, (*sym2)->name ) );
}
static struct asm_sym **SortAsmSyms( void )
/*****************************************/
{
struct asm_sym **syms;
struct asm_sym *sym;
unsigned i, j;
syms = AsmAlloc( AsmSymCount * sizeof( struct asm_sym * ) );
if( syms ) {
/* copy symbols to table */
for( i = j = 0; i < HASH_TABLE_SIZE; i++ ) {
struct asm_sym *next;
next = sym_table[i];
for( ;; ) {
sym = next;
if( sym == NULL )
break;
next = sym->next;
syms[j++] = sym;
}
}
/* sort 'em */
qsort( syms, AsmSymCount, sizeof( struct asm_sym * ), compare_fn );
}
return( syms );
}
const char *get_seg_align( seg_info *seg )
/****************************************/
{
switch( seg->segrec->d.segdef.align ) {
case ALIGN_ABS:
case ALIGN_BYTE:
return( "Byte " );
case ALIGN_WORD:
return( "Word " );
case ALIGN_DWORD:
return( "DWord" );
case ALIGN_PARA:
return( "Para " );
case ALIGN_PAGE:
return( "Page " );
case ALIGN_4KPAGE:
return( "4K " );
default:
return( "? " );
}
}
static const char *get_seg_combine( seg_info *seg )
/*************************************************/
{
switch( seg->segrec->d.segdef.combine ) {
case COMB_INVALID:
return( "Private " );
case COMB_STACK:
return( "Stack " );
case COMB_ADDOFF:
return( "Public " );
default:
return( "? " );
}
}
static void log_segment( struct asm_sym *sym )
/********************************************/
{
if( sym->state == SYM_SEG ) {
dir_node *dir = (dir_node *)sym;
seg_info *seg = dir->e.seginfo;
LstMsg( "%s %s ", sym->name, dots + strlen( sym->name ) + 1 );
if( seg->segrec->d.segdef.use_32 ) {
LstMsg( "32 Bit %08lX ", seg->current_loc );
} else {
LstMsg( "16 Bit %04lX ", seg->current_loc );
}
LstMsg( "%s %s", get_seg_align( seg ), get_seg_combine( seg ) );
LstMsg( "'%s'\n", GetLname( seg->segrec->d.segdef.class_name_idx ) );
} else if( sym->state == SYM_GRP ) {
LstMsg( "%s %s ", sym->name, dots + strlen( sym->name ) + 1 );
LstMsg( "GROUP\n" );
}
}
static const char *get_sym_type( struct asm_sym *sym )
/****************************************************/
{
switch( sym->mem_type ) {
case MT_BYTE:
return( "Byte " );
case MT_WORD:
return( "Word " );
case MT_DWORD:
return( "DWord " );
case MT_QWORD:
return( "QWord " );
case MT_FWORD:
return( "FWord " );
case MT_NEAR:
return( "L Near " );
case MT_FAR:
return( "L Far " );
default:
return( "? " );
}
}
static void log_symbol( struct asm_sym *sym )
/*******************************************/
{
if( sym->state == SYM_CONST ) {
dir_node *dir = (dir_node *)sym;
const_info *cst = dir->e.constinfo;
LstMsg( "%s %s ", sym->name, dots + strlen( sym->name ) + 1 );
if( cst->count && cst->data[0].token != T_NUM ) {
LstMsg( "Text %s\n", cst->data[0].string_ptr );
} else {
LstMsg( "Number %04Xh\n", cst->count ? cst->data[0].value : 0 );
}
} else if( sym->state == SYM_INTERNAL && !IS_SYM_COUNTER( sym->name ) ) {
LstMsg( "%s %s ", sym->name, dots + strlen( sym->name ) + 1 );
LstMsg( "%s %04X ", get_sym_type( sym ), sym->offset );
if( sym->segment ) {
LstMsg( "%s", sym->segment->name );
} else {
LstMsg( "No Seg" );
}
if( sym->public ) {
LstMsg( "\tPublic" );
}
LstMsg( "\n" );
} else if( sym->state == SYM_EXTERNAL ) {
LstMsg( "%s %s ", sym->name, dots + strlen( sym->name ) + 1 );
LstMsg( "%s %04X ", get_sym_type( sym ), sym->offset );
LstMsg( "External" );
LstMsg( "\n" );
}
}
void WriteListing( void )
/***********************/
{
struct asm_sym **syms;
unsigned i;
if( AsmFiles.file[LST] == NULL ) {
return; // no point going through the motions if lst file isn't open
}
syms = SortAsmSyms();
if( syms ) {
/* first write out the segments */
LstMsg( "\n\nSegments and Groups:\n\n" );
LstMsg( " N a m e Size" );
LstMsg( " Length Align Combine Class\n\n" );
for( i = 0; i < AsmSymCount; ++i ) {
log_segment( syms[i] );
}
LstMsg( "\n" );
/* next write out procedures and stuff */
/* next write out symbols */
LstMsg( "\n\nSymbols:\n\n" );
LstMsg( " N a m e Type" );
LstMsg( " Value Attr\n\n" );
for( i = 0; i < AsmSymCount; ++i ) {
log_symbol( syms[i] );
}
LstMsg( "\n" );
/* free the sorted symbols */
AsmFree( syms );
}
}
#if defined( DEBUG_OUT )
static void DumpSymbol( struct asm_sym *sym )
/*******************************************/
{
dir_node *dir;
char *type;
char value[512];
char *langtype;
char *public;
dir = (dir_node *)sym;
*value = 0;
switch( sym->state ) {
case SYM_SEG:
type = "SEGMENT";
// dir->e.seginfo->lname_idx = 0;
// dir->e.seginfo->grpidx = 0;
// dir->e.seginfo->segrec = NULL;
break;
case SYM_GRP:
type = "GROUP";
// dir->e.grpinfo = AsmAlloc( sizeof( grp_info ) );
// dir->e.grpinfo->idx = grpdefidx;
// dir->e.grpinfo->seglist = NULL;
// dir->e.grpinfo->numseg = 0;
// dir->e.grpinfo->lname_idx = 0;
break;
case SYM_EXTERNAL:
type = "EXTERNAL";
// dir->e.extinfo = AsmAlloc( sizeof( ext_info ) );
// dir->e.extinfo->idx = ++extdefidx;
// dir->e.extinfo->use32 = Use32;
// dir->e.extinfo->comm = 0;
break;
// case TAB_COMM:
// sym->state = SYM_EXTERNAL;
// dir->e.comminfo = AsmAlloc( sizeof( comm_info ) );
// dir->e.comminfo->idx = ++extdefidx;
// dir->e.comminfo->use32 = Use32;
// dir->e.comminfo->comm = 1;
// break;
case SYM_CONST:
type = "CONSTANT";
// dir->e.constinfo = AsmAlloc( sizeof( const_info ) );
// dir->e.constinfo->data = NULL;
// dir->e.constinfo->count = 0;
break;
case SYM_PROC:
type = "PROCEDURE";
// dir->e.procinfo = AsmAlloc( sizeof( proc_info ) );
// dir->e.procinfo->regslist = NULL;
// dir->e.procinfo->paralist = NULL;
// dir->e.procinfo->locallist = NULL;
break;
case SYM_MACRO:
type = "MACRO";
// dir->e.macroinfo = AsmAlloc( sizeof( macro_info ) );
// dir->e.macroinfo->parmlist = NULL;
// dir->e.macroinfo->data = NULL;
// dir->e.macroinfo->filename = NULL;
break;
case SYM_CLASS_LNAME:
type = "CLASS";
break;
case SYM_LNAME:
type = "LNAME";
// dir->e.lnameinfo = AsmAlloc( sizeof( lname_info ) );
// dir->e.lnameinfo->idx = ++LnamesIdx;
break;
// case TAB_PUB:
// sym->public = TRUE;
// return;
// case TAB_GLOBAL:
// break;
case SYM_STRUCT:
type = "STRUCTURE";
// dir->e.structinfo = AsmAlloc( sizeof( struct_info ) );
// dir->e.structinfo->size = 0;
// dir->e.structinfo->alignment = 0;
// dir->e.structinfo->head = NULL;
// dir->e.structinfo->tail = NULL;
break;
case SYM_STRUCT_FIELD:
type = "STRUCTURE FIELD";
break;
case SYM_LIB:
type = "LIBRARY";
break;
case SYM_UNDEFINED:
type = "UNDEFINED";
break;
case SYM_INTERNAL:
type = "INTERNAL";
break;
default:
type = "UNKNOWN";
break;
}
if( sym->public ) {
public = "PUBLIC ";
} else {
public = "";
}
switch( sym->langtype ) {
case LANG_C:
langtype = "C";
break;
case LANG_BASIC:
langtype = "BASIC";
break;
case LANG_FORTRAN:
langtype = "FORTRAN";
break;
case LANG_PASCAL:
langtype = "PASCAL";
break;
case LANG_WATCOM_C:
langtype = "WATCOM_C";
break;
case LANG_STDCALL:
langtype = "STDCALL";
break;
case LANG_SYSCALL:
langtype = "SYSCALL";
break;
default:
langtype = "";
break;
}
DoDebugMsg( "%-30s\t%s\t%s%s\t%8X\t%s\n", sym->name, type, public, langtype, sym->offset, value );
}
void DumpASym( void )
/*******************/
{
struct asm_sym *sym;
unsigned i;
LstMsg( "\n" );
for( i = 0; i < HASH_TABLE_SIZE; i++ ) {
struct asm_sym *next;
next = sym_table[i];
for( ;; ) {
sym = next;
if( sym == NULL )
break;
next = sym->next;
DumpSymbol( sym );
}
}
}
#endif
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?