head 1.4; access ; symbols RMS-has:1.2; locks ; strict; comment @ * @; 1.4 date 88.06.08.23.13.40; author gnu; state Exp; branches ; next 1.3; 1.3 date 88.02.28.03.37.53; author gnu; state Exp; branches ; next 1.2; 1.2 date 88.01.26.05.02.32; author gnu; state Exp; branches ; next 1.1; 1.1 date 88.01.26.00.38.04; author gnu; state Exp; branches ; next ; desc @Original from RMS's work dirs on Wheaties @ 1.4 log @Half reasonable reading of coff files. Problem was that it assumed that a .text would show up sometime, and it never did. We have to close out each source file's symtab as we hit the next one. @ text @/* Read coff symbol tables and convert to internal format, for GDB. Design and support routines derived from dbxread.c, and UMAX COFF specific routines written 9/1/87 by David D. Johnson, Brown University. Revised 11/27/87 ddj@@cs.brown.edu Copyright (C) 1987 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the GDB General Public License for full details. Everyone is granted permission to copy, modify and redistribute GDB, but only under the conditions described in the GDB General Public License. A copy of this license is supposed to have been given to you along with GDB so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. In other words, go ahead and share GDB, but don't try to stop anyone else from sharing it farther. Help stamp out software hoarding! */ #include "defs.h" #include "param.h" #ifdef COFF_FORMAT #include "initialize.h" #include "symtab.h" #include #include #include #include #include #include static void add_symbol_to_list (); static void read_coff_symtab (); static void patch_opaque_types (); static struct type *decode_function_type (); static struct type *decode_type (); static struct type *decode_base_type (); static struct type *read_enum_type (); static struct type *read_struct_type (); static void finish_block (); static struct blockvector *make_blockvector (); static struct symbol *process_coff_symbol (); static int init_stringtab (); static void free_stringtab (); static char *getfilename (); static char *getsymname (); static int init_lineno (); static void enter_linenos (); START_FILE /* Name of source file whose symbol data we are now processing. This comes from a symbol named ".file". */ static char *last_source_file; /* Core address of start and end of text of current source file. This comes from a ".text" symbol where x_nlinno > 0. */ static CORE_ADDR cur_src_start_addr; static CORE_ADDR cur_src_end_addr; /* End of the text segment of the executable file, as found in the symbol _etext. */ static CORE_ADDR end_of_text_addr; /* The addresses of the symbol table stream and number of symbols of the object file we are reading (as copied into core). */ static FILE *nlist_stream_global; static int nlist_nsyms_global; /* The file and text section headers of the symbol file */ static FILHDR file_hdr; static SCNHDR text_hdr; /* The index in the symbol table of the last coff symbol that was processed. */ static int symnum; /* Vector of types defined so far, indexed by their coff symnum. */ static struct typevector *type_vector; /* Number of elements allocated for type_vector currently. */ static int type_vector_length; /* Vector of line number information. */ static struct linetable *line_vector; /* Index of next entry to go in line_vector_index. */ static int line_vector_index; /* Last line number recorded in the line vector. */ static int prev_line_number; /* Number of elements allocated for line_vector currently. */ static int line_vector_length; /* Chain of typedefs of pointers to empty struct/union types. They are chained thru the SYMBOL_VALUE. */ #define HASHSIZE 127 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 pending { struct pending *next; struct symbol *symbol; }; /* Here are the three lists that symbols are put on. */ struct pending *file_symbols; /* static at top level, and types */ struct pending *global_symbols; /* global functions and variables */ struct pending *local_symbols; /* everything local to lexical context */ /* List of unclosed lexical contexts (that will become blocks, eventually). */ struct context_stack { struct context_stack *next; struct pending *locals; struct pending_block *old_blocks; struct symbol *name; CORE_ADDR start_addr; int depth; }; struct context_stack *context_stack; /* Nonzero if within a function (so symbols should be local, if nothing says specifically). */ int within_function; /* List of blocks already made (lexical contexts already closed). This is used at the end to make the blockvector. */ struct pending_block { struct pending_block *next; struct block *block; }; struct pending_block *pending_blocks; extern CORE_ADDR first_object_file_end; /* From blockframe.c */ /* File name symbols were loaded from. */ static char *symfile; int debug = 1; /* Look up a coff type-number index. Return the address of the slot where the type for that index is stored. The type-number is in INDEX. This can be used for finding the type associated with that index or for associating a new type with the index. */ static struct type ** coff_lookup_type (index) register int index; { if (index >= type_vector_length) { type_vector_length *= 2; type_vector = (struct typevector *) xrealloc (type_vector, sizeof (struct typevector) + type_vector_length * sizeof (struct type *)); bzero (&type_vector->type[type_vector_length / 2], type_vector_length * sizeof (struct type *) / 2); } return &type_vector->type[index]; } /* Make sure there is a type allocated for type number index and return the type object. This can create an empty (zeroed) type object. */ static struct type * coff_alloc_type (index) int index; { register struct type **type_addr = coff_lookup_type (index); register struct type *type = *type_addr; /* If we are referring to a type not known at all yet, allocate an empty type for it. We will fill it in later if we find out how. */ if (type == 0) { type = (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); bzero (type, sizeof (struct type)); *type_addr = type; } return type; } /* maintain the lists of symbols and blocks */ /* Add a symbol to one of the lists of symbols. */ static void add_symbol_to_list (symbol, listhead) struct symbol *symbol; struct pending **listhead; { register struct pending *link = (struct pending *) xmalloc (sizeof (struct 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 finish_block (symbol, listhead, old_blocks, start, end) struct symbol *symbol; struct pending **listhead; struct pending_block *old_blocks; CORE_ADDR start, end; { register struct 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 *) xmalloc (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