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