@ -123,44 +123,6 @@ static unsigned local_auxesz;
static struct symbol * opaque_type_chain [ HASHSIZE ] ;
/* Record the symbols defined for each context in a list.
We don ' t create a struct block for the context until we
know how long to make it . */
struct coff_pending
{
struct coff_pending * next ;
struct symbol * symbol ;
} ;
/* Here are the three lists that symbols are put on. */
struct coff_pending * coff_file_symbols ; /* static at top level, and types */
struct coff_pending * coff_global_symbols ; /* global functions and variables */
struct coff_pending * coff_local_symbols ; /* everything local to lexical context */
/* List of unclosed lexical contexts
( that will become blocks , eventually ) . */
struct coff_context_stack
{
struct coff_context_stack * next ;
struct coff_pending * locals ;
struct pending_block * old_blocks ;
struct symbol * name ;
CORE_ADDR start_addr ;
int depth ;
} ;
struct coff_context_stack * coff_context_stack ;
/* Nonzero if within a function (so symbols should be local,
if nothing says specifically ) . */
int within_function ;
#if 0
/* The type of the function we are currently reading in. This is
used by define_symbol to record the type of arguments to a function . */
@ -229,9 +191,6 @@ decode_function_type PARAMS ((struct coff_symbol *, unsigned int,
static struct type *
coff_read_enum_type PARAMS ( ( int , int , int ) ) ;
static struct blockvector *
make_blockvector PARAMS ( ( struct objfile * ) ) ;
static struct symbol *
process_coff_symbol PARAMS ( ( struct coff_symbol * , union internal_auxent * ,
struct objfile * ) ) ;
@ -300,14 +259,6 @@ coff_start_symtab PARAMS ((void));
static void
coff_record_line PARAMS ( ( int , CORE_ADDR ) ) ;
static void
coff_finish_block PARAMS ( ( struct symbol * , struct coff_pending * * ,
struct pending_block * , CORE_ADDR , CORE_ADDR ,
struct objfile * ) ) ;
static void
coff_add_symbol_to_list PARAMS ( ( struct symbol * , struct coff_pending * * ) ) ;
static struct type *
coff_alloc_type PARAMS ( ( int ) ) ;
@ -365,142 +316,6 @@ coff_alloc_type (index)
return type ;
}
/* maintain the lists of symbols and blocks */
/* Add a symbol to one of the lists of symbols. */
static void
coff_add_symbol_to_list ( symbol , listhead )
struct symbol * symbol ;
struct coff_pending * * listhead ;
{
register struct coff_pending * link
= ( struct coff_pending * ) xmalloc ( sizeof ( struct coff_pending ) ) ;
link - > next = * listhead ;
link - > symbol = symbol ;
* listhead = link ;
}
/* Take one of the lists of symbols and make a block from it.
Put the block on the list of pending blocks . */
static void
coff_finish_block ( symbol , listhead , old_blocks , start , end , objfile )
struct symbol * symbol ;
struct coff_pending * * listhead ;
struct pending_block * old_blocks ;
CORE_ADDR start , end ;
struct objfile * objfile ;
{
register struct coff_pending * next , * next1 ;
register struct block * block ;
register struct pending_block * pblock ;
struct pending_block * opblock ;
register int i ;
/* Count the length of the list of symbols. */
for ( next = * listhead , i = 0 ; next ; next = next - > next , i + + ) ;
block = ( struct block * )
obstack_alloc ( & objfile - > symbol_obstack , sizeof ( struct block ) + ( i - 1 ) * sizeof ( struct symbol * ) ) ;
/* Copy the symbols into the block. */
BLOCK_NSYMS ( block ) = i ;
for ( next = * listhead ; next ; next = next - > next )
BLOCK_SYM ( block , - - i ) = next - > symbol ;
BLOCK_START ( block ) = start ;
BLOCK_END ( block ) = end ;
BLOCK_SUPERBLOCK ( block ) = 0 ; /* Filled in when containing block is made */
/* Put the block in as the value of the symbol that names it. */
if ( symbol )
{
SYMBOL_BLOCK_VALUE ( symbol ) = block ;
BLOCK_FUNCTION ( block ) = symbol ;
}
else
BLOCK_FUNCTION ( block ) = 0 ;
/* Now free the links of the list, and empty the list. */
for ( next = * listhead ; next ; next = next1 )
{
next1 = next - > next ;
free ( ( PTR ) next ) ;
}
* listhead = 0 ;
/* Install this block as the superblock
of all blocks made since the start of this scope
that don ' t have superblocks yet . */
opblock = 0 ;
for ( pblock = pending_blocks ; pblock ! = old_blocks ; pblock = pblock - > next )
{
if ( BLOCK_SUPERBLOCK ( pblock - > block ) = = 0 )
BLOCK_SUPERBLOCK ( pblock - > block ) = block ;
opblock = pblock ;
}
/* Record this block on the list of all blocks in the file.
Put it after opblock , or at the beginning if opblock is 0.
This puts the block in the list after all its subblocks . */
pblock = ( struct pending_block * ) xmalloc ( sizeof ( struct pending_block ) ) ;
pblock - > block = block ;
if ( opblock )
{
pblock - > next = opblock - > next ;
opblock - > next = pblock ;
}
else
{
pblock - > next = pending_blocks ;
pending_blocks = pblock ;
}
}
static struct blockvector *
make_blockvector ( objfile )
struct objfile * objfile ;
{
register struct pending_block * next , * next1 ;
register struct blockvector * blockvector ;
register int i ;
/* Count the length of the list of blocks. */
for ( next = pending_blocks , i = 0 ; next ; next = next - > next , i + + ) ;
blockvector = ( struct blockvector * )
obstack_alloc ( & objfile - > symbol_obstack , sizeof ( struct blockvector ) + ( i - 1 ) * sizeof ( struct block * ) ) ;
/* Copy the blocks into the blockvector.
This is done in reverse order , which happens to put
the blocks into the proper order ( ascending starting address ) .
coff_finish_block has hair to insert each block into the list
after its subblocks in order to make sure this is true . */
BLOCKVECTOR_NBLOCKS ( blockvector ) = i ;
for ( next = pending_blocks ; next ; next = next - > next )
BLOCKVECTOR_BLOCK ( blockvector , - - i ) = next - > block ;
/* Now free the links of the list, and empty the list. */
for ( next = pending_blocks ; next ; next = next1 )
{
next1 = next - > next ;
free ( ( PTR ) next ) ;
}
pending_blocks = 0 ;
return blockvector ;
}
/* Manage the vector of line numbers. */
static void
@ -531,11 +346,14 @@ coff_record_line (line, pc)
static void
coff_start_symtab ( )
{
coff_file_symbols = 0 ;
coff_global_symbols = 0 ;
coff_context_stack = 0 ;
within_function = 0 ;
last_source_file = NULL ;
start_symtab (
/* We fill in the filename later. */
" " ,
/* We never know the directory name for COFF. */
NULL ,
/* The start address is irrelevant, since we set
last_source_start_addr in coff_end_symtab . */
0 ) ;
/* Initialize the source file line number information for this file. */
@ -581,87 +399,24 @@ static void
coff_end_symtab ( objfile )
struct objfile * objfile ;
{
register struct symtab * symtab ;
register struct coff_context_stack * cstk ;
register struct blockvector * blockvector ;
register struct linetable * lv ;
struct symtab * symtab ;
/* Finish the lexical context of the last function in the file. */
last_source_start_addr = cur_src_start_addr ;
if ( coff_context_stack )
{
cstk = coff_context_stack ;
coff_context_stack = 0 ;
/* Make a block for the local symbols within. */
coff_finish_block ( cstk - > name , & coff_local_symbols , cstk - > old_blocks ,
cstk - > start_addr , cur_src_end_addr , objfile ) ;
free ( ( PTR ) cstk ) ;
}
/* For COFF, we only have one subfile, so we can just look at
subfiles and not worry about there being other elements in the
chain . We fill in various fields now because we didn ' t know them
before ( or because doing it now is simply an artifact of how this
file used to be written ) . */
subfiles - > line_vector = line_vector ;
subfiles - > name = last_source_file ;
/* Ignore a file that has no functions with real debugging info. */
if ( pending_blocks = = 0 & & coff_file_symbols = = 0 & & coff_global_symbols = = 0 )
{
free ( ( PTR ) line_vector ) ;
line_vector = 0 ;
line_vector_length = - 1 ;
last_source_file = NULL ;
return ;
}
/* sort_pending is needed for amdcoff, at least.
sort_linevec is needed for the SCO compiler . */
symtab = end_symtab ( cur_src_end_addr , 1 , 1 , objfile , 0 ) ;
/* It is unfortunate that in amdcoff, pending blocks might not be ordered
in this stage . Especially , blocks for static functions will show up at
the end . We need to sort them , so tools like ` find_pc_function ' and
` find_pc_block ' can work reliably . */
if ( pending_blocks ) {
/* FIXME! Remove this horrid bubble sort and use qsort!!! */
int swapped ;
do {
struct pending_block * pb , * pbnext ;
pb = pending_blocks , pbnext = pb - > next ;
swapped = 0 ;
while ( pbnext ) {
/* swap blocks if unordered! */
if ( BLOCK_START ( pb - > block ) < BLOCK_START ( pbnext - > block ) ) {
struct block * tmp = pb - > block ;
complain ( & misordered_blocks_complaint , BLOCK_START ( pb - > block ) ) ;
pb - > block = pbnext - > block ;
pbnext - > block = tmp ;
swapped = 1 ;
}
pb = pbnext ;
pbnext = pbnext - > next ;
}
} while ( swapped ) ;
}
/* Create the two top-level blocks for this file (STATIC_BLOCK and
GLOBAL_BLOCK ) . */
coff_finish_block ( 0 , & coff_file_symbols , 0 , cur_src_start_addr , cur_src_end_addr , objfile ) ;
coff_finish_block ( 0 , & coff_global_symbols , 0 , cur_src_start_addr , cur_src_end_addr , objfile ) ;
/* Create the blockvector that points to all the file's blocks. */
blockvector = make_blockvector ( objfile ) ;
/* Now create the symtab object for this source file. */
symtab = allocate_symtab ( last_source_file , objfile ) ;
/* Fill in its components. */
symtab - > blockvector = blockvector ;
symtab - > free_code = free_linetable ;
symtab - > free_ptr = 0 ;
symtab - > filename = last_source_file ;
symtab - > dirname = NULL ;
lv = line_vector ;
lv - > nitems = line_vector_index ;
symtab - > linetable = ( struct linetable * )
xrealloc ( ( char * ) lv , ( sizeof ( struct linetable )
+ lv - > nitems * sizeof ( struct linetable_entry ) ) ) ;
free_named_symtabs ( symtab - > filename ) ;
if ( symtab ! = NULL )
free_named_symtabs ( symtab - > filename ) ;
/* Reinitialize for beginning of new file. */
line_vector = 0 ;
@ -888,7 +643,7 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
struct objfile * objfile ;
{
FILE * stream ;
register struct coff_co ntext_stack * new ;
register struct context_stack * new ;
struct coff_symbol coff_symbol ;
register struct coff_symbol * cs = & coff_symbol ;
static struct internal_syment main_sym ;
@ -1098,41 +853,41 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
complain ( & bf_no_aux_complaint , cs - > c_symnum ) ;
fcn_first_line = main_aux . x_sym . x_misc . x_lnsz . x_lnno ;
new = ( struct coff_context_stack * )
xmalloc ( sizeof ( struct coff_context_stack ) ) ;
new - > depth = depth = 0 ;
new - > next = 0 ;
coff_context_stack = new ;
new - > locals = 0 ;
new - > old_blocks = pending_blocks ;
new - > start_addr = fcn_start_addr ;
/* Might want to check that locals are 0 and
context_stack_depth is zero , and complain if not . */
depth = 0 ;
new = push_context ( depth , fcn_start_addr ) ;
fcn_cs_saved . c_name = getsymname ( & fcn_sym_saved ) ;
new - > name = process_coff_symbol ( & fcn_cs_saved ,
& fcn_aux_saved , objfile ) ;
}
else if ( STREQ ( cs - > c_name , " .ef " ) )
{
/* the value of .ef is the address of epilogue code;
* not useful for gdb
*/
/* the value of .ef is the address of epilogue code;
not useful for gdb . */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains number of lines to ' } ' */
new = coff_context_stack ;
if ( new = = 0 )
new = pop_context ( ) ;
/* Stack must be empty now. */
if ( context_stack_depth > 0 | | new = = NULL )
{
complain ( & ef_complaint , cs - > c_symnum ) ;
within_function = 0 ;
break ;
}
if ( cs - > c_naux ! = 1 ) {
complain ( & ef_no_aux_complaint , cs - > c_symnum ) ;
fcn_last_line = 0x7FFFFFFF ;
} else {
fcn_last_line = main_aux . x_sym . x_misc . x_lnsz . x_lnno ;
}
if ( cs - > c_naux ! = 1 )
{
complain ( & ef_no_aux_complaint , cs - > c_symnum ) ;
fcn_last_line = 0x7FFFFFFF ;
}
else
{
fcn_last_line = main_aux . x_sym . x_misc . x_lnsz . x_lnno ;
}
enter_linenos ( fcn_line_ptr , fcn_first_line , fcn_last_line ) ;
coff_finish_block ( new - > name , & coff_local_symbols , new - > old_blocks ,
finish_block ( new - > name , & local_symbols , new - > old_blocks ,
new - > start_addr ,
# if defined (FUNCTION_EPILOGUE_SIZE)
/* This macro should be defined only on
@ -1149,45 +904,31 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
# endif
objfile
) ;
coff_context_stack = 0 ;
within_function = 0 ;
free ( ( PTR ) new ) ;
}
break ;
case C_BLOCK :
if ( STREQ ( cs - > c_name , " .bb " ) )
{
new = ( struct coff_context_stack * )
xmalloc ( sizeof ( struct coff_context_stack ) ) ;
depth + + ;
new - > depth = depth ;
new - > next = coff_context_stack ;
coff_context_stack = new ;
new - > locals = coff_local_symbols ;
new - > old_blocks = pending_blocks ;
new - > start_addr = cs - > c_value ;
new - > name = 0 ;
coff_local_symbols = 0 ;
push_context ( + + depth , cs - > c_value ) ;
}
else if ( STREQ ( cs - > c_name , " .eb " ) )
{
new = coff_context_stack ;
if ( new = = 0 | | depth ! = new - > depth )
new = pop_context ( ) ;
if ( depth - - ! = new - > depth )
{
complain ( & eb_complaint , ( char * ) symnum ) ;
break ;
}
if ( coff_ local_symbols & & coff_context_stack - > next )
if ( local_symbols & & context_stack_depth > 0 )
{
/* Make a block for the local symbols within. */
coff_ finish_block ( 0 , & coff_ local_symbols, new - > old_blocks ,
finish_block ( 0 , & local_symbols , new - > old_blocks ,
new - > start_addr , cs - > c_value , objfile ) ;
}
depth - - ;
coff_local_symbols = new - > locals ;
coff_context_stack = new - > next ;
free ( ( PTR ) new ) ;
/* Now pop locals of block just finished. */
local_symbols = new - > locals ;
}
break ;
@ -1337,9 +1078,6 @@ init_stringtab (chan, offset)
return 0 ;
stringtab = ( char * ) xmalloc ( length ) ;
if ( stringtab = = NULL )
return - 1 ;
memcpy ( stringtab , & length , sizeof length ) ;
if ( length = = sizeof length ) /* Empty table -- just the count */
return 0 ;
@ -1435,9 +1173,6 @@ init_lineno (chan, offset, size)
/* Allocate the desired table, plus a sentinel */
linetab = ( char * ) xmalloc ( size + local_linesz ) ;
if ( linetab = = NULL )
return - 1 ;
val = myread ( chan , linetab , size ) ;
if ( val ! = size )
return - 1 ;
@ -1626,9 +1361,9 @@ process_coff_symbol (cs, aux, objfile)
SYMBOL_CLASS ( sym ) = LOC_BLOCK ;
if ( cs - > c_sclass = = C_STAT )
coff_ add_symbol_to_list ( sym , & coff_ file_symbols) ;
add_symbol_to_list ( sym , & file_symbols ) ;
else if ( cs - > c_sclass = = C_EXT )
coff_ add_symbol_to_list ( sym , & coff_ global_symbols) ;
add_symbol_to_list ( sym , & global_symbols ) ;
}
else
{
@ -1640,13 +1375,13 @@ process_coff_symbol (cs, aux, objfile)
case C_AUTO :
SYMBOL_CLASS ( sym ) = LOC_LOCAL ;
coff_ add_symbol_to_list ( sym , & coff_ local_symbols) ;
add_symbol_to_list ( sym , & local_symbols ) ;
break ;
case C_EXT :
SYMBOL_CLASS ( sym ) = LOC_STATIC ;
SYMBOL_VALUE_ADDRESS ( sym ) = ( CORE_ADDR ) cs - > c_value ;
coff_ add_symbol_to_list ( sym , & coff_ global_symbols) ;
add_symbol_to_list ( sym , & global_symbols ) ;
break ;
case C_STAT :
@ -1654,11 +1389,11 @@ process_coff_symbol (cs, aux, objfile)
SYMBOL_VALUE_ADDRESS ( sym ) = ( CORE_ADDR ) cs - > c_value ;
if ( within_function ) {
/* Static symbol of local scope */
coff_ add_symbol_to_list ( sym , & coff_ local_symbols) ;
add_symbol_to_list ( sym , & local_symbols ) ;
}
else {
/* Static symbol at top level of file */
coff_ add_symbol_to_list ( sym , & coff_ file_symbols) ;
add_symbol_to_list ( sym , & file_symbols ) ;
}
break ;
@ -1668,7 +1403,7 @@ process_coff_symbol (cs, aux, objfile)
case C_REG :
SYMBOL_CLASS ( sym ) = LOC_REGISTER ;
SYMBOL_VALUE ( sym ) = SDB_REG_TO_REGNUM ( cs - > c_value ) ;
coff_ add_symbol_to_list ( sym , & coff_ local_symbols) ;
add_symbol_to_list ( sym , & local_symbols ) ;
break ;
case C_LABEL :
@ -1681,7 +1416,7 @@ process_coff_symbol (cs, aux, objfile)
/* Add parameter to function. */
add_param_to_type ( & in_function_type , sym ) ;
# endif
coff_ add_symbol_to_list ( sym , & coff_ local_symbols) ;
add_symbol_to_list ( sym , & local_symbols ) ;
# if !defined (BELIEVE_PCC_PROMOTION) && (TARGET_BYTE_ORDER == BIG_ENDIAN)
/* If PCC says a parameter is a short or a char,
aligned on an int boundary , realign it to the " little end "
@ -1700,7 +1435,7 @@ process_coff_symbol (cs, aux, objfile)
case C_REGPARM :
SYMBOL_CLASS ( sym ) = LOC_REGPARM ;
SYMBOL_VALUE ( sym ) = SDB_REG_TO_REGNUM ( cs - > c_value ) ;
coff_ add_symbol_to_list ( sym , & coff_ local_symbols) ;
add_symbol_to_list ( sym , & local_symbols ) ;
# if !defined (BELIEVE_PCC_PROMOTION)
/* FIXME: This should retain the current type, since it's just
a register value . gnu @ adobe , 26F eb93 */
@ -1741,7 +1476,7 @@ process_coff_symbol (cs, aux, objfile)
SYMBOL_VALUE_CHAIN ( sym ) = opaque_type_chain [ i ] ;
opaque_type_chain [ i ] = sym ;
}
coff_ add_symbol_to_list ( sym , & coff_ file_symbols) ;
add_symbol_to_list ( sym , & file_symbols ) ;
break ;
case C_STRTAG :
@ -1760,7 +1495,7 @@ process_coff_symbol (cs, aux, objfile)
TYPE_TAG_NAME ( SYMBOL_TYPE ( sym ) ) =
concat ( SYMBOL_NAME ( sym ) , NULL ) ;
coff_ add_symbol_to_list ( sym , & coff_ file_symbols) ;
add_symbol_to_list ( sym , & file_symbols ) ;
break ;
default :
@ -2114,21 +1849,23 @@ coff_read_enum_type (index, length, lastsym)
register struct type * type ;
int nsyms = 0 ;
int done = 0 ;
struct coff_ pending * * symlist ;
struct pending * * symlist ;
struct coff_symbol member_sym ;
register struct coff_symbol * ms = & member_sym ;
struct internal_syment sub_sym ;
union internal_auxent sub_aux ;
struct coff_pending * osyms , * syms ;
struct pending * osyms , * syms ;
int o_nsyms ;
register int n ;
char * name ;
type = coff_alloc_type ( index ) ;
if ( within_function )
symlist = & coff_ local_symbols;
symlist = & local_symbols ;
else
symlist = & coff_ file_symbols;
symlist = & file_symbols ;
osyms = * symlist ;
o_nsyms = osyms ? osyms - > nsyms : 0 ;
while ( ! done & & symnum < lastsym & & symnum < nlist_nsyms_global )
{
@ -2146,7 +1883,7 @@ coff_read_enum_type (index, length, lastsym)
SYMBOL_CLASS ( sym ) = LOC_CONST ;
SYMBOL_NAMESPACE ( sym ) = VAR_NAMESPACE ;
SYMBOL_VALUE ( sym ) = ms - > c_value ;
coff_ add_symbol_to_list ( sym , symlist ) ;
add_symbol_to_list ( sym , symlist ) ;
nsyms + + ;
break ;
@ -2174,15 +1911,28 @@ coff_read_enum_type (index, length, lastsym)
The symbols can be found in the symlist that we put them on
to cause them to be defined . osyms contains the old value
of that symlist ; everything up to there was defined by us . */
/* Note that we preserve the order of the enum constants, so
that in something like " enum {FOO, LAST_THING=FOO} " we print
FOO , not LAST_THING . */
for ( syms = * symlist , n = nsyms ; syms ! = osyms ; syms = syms - > next )
for ( syms = * symlist , n = 0 ; syms ; syms = syms - > next )
{
SYMBOL_TYPE ( syms - > symbol ) = type ;
TYPE_FIELD_NAME ( type , - - n ) = SYMBOL_NAME ( syms - > symbol ) ;
TYPE_FIELD_VALUE ( type , n ) = 0 ;
TYPE_FIELD_BITPOS ( type , n ) = SYMBOL_VALUE ( syms - > symbol ) ;
TYPE_FIELD_BITSIZE ( type , n ) = 0 ;
int j = 0 ;
if ( syms = = osyms )
j = o_nsyms ;
for ( ; j < syms - > nsyms ; j + + , n + + )
{
struct symbol * xsym = syms - > symbol [ j ] ;
SYMBOL_TYPE ( xsym ) = type ;
TYPE_FIELD_NAME ( type , n ) = SYMBOL_NAME ( xsym ) ;
TYPE_FIELD_VALUE ( type , n ) = 0 ;
TYPE_FIELD_BITPOS ( type , n ) = SYMBOL_VALUE ( xsym ) ;
TYPE_FIELD_BITSIZE ( type , n ) = 0 ;
}
if ( syms = = osyms )
break ;
}
#if 0
/* This screws up perfectly good C programs with enums. FIXME. */
/* Is this Modula-2's BOOLEAN type? Flag it as such if so. */