]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/coffread.c
gdb-2.5.1
[thirdparty/binutils-gdb.git] / gdb / coffread.c
CommitLineData
7b4ac7e1 1/* Read coff symbol tables and convert to internal format, for GDB.
2 Design and support routines derived from dbxread.c, and UMAX COFF
3 specific routines written 9/1/87 by David D. Johnson, Brown University.
4 Revised 11/27/87 ddj@cs.brown.edu
5 Copyright (C) 1987 Free Software Foundation, Inc.
6
7GDB is distributed in the hope that it will be useful, but WITHOUT ANY
8WARRANTY. No author or distributor accepts responsibility to anyone
9for the consequences of using it or for whether it serves any
10particular purpose or works at all, unless he says so in writing.
11Refer to the GDB General Public License for full details.
12
13Everyone is granted permission to copy, modify and redistribute GDB,
14but only under the conditions described in the GDB General Public
15License. A copy of this license is supposed to have been given to you
16along with GDB so you can know your rights and responsibilities. It
17should be in a file named COPYING. Among other things, the copyright
18notice and this notice must be preserved on all copies.
19
20In other words, go ahead and share GDB, but don't try to stop
21anyone else from sharing it farther. Help stamp out software hoarding!
22*/
23\f
24#include "defs.h"
25#include "param.h"
26#ifdef COFF_FORMAT
27#include "initialize.h"
28#include "symtab.h"
29
30#include <a.out.h>
31#include <stdio.h>
32#include <obstack.h>
7b4ac7e1 33#include <sys/param.h>
34#include <sys/file.h>
35
36static void add_symbol_to_list ();
37static void read_coff_symtab ();
38static void patch_opaque_types ();
39static struct type *decode_function_type ();
40static struct type *decode_type ();
41static struct type *decode_base_type ();
42static struct type *read_enum_type ();
43static struct type *read_struct_type ();
44static void finish_block ();
45static struct blockvector *make_blockvector ();
46static struct symbol *process_coff_symbol ();
47static int init_stringtab ();
48static void free_stringtab ();
49static char *getfilename ();
50static char *getsymname ();
51static int init_lineno ();
52static void enter_linenos ();
53
54START_FILE
55
56/* Name of source file whose symbol data we are now processing.
57 This comes from a symbol named ".file". */
58
59static char *last_source_file;
60
61/* Core address of start and end of text of current source file.
62 This comes from a ".text" symbol where x_nlinno > 0. */
63
64static CORE_ADDR cur_src_start_addr;
65static CORE_ADDR cur_src_end_addr;
66
67/* End of the text segment of the executable file,
68 as found in the symbol _etext. */
69
70static CORE_ADDR end_of_text_addr;
71
72/* The addresses of the symbol table stream and number of symbols
73 of the object file we are reading (as copied into core). */
74
75static FILE *nlist_stream_global;
76static int nlist_nsyms_global;
77
78/* The file and text section headers of the symbol file */
79
80static FILHDR file_hdr;
81static SCNHDR text_hdr;
82
83/* The index in the symbol table of the last coff symbol that was processed. */
84
85static int symnum;
86
87/* Vector of types defined so far, indexed by their coff symnum. */
88
89static struct typevector *type_vector;
90
91/* Number of elements allocated for type_vector currently. */
92
93static int type_vector_length;
94
95/* Vector of line number information. */
96
97static struct linetable *line_vector;
98
99/* Index of next entry to go in line_vector_index. */
100
101static int line_vector_index;
102
103/* Last line number recorded in the line vector. */
104
105static int prev_line_number;
106
107/* Number of elements allocated for line_vector currently. */
108
109static int line_vector_length;
110
111/* Chain of typedefs of pointers to empty struct/union types.
112 They are chained thru the SYMBOL_VALUE. */
113
114#define HASHSIZE 127
115static struct symbol *opaque_type_chain[HASHSIZE];
116
117/* Record the symbols defined for each context in a list.
118 We don't create a struct block for the context until we
119 know how long to make it. */
120
121struct pending
122{
123 struct pending *next;
124 struct symbol *symbol;
125};
126
127/* Here are the three lists that symbols are put on. */
128
129struct pending *file_symbols; /* static at top level, and types */
130
131struct pending *global_symbols; /* global functions and variables */
132
133struct pending *local_symbols; /* everything local to lexical context */
134
135/* List of unclosed lexical contexts
136 (that will become blocks, eventually). */
137
138struct context_stack
139{
140 struct context_stack *next;
141 struct pending *locals;
142 struct pending_block *old_blocks;
143 struct symbol *name;
144 CORE_ADDR start_addr;
145 int depth;
146};
147
148struct context_stack *context_stack;
149
150/* Nonzero if within a function (so symbols should be local,
151 if nothing says specifically). */
152
153int within_function;
154
155/* List of blocks already made (lexical contexts already closed).
156 This is used at the end to make the blockvector. */
157
158struct pending_block
159{
160 struct pending_block *next;
161 struct block *block;
162};
163
164struct pending_block *pending_blocks;
165
166extern CORE_ADDR first_object_file_end; /* From blockframe.c */
167
168/* File name symbols were loaded from. */
169
170static char *symfile;
7b4ac7e1 171\f
172/* Look up a coff type-number index. Return the address of the slot
173 where the type for that index is stored.
174 The type-number is in INDEX.
175
176 This can be used for finding the type associated with that index
177 or for associating a new type with the index. */
178
179static struct type **
180coff_lookup_type (index)
181 register int index;
182{
183 if (index >= type_vector_length)
184 {
185 type_vector_length *= 2;
186 type_vector = (struct typevector *)
187 xrealloc (type_vector, sizeof (struct typevector)
188 + type_vector_length * sizeof (struct type *));
189 bzero (&type_vector->type[type_vector_length / 2],
190 type_vector_length * sizeof (struct type *) / 2);
191 }
192 return &type_vector->type[index];
193}
194
195/* Make sure there is a type allocated for type number index
196 and return the type object.
197 This can create an empty (zeroed) type object. */
198
199static struct type *
200coff_alloc_type (index)
201 int index;
202{
203 register struct type **type_addr = coff_lookup_type (index);
204 register struct type *type = *type_addr;
205
206 /* If we are referring to a type not known at all yet,
207 allocate an empty type for it.
208 We will fill it in later if we find out how. */
209 if (type == 0)
210 {
211 type = (struct type *) obstack_alloc (symbol_obstack,
212 sizeof (struct type));
213 bzero (type, sizeof (struct type));
214 *type_addr = type;
215 }
216 return type;
217}
218\f
219/* maintain the lists of symbols and blocks */
220
221/* Add a symbol to one of the lists of symbols. */
222static void
223add_symbol_to_list (symbol, listhead)
224 struct symbol *symbol;
225 struct pending **listhead;
226{
227 register struct pending *link
228 = (struct pending *) xmalloc (sizeof (struct pending));
229
230 link->next = *listhead;
231 link->symbol = symbol;
232 *listhead = link;
233}
234
235/* Take one of the lists of symbols and make a block from it.
236 Put the block on the list of pending blocks. */
237
238static void
239finish_block (symbol, listhead, old_blocks, start, end)
240 struct symbol *symbol;
241 struct pending **listhead;
242 struct pending_block *old_blocks;
243 CORE_ADDR start, end;
244{
245 register struct pending *next, *next1;
246 register struct block *block;
247 register struct pending_block *pblock;
248 struct pending_block *opblock;
249 register int i;
250
251 /* Count the length of the list of symbols. */
252
253 for (next = *listhead, i = 0; next; next = next->next, i++);
254
255 block = (struct block *) xmalloc (sizeof (struct block) + (i - 1) * sizeof (struct symbol *));
256
257 /* Copy the symbols into the block. */
258
259 BLOCK_NSYMS (block) = i;
260 for (next = *listhead; next; next = next->next)
261 BLOCK_SYM (block, --i) = next->symbol;
262
263 BLOCK_START (block) = start;
264 BLOCK_END (block) = end;
265 BLOCK_SUPERBLOCK (block) = 0; /* Filled in when containing block is made */
266
267 /* Put the block in as the value of the symbol that names it. */
268
269 if (symbol)
270 {
271 SYMBOL_BLOCK_VALUE (symbol) = block;
272 BLOCK_FUNCTION (block) = symbol;
273 }
274 else
275 BLOCK_FUNCTION (block) = 0;
276
277 /* Now free the links of the list, and empty the list. */
278
279 for (next = *listhead; next; next = next1)
280 {
281 next1 = next->next;
282 free (next);
283 }
284 *listhead = 0;
285
286 /* Install this block as the superblock
287 of all blocks made since the start of this scope
288 that don't have superblocks yet. */
289
290 opblock = 0;
291 for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
292 {
293 if (BLOCK_SUPERBLOCK (pblock->block) == 0)
294 BLOCK_SUPERBLOCK (pblock->block) = block;
295 opblock = pblock;
296 }
297
298 /* Record this block on the list of all blocks in the file.
299 Put it after opblock, or at the beginning if opblock is 0.
300 This puts the block in the list after all its subblocks. */
301
302 pblock = (struct pending_block *) xmalloc (sizeof (struct pending_block));
303 pblock->block = block;
304 if (opblock)
305 {
306 pblock->next = opblock->next;
307 opblock->next = pblock;
308 }
309 else
310 {
311 pblock->next = pending_blocks;
312 pending_blocks = pblock;
313 }
314}
315
316static struct blockvector *
317make_blockvector ()
318{
319 register struct pending_block *next, *next1;
320 register struct blockvector *blockvector;
321 register int i;
322
323 /* Count the length of the list of blocks. */
324
325 for (next = pending_blocks, i = 0; next; next = next->next, i++);
326
327 blockvector = (struct blockvector *) xmalloc (sizeof (struct blockvector) + (i - 1) * sizeof (struct block *));
328
329 /* Copy the blocks into the blockvector.
330 This is done in reverse order, which happens to put
331 the blocks into the proper order (ascending starting address).
332 finish_block has hair to insert each block into the list
333 after its subblocks in order to make sure this is true. */
334
335 BLOCKVECTOR_NBLOCKS (blockvector) = i;
336 for (next = pending_blocks; next; next = next->next)
337 BLOCKVECTOR_BLOCK (blockvector, --i) = next->block;
338
339 /* Now free the links of the list, and empty the list. */
340
341 for (next = pending_blocks; next; next = next1)
342 {
343 next1 = next->next;
344 free (next);
345 }
346 pending_blocks = 0;
347
348 return blockvector;
349}
350
351/* Manage the vector of line numbers. */
352
353static
354record_line (line, pc)
355 int line;
356 CORE_ADDR pc;
357{
358 /* Make sure line vector is big enough. */
359
360 if (line_vector_index + 2 >= line_vector_length)
361 {
362 line_vector_length *= 2;
363 line_vector = (struct linetable *)
364 xrealloc (line_vector, sizeof (struct linetable)
365 + line_vector_length * sizeof (int));
366 }
367
368 /* If this line is not continguous with previous one recorded,
369 all lines between subsequent line and current one are same pc.
370 Add one item to line vector, and if more than one line skipped,
371 record a line-number entry for it. */
372 if (prev_line_number > 0 && line != prev_line_number + 1)
373 line_vector->item[line_vector_index++] = pc;
374 if (prev_line_number < 0 || line > prev_line_number + 2)
375 line_vector->item[line_vector_index++] = - line;
376 prev_line_number = line;
377
378 /* Record the core address of the line. */
379 line_vector->item[line_vector_index++] = pc;
380}
381\f
382/* Start a new symtab for a new source file.
383 This is called when a COFF ".file" symbol is seen;
384 it indicates the start of data for one original source file. */
385
386static void
387start_symtab ()
388{
389 file_symbols = 0;
390 global_symbols = 0;
391 context_stack = 0;
392 within_function = 0;
393 last_source_file = 0;
394
395 /* Initialize the source file information for this file. */
396
397 line_vector_index = 0;
398 line_vector_length = 1000;
399 prev_line_number = -2; /* Force first line number to be explicit */
400 line_vector = (struct linetable *)
401 xmalloc (sizeof (struct linetable) + line_vector_length * sizeof (int));
402}
403
404/* Save the vital information for use when closing off the current file.
405 NAME is the file name the symbols came from, START_ADDR is the first
406 text address for the file, and SIZE is the number of bytes of text. */
407
408static void
409complete_symtab (name, start_addr, size)
410 char *name;
411 CORE_ADDR start_addr;
412 unsigned int size;
413{
414 last_source_file = savestring (name, strlen (name));
415 cur_src_start_addr = start_addr;
416 cur_src_end_addr = start_addr + size;
417}
418
419/* Finish the symbol definitions for one main source file,
420 close off all the lexical contexts for that file
421 (creating struct block's for them), then make the
422 struct symtab for that file and put it in the list of all such. */
423
424static void
425end_symtab ()
426{
427 register struct symtab *symtab;
428 register struct context_stack *cstk;
429 register struct blockvector *blockvector;
430 register struct linetable *lv;
431
432 /* Finish the lexical context of the last function in the file. */
433
434 if (context_stack)
435 {
436 cstk = context_stack;
437 /* Make a block for the local symbols within. */
438 finish_block (cstk->name, &local_symbols, cstk->old_blocks,
439 cstk->start_addr, cur_src_end_addr);
440 free (cstk);
441 }
442
443 finish_block (0, &file_symbols, 0, cur_src_start_addr, cur_src_end_addr);
444 finish_block (0, &global_symbols, 0, cur_src_start_addr, cur_src_end_addr);
445 blockvector = make_blockvector ();
446
447 /* Now create the symtab objects proper this source file. */
448
449 symtab = (struct symtab *) xmalloc (sizeof (struct symtab));
450 /* Fill in its components. */
451 symtab->blockvector = blockvector;
452 symtab->free_code = free_contents;
453 symtab->free_ptr = 0;
454 symtab->filename = last_source_file;
455 lv = line_vector;
456 lv->nitems = line_vector_index;
457 symtab->linetable = (struct linetable *)
458 xrealloc (lv, sizeof (struct linetable) + lv->nitems * sizeof (int));
459 symtab->nlines = 0;
460 symtab->line_charpos = 0;
461
462 /* Link the new symtab into the list of such. */
463 symtab->next = symtab_list;
464 symtab_list = symtab;
465
466 line_vector = 0;
467 line_vector_length = -1;
468 last_source_file = 0;
469}
470\f
471/* Accumulate the misc functions in bunches of 127.
472 At the end, copy them all into one newly allocated structure. */
473
474#define MISC_BUNCH_SIZE 127
475
476struct misc_bunch
477{
478 struct misc_bunch *next;
479 struct misc_function contents[MISC_BUNCH_SIZE];
480};
481
482/* Bunch currently being filled up.
483 The next field points to chain of filled bunches. */
484
485static struct misc_bunch *misc_bunch;
486
487/* Number of slots filled in current bunch. */
488
489static int misc_bunch_index;
490
491/* Total number of misc functions recorded so far. */
492
493static int misc_count;
494
495static void
496init_misc_functions ()
497{
498 misc_count = 0;
499 misc_bunch = 0;
500 misc_bunch_index = MISC_BUNCH_SIZE;
501}
502
503static void
504record_misc_function (name, address)
505 char *name;
506 CORE_ADDR address;
507{
508 register struct misc_bunch *new;
509
510 if (misc_bunch_index == MISC_BUNCH_SIZE)
511 {
512 new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch));
513 misc_bunch_index = 0;
514 new->next = misc_bunch;
515 misc_bunch = new;
516 }
517 misc_bunch->contents[misc_bunch_index].name = savestring (name, strlen (name));
518 misc_bunch->contents[misc_bunch_index].address = address;
519 misc_bunch_index++;
520 misc_count++;
521}
522
523static int
524compare_misc_functions (fn1, fn2)
525 struct misc_function *fn1, *fn2;
526{
527 /* Return a signed result based on unsigned comparisons
528 so that we sort into unsigned numeric order. */
529 if (fn1->address < fn2->address)
530 return -1;
531 if (fn1->address > fn2->address)
532 return 1;
533 return 0;
534}
535
536static void
537discard_misc_bunches ()
538{
539 register struct misc_bunch *next;
540
541 while (misc_bunch)
542 {
543 next = misc_bunch->next;
544 free (misc_bunch);
545 misc_bunch = next;
546 }
547}
548
549static void
550condense_misc_bunches ()
551{
552 register int i, j;
553 register struct misc_bunch *bunch;
554#ifdef NAMES_HAVE_UNDERSCORE
555 int offset = 1;
556#else
557 int offset = 0;
558#endif
559
560 misc_function_vector
561 = (struct misc_function *)
562 xmalloc (misc_count * sizeof (struct misc_function));
563
564 j = 0;
565 bunch = misc_bunch;
566 while (bunch)
567 {
568 for (i = 0; i < misc_bunch_index; i++)
569 {
570 register char *tmp;
571
572 misc_function_vector[j] = bunch->contents[i];
573 tmp = misc_function_vector[j].name;
574 misc_function_vector[j].name = (tmp[0] == '_' ? tmp + offset : tmp);
575 j++;
576 }
577 bunch = bunch->next;
578 misc_bunch_index = MISC_BUNCH_SIZE;
579 }
580
581 misc_function_count = j;
582
583 /* Sort the misc functions by address. */
584
585 qsort (misc_function_vector, j, sizeof (struct misc_function),
586 compare_misc_functions);
587}
588
589/* Call sort_syms to sort alphabetically
590 the symbols of each block of each symtab. */
591
592static int
593compare_symbols (s1, s2)
594 struct symbol **s1, **s2;
595{
596 /* Names that are less should come first. */
597 register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
598 if (namediff != 0) return namediff;
599 /* For symbols of the same name, registers should come first. */
600 return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
601 - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
602}
603
604static void
605sort_syms ()
606{
607 register struct symtab *s;
608 register int i, nbl;
609 register struct blockvector *bv;
610 register struct block *b;
611
612 for (s = symtab_list; s; s = s->next)
613 {
614 bv = BLOCKVECTOR (s);
615 nbl = BLOCKVECTOR_NBLOCKS (bv);
616 for (i = 0; i < nbl; i++)
617 {
618 b = BLOCKVECTOR_BLOCK (bv, i);
619 qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
620 sizeof (struct symbol *), compare_symbols);
621 }
622 }
623}
624\f
625/* This is the symbol-file command. Read the file, analyze its symbols,
626 and add a struct symtab to symtab_list. */
627
628void
629symbol_file_command (name)
630 char *name;
631{
632 int desc;
633 int num_symbols;
634 int num_sections;
635 int symtab_offset;
636 extern void close ();
637 register int val;
638 struct cleanup *old_chain;
639
640 dont_repeat ();
641
642 if (name == 0)
643 {
644 if (symtab_list && !query ("Discard symbol table? ", 0))
645 error ("Not confirmed.");
646 free_all_symtabs ();
647 return;
648 }
649
650 if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name))
651 error ("Not confirmed.");
652
653 if (symfile)
654 free (symfile);
655 symfile = 0;
656
657 {
658 char *absolute_name;
659
660 desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
661 if (desc < 0)
662 perror_with_name (name);
663 else
664 name = absolute_name;
665 }
666
667 old_chain = make_cleanup (close, desc);
668 make_cleanup (free_current_contents, &name);
669
670 if ((num_symbols = read_file_hdr (desc, &file_hdr)) < 0)
671 error ("File \"%s\" not in executable format.", name);
672
673 if (num_symbols == 0)
674 {
675 free_all_symtabs ();
676 printf ("%s does not have a symbol-table.\n", name);
677 fflush (stdout);
678 return;
679 }
680
681 num_sections = file_hdr.f_nscns;
682 symtab_offset = file_hdr.f_symptr;
683
684 if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections) < 0)
685 error ("\"%s\": can't read text section header", name);
686
687 /* Read the line number table, all at once. */
688
689 val = init_lineno (desc, text_hdr.s_lnnoptr, text_hdr.s_nlnno);
690 if (val < 0)
691 error ("\"%s\": error reading line numbers\n", name);
692
693 /* Now read the string table, all at once. */
694
695 val = init_stringtab (desc, symtab_offset + num_symbols * SYMESZ);
696 if (val < 0)
697 error ("\"%s\": can't get string table", name);
698 make_cleanup (free_stringtab, 0);
699
700 /* Position to read the symbol table. Do not read it all at once. */
701 val = lseek (desc, (long)symtab_offset, 0);
702 if (val < 0)
703 perror_with_name (name);
704
705 printf ("Reading symbol data from %s...", name);
706 fflush (stdout);
707
708 /* Throw away the old symbol table. */
709
710 free_all_symtabs ();
711
712 init_misc_functions ();
713 make_cleanup (discard_misc_bunches, 0);
714
715 /* Now that the executable file is positioned at symbol table,
716 process it and define symbols accordingly. */
717
718 read_coff_symtab (desc, num_symbols);
719
720 patch_opaque_types ();
721
722 /* Sort symbols alphabetically within each block. */
723
724 sort_syms ();
725
726 /* Go over the misc functions and install them in vector. */
727
728 condense_misc_bunches ();
729
730 /* Don't allow char * to have a typename (else would get caddr_t.) */
731
732 TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
733
734 /* Make a default for file to list. */
735
736 select_source_symtab (symtab_list);
737
738 symfile = savestring (name, strlen (name));
739
740 do_cleanups (old_chain);
741
742 printf ("done.\n");
743 fflush (stdout);
744}
745
746/* Return name of file symbols were loaded from, or 0 if none.. */
747
748char *
749get_sym_file ()
750{
751 return symfile;
752}
753\f
754/* Simplified internal version of coff symbol table information */
755
756struct coff_symbol {
757 char *c_name;
758 int c_symnum; /* symbol number of this entry */
759 int c_nsyms; /* 1 if syment only, 2 if syment + auxent */
760 long c_value;
761 int c_sclass;
762 int c_secnum;
763 unsigned int c_type;
764};
765
766/* Given pointers to a symbol table in coff style exec file,
767 analyze them and create struct symtab's describing the symbols.
768 NSYMS is the number of symbols in the symbol table.
769 We read them one at a time using read_one_sym (). */
770
771static void
772read_coff_symtab (desc, nsyms)
773 int desc;
774 int nsyms;
775{
776 FILE *stream = fdopen (desc, "r");
777 register struct context_stack *new;
778 struct coff_symbol coff_symbol;
779 register struct coff_symbol *cs = &coff_symbol;
780 static SYMENT main_sym;
781 static AUXENT main_aux;
782
783 int num_object_files = 0;
632ea0cc 784 int next_file_symnum;
7b4ac7e1 785 char *filestring;
786 int depth;
787 int fcn_first_line;
788 int fcn_last_line;
789 long fcn_line_ptr;
790
791 nlist_stream_global = stream;
792 nlist_nsyms_global = nsyms;
793 last_source_file = 0;
794 bzero (opaque_type_chain, sizeof opaque_type_chain);
795
796 type_vector_length = 160;
797 type_vector = (struct typevector *)
798 xmalloc (sizeof (struct typevector)
799 + type_vector_length * sizeof (struct type *));
800 bzero (type_vector->type, type_vector_length * sizeof (struct type *));
801
802 start_symtab ();
803
804 symnum = 0;
805 while (symnum < nsyms)
806 {
807 read_one_sym (cs, &main_sym, &main_aux);
808
7b4ac7e1 809 if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
810 {
811 CORE_ADDR last_file_end = cur_src_end_addr;
812
813 if (last_source_file)
814 end_symtab ();
815
816 start_symtab ();
817 complete_symtab ("_globals_", 0, first_object_file_end);
818 /* done with all files, everything from here on out is globals */
819 }
820
632ea0cc 821 /* Special case for file with type declarations only, no text. */
822 if (!last_source_file && cs->c_type != T_NULL && cs->c_secnum == N_DEBUG)
823 complete_symtab (filestring, 0, 0);
824
7b4ac7e1 825 if (ISFCN (cs->c_type))
826 {
827 /*
828 * gdb expects all functions to also be in misc_function
829 * list -- why not...
830 */
831 record_misc_function (cs->c_name, cs->c_value);
832
833 fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
834 within_function = 1;
835
836 new = (struct context_stack *)
837 xmalloc (sizeof (struct context_stack));
838 new->depth = depth = 0;
839 new->next = 0;
840 context_stack = new;
841 new->locals = 0;
842 new->old_blocks = pending_blocks;
843 new->start_addr = cs->c_value;
844 new->name = process_coff_symbol (cs, &main_aux);
845 continue;
846 }
847
848 switch (cs->c_sclass)
849 {
850 case C_EFCN:
851 case C_EXTDEF:
852 case C_ULABEL:
853 case C_USTATIC:
854 case C_LINE:
855 case C_ALIAS:
856 case C_HIDDEN:
857 printf ("Bad n_sclass = %d\n", cs->c_sclass);
858 break;
859
860 case C_FILE:
861 /*
862 * c_value field contains symnum of next .file entry in table
863 * or symnum of first global after last .file.
864 */
865 next_file_symnum = cs->c_value;
866 filestring = getfilename (&main_aux);
867 /*
868 * Complete symbol table for last object file
869 * containing debugging information.
870 */
871 if (last_source_file)
872 {
873 end_symtab ();
874 start_symtab ();
875 }
7b4ac7e1 876 num_object_files++;
877 break;
878
879 case C_EXT:
880 if (cs->c_secnum == N_ABS && strcmp (cs->c_name, _ETEXT) == 0)
881 {
882 end_of_text_addr = cs->c_value;
883 }
884 if (cs->c_type == T_NULL)
885 {
886 if (cs->c_secnum <= 1) /* text or abs */
887 {
888 record_misc_function (cs->c_name, cs->c_value);
889 break;
890 }
891 else
892 cs->c_type = T_INT;
893 }
894 (void) process_coff_symbol (cs, &main_aux);
895 break;
896
897 case C_STAT:
898 if (cs->c_type == T_NULL && cs->c_secnum > N_UNDEF)
899 {
7b4ac7e1 900 if (strcmp (cs->c_name, _TEXT) == 0)
901 {
7b4ac7e1 902 if (num_object_files == 1)
903 {
904 /* Record end address of first file, crt0.s */
905 first_object_file_end =
906 cs->c_value + main_aux.x_scn.x_scnlen;
907 }
908 /*
909 * Fill in missing information for debugged
910 * object file only if we have line number info.
911 */
912 if (main_aux.x_scn.x_nlinno > 0)
913 {
914 complete_symtab (filestring, cs->c_value,
915 main_aux.x_scn.x_scnlen);
916 }
917 break;
918 }
919 else if (strcmp (cs->c_name, _DATA) == 0)
920 break;
921 else if (strcmp (cs->c_name, _BSS) == 0)
922 break;
923
924 /* get rid of assembly labels here */
925 /* record_misc_function (cs->c_name, cs->c_value); */
926 break;
927 }
928 (void) process_coff_symbol (cs, &main_aux);
929 break;
930
931 case C_FCN:
932 if (strcmp (cs->c_name, ".bf") == 0)
933 {
934 /* value contains address of first non-init type code */
935 /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
936 contains line number of '{' } */
937 fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
938 }
939 else if (strcmp (cs->c_name, ".ef") == 0)
940 {
941 /* value contains address of exit/return from function */
942 /* round it up to next multiple of 16 */
943 cs->c_value = (cs->c_value + 15) & -16;
944 /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
945 contains number of lines to '}' */
946 fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
947 enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line);
948
949 new = context_stack;
950 finish_block (new->name, &local_symbols, new->old_blocks,
951 new->start_addr, cs->c_value);
952 context_stack = 0;
953 within_function = 0;
954 free (new);
955 }
956 break;
957
958 case C_BLOCK:
959 if (strcmp (cs->c_name, ".bb") == 0)
960 {
961 new = (struct context_stack *)
962 xmalloc (sizeof (struct context_stack));
963 depth++;
964 new->depth = depth;
965 new->next = context_stack;
966 context_stack = new;
967 new->locals = local_symbols;
968 new->old_blocks = pending_blocks;
969 new->start_addr = cs->c_value;
970 new->name = 0;
971 local_symbols = 0;
972 }
973 else if (strcmp (cs->c_name, ".eb") == 0)
974 {
975 new = context_stack;
976 if (new == 0 || depth != new->depth)
977 error ("Invalid symbol data: .bb/.eb symbol mismatch.");
978 if (local_symbols && context_stack->next)
979 {
980 /* Make a block for the local symbols within. */
981 finish_block (0, &local_symbols, new->old_blocks,
982 new->start_addr, cs->c_value);
983 }
984 depth--;
985 local_symbols = new->locals;
986 context_stack = new->next;
987 free (new);
988 }
989 break;
990
991 default:
992 (void) process_coff_symbol (cs, &main_aux);
993 break;
994 }
995 }
996
997 if (last_source_file)
998 end_symtab ();
999 fclose (stream);
1000}
1001\f
1002/* Routines for reading headers and symbols from executable. */
1003
1004/* Read COFF file header, check magic number,
1005 and return number of symbols. */
1006read_file_hdr (chan, file_hdr)
1007 int chan;
1008 FILHDR *file_hdr;
1009{
1010 lseek (chan, 0L, 0);
1011 if (myread (chan, (char *)file_hdr, FILHSZ) < 0)
1012 return -1;
1013
632ea0cc 1014 switch (file_hdr->f_magic)
1015 {
1016 case NS32GMAGIC:
1017 case NS32SMAGIC:
1018 return file_hdr->f_nsyms;
1019
1020 default:
1021 return -1;
1022 }
7b4ac7e1 1023}
1024
1025read_aout_hdr (chan, aout_hdr, size)
1026 int chan;
1027 AOUTHDR *aout_hdr;
1028 int size;
1029{
1030 lseek (chan, (long)FILHSZ, 0);
1031 if (size != sizeof (AOUTHDR))
1032 return -1;
1033 if (myread (chan, (char *)aout_hdr, size) != size)
1034 return -1;
1035 return 0;
1036}
1037
1038read_section_hdr (chan, section_name, section_hdr, nsects)
1039 register int chan;
1040 register char *section_name;
1041 SCNHDR *section_hdr;
1042 register int nsects;
1043{
1044 register int i;
1045
1046 if (lseek (chan, FILHSZ + sizeof (AOUTHDR), 0) < 0)
1047 return -1;
1048
1049 for (i = 0; i < nsects; i++)
1050 {
1051 if (myread (chan, (char *)section_hdr, SCNHSZ) < 0)
1052 return -1;
1053 if (strncmp (section_hdr->s_name, section_name, 8) == 0)
1054 return 0;
1055 }
1056 return -1;
1057}
1058
1059read_one_sym (cs, sym, aux)
1060 register struct coff_symbol *cs;
1061 register SYMENT *sym;
1062 register AUXENT *aux;
1063{
1064 cs->c_symnum = symnum;
1065 fread ((char *)sym, SYMESZ, 1, nlist_stream_global);
1066 cs->c_nsyms = (sym->n_numaux & 0xff) + 1;
1067 if (cs->c_nsyms == 2)
1068 {
1069 /* doc for coff says there is either no aux entry or just one */
1070 fread ((char *)aux, AUXESZ, 1, nlist_stream_global);
1071 }
1072 else if (cs->c_nsyms > 2)
1073 error ("more than one aux symbol table entry at symnum=%d\n", symnum);
1074
1075 cs->c_name = getsymname (sym);
1076 cs->c_value = sym->n_value;
1077 cs->c_sclass = (sym->n_sclass & 0xff);
1078 cs->c_secnum = sym->n_scnum;
1079 cs->c_type = (unsigned) sym->n_type;
1080
7b4ac7e1 1081 symnum += cs->c_nsyms;
1082}
1083\f
1084/* Support for string table handling */
1085
1086static char *stringtab = NULL;
1087
1088static int
1089init_stringtab (chan, offset)
1090 int chan;
1091 long offset;
1092{
1093 long buffer;
1094 int val;
1095
1096 if (lseek (chan, offset, 0) < 0)
1097 return -1;
1098
1099 val = myread (chan, (char *)&buffer, sizeof buffer);
7b4ac7e1 1100 if (val != sizeof buffer)
1101 return -1;
1102
1103 if (stringtab)
1104 free (stringtab);
1105 stringtab = (char *) xmalloc (buffer);
1106 bcopy (&buffer, stringtab, sizeof buffer);
1107
1108 val = myread (chan, stringtab + sizeof buffer, buffer - sizeof buffer);
1109 if (val != buffer - sizeof buffer || stringtab[buffer - 1] != '\0')
1110 return -1;
1111
1112 return 0;
1113}
1114
1115static void
1116free_stringtab ()
1117{
1118 if (stringtab)
1119 free (stringtab);
1120 stringtab = NULL;
1121}
1122
1123static char *
1124getsymname (symbol_entry)
1125 SYMENT *symbol_entry;
1126{
1127 static char buffer[SYMNMLEN+1];
1128 char *result;
1129
1130 if (symbol_entry->n_zeroes == 0)
1131 {
7b4ac7e1 1132 result = stringtab + symbol_entry->n_offset;
1133 }
1134 else
1135 {
1136 strncpy (buffer, symbol_entry->n_name, SYMNMLEN);
1137 buffer[SYMNMLEN] = '\0';
1138 result = buffer;
1139 }
1140 return result;
1141}
1142
1143static char *
1144getfilename (aux_entry)
1145 AUXENT *aux_entry;
1146{
1147 static char buffer[BUFSIZ];
1148 register char *temp;
1149 char *result;
1150 extern char *rindex ();
1151
7b4ac7e1 1152 if (aux_entry->x_file.x_foff != 0)
1153 strcpy (buffer, stringtab + aux_entry->x_file.x_foff);
1154 else
7b4ac7e1 1155 {
1156 strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
1157 buffer[FILNMLEN] = '\0';
1158 }
1159 result = buffer;
1160 if ((temp = rindex (result, '/')) != NULL)
1161 result = temp + 1;
1162 return (result);
1163}
1164
1165/* Support for line number handling */
1166static char *linetab = NULL;
1167static long linetab_offset;
1168static int linetab_count;
1169
1170static int
1171init_lineno (chan, offset, count)
1172 int chan;
1173 long offset;
1174 int count;
1175{
1176 int val;
1177
1178 if (lseek (chan, offset, 0) < 0)
1179 return -1;
1180
1181 if (linetab)
1182 free (linetab);
1183 linetab = (char *) xmalloc (count * LINESZ);
1184
1185 val = myread (chan, linetab, count * LINESZ);
1186 if (val != count * LINESZ)
1187 return -1;
1188
1189 linetab_offset = offset;
1190 linetab_count = count;
1191 return 0;
1192}
1193
1194static void
1195enter_linenos (file_offset, first_line, last_line)
1196 long file_offset;
1197 register int first_line;
1198 register int last_line;
1199{
1200 register char *rawptr = &linetab[file_offset - linetab_offset];
1201 register struct lineno *lptr;
1202
1203 /* skip first line entry for each function */
1204 rawptr += LINESZ;
1205 /* line numbers start at one for the first line of the function */
1206 first_line--;
1207
1208 for (lptr = (struct lineno *)rawptr;
1209 lptr->l_lnno && lptr->l_lnno <= last_line;
1210 rawptr += LINESZ, lptr = (struct lineno *)rawptr)
1211 {
1212 record_line (first_line + lptr->l_lnno, lptr->l_addr.l_paddr);
1213 }
1214}
1215\f
1216static int
1217hashname (name)
1218 char *name;
1219{
1220 register char *p = name;
1221 register int total = p[0];
1222 register int c;
1223
1224 c = p[1];
1225 total += c << 2;
1226 if (c)
1227 {
1228 c = p[2];
1229 total += c << 4;
1230 if (c)
1231 total += p[3] << 6;
1232 }
1233
1234 return total % HASHSIZE;
1235}
1236
1237static void
1238patch_type (type, real_type)
1239 struct type *type;
1240 struct type *real_type;
1241{
1242 register struct type *target = TYPE_TARGET_TYPE (type);
1243 register struct type *real_target = TYPE_TARGET_TYPE (real_type);
1244 int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
1245
1246 TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
1247 TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
1248 TYPE_FIELDS (target) = (struct field *)
1249 obstack_alloc (symbol_obstack, field_size);
1250
1251 bcopy (TYPE_FIELDS (real_target), TYPE_FIELDS (target), field_size);
1252
1253 if (TYPE_NAME (real_target))
1254 {
1255 if (TYPE_NAME (target))
1256 free (TYPE_NAME (target));
1257 TYPE_NAME (target) = concat (TYPE_NAME (real_target), "", "");
1258 }
1259}
1260
1261/* Patch up all appropriate typdef symbols in the opaque_type_chains
1262 so that they can be used to print out opaque data structures properly */
1263
1264static void
1265patch_opaque_types ()
1266{
1267 struct symtab *s;
1268
1269 /* Look at each symbol in the per-file block of each symtab. */
1270 for (s = symtab_list; s; s = s->next)
1271 {
1272 register struct block *b;
1273 register int i;
1274
1275 /* Go through the per-file symbols only */
1276 b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1);
1277 for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
1278 {
1279 register struct symbol *real_sym;
1280
1281 /* Find completed typedefs to use to fix opaque ones.
1282 Remove syms from the chain when their types are stored,
1283 but search the whole chain, as there may be several syms
1284 from different files with the same name. */
1285 real_sym = BLOCK_SYM (b, i);
1286 if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
1287 SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
1288 TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
1289 TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
1290 {
1291 register char *name = SYMBOL_NAME (real_sym);
1292 register int hash = hashname (name);
1293 register struct symbol *sym, *prev;
1294
1295 prev = 0;
1296 for (sym = opaque_type_chain[hash]; sym;)
1297 {
1298 if (name[0] == SYMBOL_NAME (sym)[0] &&
1299 !strcmp (name + 1, SYMBOL_NAME (sym) + 1))
1300 {
1301 if (prev)
1302 SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym);
1303 else
1304 opaque_type_chain[hash]
1305 = (struct symbol *) SYMBOL_VALUE (sym);
1306
1307 patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
1308
1309 if (prev)
1310 sym = (struct symbol *) SYMBOL_VALUE (prev);
1311 else
1312 sym = opaque_type_chain[hash];
1313 }
1314 else
1315 {
1316 prev = sym;
1317 sym = (struct symbol *) SYMBOL_VALUE (sym);
1318 }
1319 }
1320 }
1321 }
1322 }
1323}
1324\f
1325static struct symbol *
1326process_coff_symbol (cs, aux)
1327 register struct coff_symbol *cs;
1328 register AUXENT *aux;
1329{
1330 register struct symbol *sym = (struct symbol *)
1331 xmalloc (sizeof (struct symbol));
1332 char *name;
1333 char *dot;
1334#ifdef NAMES_HAVE_UNDERSCORE
1335 int offset = 1;
1336#else
1337 int offset = 0;
1338#endif
1339
1340 bzero (sym, sizeof (struct symbol));
1341 name = cs->c_name;
1342 name = (name[0] == '_' ? name + offset : name);
1343 SYMBOL_NAME (sym) = savestring (name, strlen (name));
1344
1345 /* default assumptions */
1346 SYMBOL_VALUE (sym) = cs->c_value;
1347 SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
1348
1349 if (ISFCN (cs->c_type))
1350 {
1351 SYMBOL_TYPE (sym) = decode_function_type (cs, cs->c_type, aux);
1352 SYMBOL_CLASS (sym) = LOC_BLOCK;
1353 if (cs->c_sclass == C_STAT)
1354 add_symbol_to_list (sym, &file_symbols);
1355 else if (cs->c_sclass == C_EXT)
1356 add_symbol_to_list (sym, &global_symbols);
1357 }
1358 else
1359 {
1360 SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
1361 switch (cs->c_sclass)
1362 {
1363 case C_NULL:
1364 break;
1365
1366 case C_AUTO:
1367 SYMBOL_CLASS (sym) = LOC_LOCAL;
1368 add_symbol_to_list (sym, &local_symbols);
1369 break;
1370
1371 case C_EXT:
1372 SYMBOL_CLASS (sym) = LOC_STATIC;
1373 add_symbol_to_list (sym, &global_symbols);
1374 break;
1375
1376 case C_STAT:
1377 SYMBOL_CLASS (sym) = LOC_STATIC;
1378 if (within_function) {
1379 /* Static symbol of local scope */
1380 add_symbol_to_list (sym, &local_symbols);
1381 }
1382 else {
1383 /* Static symbol at top level of file */
1384 add_symbol_to_list (sym, &file_symbols);
1385 }
1386 break;
1387
1388 case C_REG:
1389 case C_REGPARM:
1390 SYMBOL_CLASS (sym) = LOC_REGISTER;
1391 add_symbol_to_list (sym, &local_symbols);
1392 break;
1393
1394 case C_LABEL:
1395 break;
1396
1397 case C_ARG:
1398 SYMBOL_CLASS (sym) = LOC_ARG;
1399 add_symbol_to_list (sym, &local_symbols);
1400 /* If PCC says a parameter is a short or a char,
1401 it is really an int. */
1402 if (SYMBOL_TYPE (sym) == builtin_type_char
1403 || SYMBOL_TYPE (sym) == builtin_type_short)
1404 SYMBOL_TYPE (sym) = builtin_type_int;
1405 else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char
1406 || SYMBOL_TYPE (sym) == builtin_type_unsigned_short)
1407 SYMBOL_TYPE (sym) = builtin_type_unsigned_int;
1408 break;
1409
1410 case C_TPDEF:
1411 SYMBOL_CLASS (sym) = LOC_TYPEDEF;
1412 SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
1413
1414 /* If type has no name, give it one */
1415 if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0
1416 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0)
1417 TYPE_NAME (SYMBOL_TYPE (sym))
1418 = concat (SYMBOL_NAME (sym), "", "");
1419
1420 /* Keep track of any type which points to empty structured type,
1421 so it can be filled from a definition from another file */
1422 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
1423 TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0)
1424 {
1425 register int i = hashname (SYMBOL_NAME (sym));
1426
1427 SYMBOL_VALUE (sym) = (int) opaque_type_chain[i];
1428 opaque_type_chain[i] = sym;
1429 }
1430 add_symbol_to_list (sym, &file_symbols);
1431 break;
1432
1433 case C_STRTAG:
1434 case C_UNTAG:
1435 case C_ENTAG:
1436 SYMBOL_CLASS (sym) = LOC_TYPEDEF;
1437 SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
1438 if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0
1439 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0)
1440 TYPE_NAME (SYMBOL_TYPE (sym))
1441 = concat ("",
1442 (cs->c_sclass == C_ENTAG
1443 ? "enum "
1444 : (cs->c_sclass == C_STRTAG
1445 ? "struct " : "union ")),
1446 SYMBOL_NAME (sym));
1447 add_symbol_to_list (sym, &file_symbols);
1448 break;
1449
1450 default:
1451 break;
1452 }
1453 }
1454 return sym;
1455}
1456\f
1457/* Decode a coff type specifier;
1458 return the type that is meant. */
1459
1460static
1461struct type *
1462decode_type (cs, c_type, aux)
1463 register struct coff_symbol *cs;
1464 unsigned int c_type;
1465 register AUXENT *aux;
1466{
1467 register struct type *type = 0;
1468 register int n;
1469 unsigned int new_c_type;
1470
1471 if (c_type & ~N_BTMASK)
1472 {
1473 new_c_type = DECREF (c_type);
1474 if (ISPTR (c_type))
1475 {
1476 type = decode_type (cs, new_c_type, aux);
1477 type = lookup_pointer_type (type);
1478 }
1479 else if (ISFCN (c_type))
1480 {
1481 type = decode_type (cs, new_c_type, aux);
1482 type = lookup_function_type (type);
1483 }
1484 else if (ISARY (c_type))
1485 {
1486 int i, n;
1487 register unsigned short *dim;
1488 struct type *base_type;
1489
1490 /* Define an array type. */
1491 /* auxent refers to array, not base type */
1492 if (aux->x_sym.x_tagndx == 0)
1493 cs->c_nsyms = 1;
1494
1495 /* shift the indices down */
1496 dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
1497 i = 1;
1498 n = dim[0];
1499 for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)
1500 *dim = *(dim + 1);
1501 *dim = 0;
1502
1503 type = (struct type *)
1504 obstack_alloc (symbol_obstack, sizeof (struct type));
1505 bzero (type, sizeof (struct type));
1506
1507 base_type = decode_type (cs, new_c_type, aux);
1508
1509 TYPE_CODE (type) = TYPE_CODE_ARRAY;
1510 TYPE_TARGET_TYPE (type) = base_type;
1511 TYPE_LENGTH (type) = n * TYPE_LENGTH (base_type);
1512 }
1513 return type;
1514 }
1515
1516 /* Reference to existing type */
1517 if (cs->c_nsyms > 1 && aux->x_sym.x_tagndx != 0)
1518 {
1519 type = coff_alloc_type (aux->x_sym.x_tagndx);
1520 return type;
1521 }
1522
1523 return decode_base_type (cs, BTYPE (c_type), aux);
1524}
1525
1526/* Decode a coff type specifier for function definition;
1527 return the type that the function returns. */
1528
1529static
1530struct type *
1531decode_function_type (cs, c_type, aux)
1532 register struct coff_symbol *cs;
1533 unsigned int c_type;
1534 register AUXENT *aux;
1535{
1536 if (aux->x_sym.x_tagndx == 0)
1537 cs->c_nsyms = 1; /* auxent refers to function, not base type */
1538
1539 return decode_type (cs, DECREF (cs->c_type), aux);
1540}
1541\f
1542/* basic C types */
1543
1544static
1545struct type *
1546decode_base_type (cs, c_type, aux)
1547 register struct coff_symbol *cs;
1548 unsigned int c_type;
1549 register AUXENT *aux;
1550{
1551 struct type *type;
1552
1553 switch (c_type)
1554 {
1555 case T_NULL:
632ea0cc 1556 /* shouldn't show up here */
7b4ac7e1 1557 break;
1558
1559 case T_ARG:
1560 /* shouldn't show up here */
1561 break;
1562
1563 case T_CHAR:
1564 return builtin_type_char;
1565
1566 case T_SHORT:
1567 return builtin_type_short;
1568
1569 case T_INT:
1570 return builtin_type_int;
1571
1572 case T_LONG:
1573 return builtin_type_long;
1574
1575 case T_FLOAT:
1576 return builtin_type_float;
1577
1578 case T_DOUBLE:
1579 return builtin_type_double;
1580
1581 case T_STRUCT:
1582 if (cs->c_nsyms != 2)
1583 {
1584 /* anonymous structure type */
1585 type = coff_alloc_type (cs->c_symnum);
1586 TYPE_CODE (type) = TYPE_CODE_STRUCT;
1587 TYPE_NAME (type) = concat ("struct ", "<opaque>", "");
1588 TYPE_LENGTH (type) = 0;
1589 TYPE_FIELDS (type) = 0;
1590 TYPE_NFIELDS (type) = 0;
1591 }
1592 else
1593 {
1594 type = read_struct_type (cs->c_symnum,
1595 aux->x_sym.x_misc.x_lnsz.x_size,
1596 aux->x_sym.x_fcnary.x_fcn.x_endndx);
1597 }
1598 return type;
1599
1600 case T_UNION:
1601 if (cs->c_nsyms != 2)
1602 {
1603 /* anonymous union type */
1604 type = coff_alloc_type (cs->c_symnum);
1605 TYPE_NAME (type) = concat ("union ", "<opaque>", "");
1606 TYPE_LENGTH (type) = 0;
1607 TYPE_FIELDS (type) = 0;
1608 TYPE_NFIELDS (type) = 0;
1609 }
1610 else
1611 {
1612 type = read_struct_type (cs->c_symnum,
1613 aux->x_sym.x_misc.x_lnsz.x_size,
1614 aux->x_sym.x_fcnary.x_fcn.x_endndx);
1615 }
1616 TYPE_CODE (type) = TYPE_CODE_UNION;
1617 return type;
1618
1619 case T_ENUM:
1620 return read_enum_type (cs->c_symnum,
1621 aux->x_sym.x_misc.x_lnsz.x_size,
1622 aux->x_sym.x_fcnary.x_fcn.x_endndx);
1623
1624 case T_MOE:
1625 /* shouldn't show up here */
1626 break;
1627
1628 case T_UCHAR:
1629 return builtin_type_unsigned_char;
1630
1631 case T_USHORT:
1632 return builtin_type_unsigned_short;
1633
1634 case T_UINT:
1635 return builtin_type_unsigned_int;
1636
1637 case T_ULONG:
1638 return builtin_type_unsigned_long;
1639 }
632ea0cc 1640 printf ("unexpected type %d at symnum %d\n", c_type, cs->c_symnum);
7b4ac7e1 1641 return builtin_type_void;
1642}
1643\f
1644/* This page contains subroutines of read_type. */
1645
1646/* Read the description of a structure (or union type)
1647 and return an object describing the type. */
1648
1649static struct type *
1650read_struct_type (index, length, lastsym)
1651 int index;
1652 int length;
1653 int lastsym;
1654{
1655 struct nextfield
1656 {
1657 struct nextfield *next;
1658 struct field field;
1659 };
1660
1661 register struct type *type;
1662 register struct nextfield *list = 0;
1663 struct nextfield *new;
1664 int nfields = 0;
1665 register int n;
1666 char *name;
1667#ifdef NAMES_HAVE_UNDERSCORE
1668 int offset = 1;
1669#else
1670 int offset = 0;
1671#endif
1672 struct coff_symbol member_sym;
1673 register struct coff_symbol *ms = &member_sym;
1674 SYMENT sub_sym;
1675 AUXENT sub_aux;
1676
1677 type = coff_alloc_type (index);
1678 TYPE_CODE (type) = TYPE_CODE_STRUCT;
1679 TYPE_LENGTH (type) = length;
1680
1681 while (symnum < lastsym && symnum < nlist_nsyms_global)
1682 {
1683 read_one_sym (ms, &sub_sym, &sub_aux);
1684 name = ms->c_name;
1685 name = (name[0] == '_' ? name + offset : name);
1686
1687 switch (ms->c_sclass)
1688 {
1689 case C_MOS:
1690 case C_MOU:
1691
1692 /* Get space to record the next field's data. */
1693 new = (struct nextfield *) alloca (sizeof (struct nextfield));
1694 new->next = list;
1695 list = new;
1696
1697 /* Save the data. */
1698 list->field.name = savestring (name, strlen (name));
1699 list->field.type = decode_type (ms, ms->c_type, &sub_aux);
1700 list->field.bitpos = 8 * ms->c_value;
1701 list->field.bitsize = 0;
1702 nfields++;
1703 break;
1704
1705 case C_FIELD:
1706
1707 /* Get space to record the next field's data. */
1708 new = (struct nextfield *) alloca (sizeof (struct nextfield));
1709 new->next = list;
1710 list = new;
1711
1712 /* Save the data. */
1713 list->field.name = savestring (name, strlen (name));
1714 list->field.type = decode_type (ms, ms->c_type, &sub_aux);
1715 list->field.bitpos = ms->c_value;
1716 list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size;
1717 nfields++;
1718 break;
1719
1720 case C_EOS:
1721 break;
1722 }
1723 }
1724 /* Now create the vector of fields, and record how big it is. */
1725
1726 TYPE_NFIELDS (type) = nfields;
1727 TYPE_FIELDS (type) = (struct field *)
1728 obstack_alloc (symbol_obstack, sizeof (struct field) * nfields);
1729
1730 /* Copy the saved-up fields into the field vector. */
1731
1732 for (n = nfields; list; list = list->next)
1733 TYPE_FIELD (type, --n) = list->field;
1734
1735 return type;
1736}
1737\f
1738/* Read a definition of an enumeration type,
1739 and create and return a suitable type object.
1740 Also defines the symbols that represent the values of the type. */
1741
1742static struct type *
1743read_enum_type (index, length, lastsym)
1744 int index;
1745 int length;
1746 int lastsym;
1747{
1748 register struct symbol *sym;
1749 register struct type *type;
1750 int nsyms = 0;
1751 struct pending **symlist;
1752 struct coff_symbol member_sym;
1753 register struct coff_symbol *ms = &member_sym;
1754 SYMENT sub_sym;
1755 AUXENT sub_aux;
1756 struct pending *osyms, *syms;
1757 register int n;
1758 char *name;
1759#ifdef NAMES_HAVE_UNDERSCORE
1760 int offset = 1;
1761#else
1762 int offset = 0;
1763#endif
1764
1765 type = coff_alloc_type (index);
1766 if (within_function)
1767 symlist = &local_symbols;
1768 else
1769 symlist = &file_symbols;
1770 osyms = *symlist;
1771
1772 while (symnum < lastsym && symnum < nlist_nsyms_global)
1773 {
1774 read_one_sym (ms, &sub_sym, &sub_aux);
1775 name = ms->c_name;
1776 name = (name[0] == '_' ? name + offset : name);
1777
1778 switch (ms->c_sclass)
1779 {
1780 case C_MOE:
1781 sym = (struct symbol *) xmalloc (sizeof (struct symbol));
1782 bzero (sym, sizeof (struct symbol));
1783
1784 SYMBOL_NAME (sym) = savestring (name, strlen (name));
1785 SYMBOL_CLASS (sym) = LOC_CONST;
1786 SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
1787 SYMBOL_VALUE (sym) = ms->c_value;
1788 add_symbol_to_list (sym, symlist);
1789 nsyms++;
1790 break;
1791
1792 case C_EOS:
1793 break;
1794 }
1795 }
1796
1797 /* Now fill in the fields of the type-structure. */
1798
1799 TYPE_LENGTH (type) = sizeof (int);
1800 TYPE_CODE (type) = TYPE_CODE_ENUM;
1801 TYPE_NFIELDS (type) = nsyms;
1802 TYPE_FIELDS (type) = (struct field *)
1803 obstack_alloc (symbol_obstack, sizeof (struct field) * nsyms);
1804
1805 /* Find the symbols for the values and put them into the type.
1806 The symbols can be found in the symlist that we put them on
1807 to cause them to be defined. osyms contains the old value
1808 of that symlist; everything up to there was defined by us. */
1809
1810 for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next)
1811 {
1812 SYMBOL_TYPE (syms->symbol) = type;
1813 TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol);
1814 TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (syms->symbol);
1815 TYPE_FIELD_BITPOS (type, n) = 0;
1816 TYPE_FIELD_BITSIZE (type, n) = 0;
1817 }
1818 return type;
1819}
1820
1821static
1822initialize ()
1823{
1824 symfile = 0;
1825
1826 add_com ("symbol-file", class_files, symbol_file_command,
1827 "Load symbol table (in coff format) from executable file FILE.");
1828}
1829
1830END_FILE
1831
1832#endif /* COFF_FORMAT */
1833