-free_numargs()
-{
- struct numarg *n = numargs_list, *m;
-
- while (n) {
- m = n->next;
- free(n);
- n = m;
- }
- numargs_list = 0;
-}
-
-\f
-/* Parsing Routines proper. */
-
-/* Parse a single symbol. Mostly just make up a GDB symbol for it.
- For blocks, procedures and types we open a new lexical context.
- This is basically just a big switch on the symbol's type.
- Return count of SYMR's handled (normally one). */
-
-static int
-parse_symbol(sh, ax)
- SYMR *sh;
- AUXU *ax;
-{
- char *name;
- struct symbol *s;
- struct block *b;
- struct type *t;
- struct field *f;
- int count = 1;
- /* When a symbol is cross-referenced from other files/symbols
- we mark it explicitly */
- int pend = (sh->reserved == 1);
- enum address_class class;
-
- switch (sh->st) {
-
- case stNil:
- break;
-
- case stGlobal: /* external symbol, goes into global block */
- class = LOC_STATIC;
- b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
- GLOBAL_BLOCK);
- s = new_symbol(sh->iss);
- SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
- goto data;
-
- case stStatic: /* static data, goes into current block. */
- class = LOC_STATIC;
- b = top_stack->cur_block;
- s = new_symbol(sh->iss);
- SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
- goto data;
-
- case stLocal: /* local variable, goes into current block */
- if (sh->sc == scRegister) {
- class = LOC_REGISTER;
- if (sh->value > 31)
- sh->value += 6;
- } else
- class = LOC_LOCAL;
- b = top_stack->cur_block;
- s = new_symbol(sh->iss);
- SYMBOL_VALUE(s) = sh->value;
-
-data: /* Common code for symbols describing data */
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- SYMBOL_CLASS(s) = class;
- add_symbol(s, b);
-
- /* Type could be missing in a number of cases */
- if (sh->sc == scUndefined || sh->sc == scNil ||
- sh->index == 0xfffff)
- SYMBOL_TYPE(s) = builtin_type_int; /* undefined? */
- else
- SYMBOL_TYPE(s) = parse_type(ax + sh->index, sh, 0);
- /* Value of a data symbol is its memory address */
- break;
-
- case stParam: /* arg to procedure, goes into current block */
- max_gdbinfo++;
- top_stack->numargs++;
-
- name = (char*)sh->iss;
- /* Special GNU C++ name. */
- if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0)
- name = "this";
- s = new_symbol(name);
-
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- if (sh->sc == scRegister) {
- SYMBOL_CLASS(s) = LOC_REGPARM;
- if (sh->value > 31)
- sh->value += 6;
- } else
- SYMBOL_CLASS(s) = LOC_ARG;
- SYMBOL_VALUE(s) = sh->value;
- SYMBOL_TYPE(s) = parse_type(ax + sh->index, sh, 0);
- add_symbol(s, top_stack->cur_block);
-#if 0
- /* FIXME: This has not been tested. See dbxread.c */
- /* Add the type of this parameter to the function/procedure
- type of this block. */
- add_param_to_type(&top_stack->cur_block->function->type,s);
-#endif
- break;
-
- case stLabel: /* label, goes into current block */
- s = new_symbol(sh->iss);
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; /* so that it can be used */
- SYMBOL_CLASS(s) = LOC_LABEL; /* but not misused */
- SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
- SYMBOL_TYPE(s) = builtin_type_int;
- add_symbol(s, top_stack->cur_block);
- break;
-
- case stProc: /* Procedure, usually goes into global block */
- case stStaticProc: /* Static procedure, goes into current block */
- s = new_symbol(sh->iss);
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_BLOCK;
- /* Type of the return value */
- if (sh->sc == scUndefined || sh->sc == scNil)
- t = builtin_type_int;
- else
- t = parse_type(ax + sh->index, sh, 0);
- b = top_stack->cur_block;
- if (sh->st == stProc) {
- struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);
- /* The next test should normally be true,
- but provides a hook for nested functions
- (which we don't want to make global). */
- if (b == BLOCKVECTOR_BLOCK(bv, STATIC_BLOCK))
- b = BLOCKVECTOR_BLOCK(bv, GLOBAL_BLOCK);
- }
- add_symbol(s, b);
-
- /* Make a type for the procedure itself */
-#if 0
- /* FIXME: This has not been tested yet! See dbxread.c */
- /* Generate a template for the type of this function. The
- types of the arguments will be added as we read the symbol
- table. */
- bcopy(SYMBOL_TYPE(s),lookup_function_type(t),sizeof(struct type));
-#else
- SYMBOL_TYPE(s) = lookup_function_type (t);
-#endif
-
- /* Create and enter a new lexical context */
- b = new_block(top_stack->maxsyms);
- SYMBOL_BLOCK_VALUE(s) = b;
- BLOCK_FUNCTION(b) = s;
- BLOCK_START(b) = BLOCK_END(b) = sh->value;
- BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
- add_block(b, top_stack->cur_st);
-
- /* Not if we only have partial info */
- if (sh->sc == scUndefined || sh->sc == scNil)
- break;
-
- push_parse_stack();
- top_stack->cur_block = b;
- top_stack->blocktype = sh->st;
- top_stack->cur_type = SYMBOL_TYPE(s);
- top_stack->cur_field = -1;
- top_stack->procadr = sh->value;
- top_stack->numargs = 0;
-
- sh->value = (long) SYMBOL_TYPE(s);
- break;
-
-
-#ifndef btVoid /* btVoid was added late. */
-#define btVoid 26
-#endif
-/* These new symbol types have been recently added to SGI machines. */
-#ifndef stStruct
-#define stStruct 26
-#endif
-#ifndef stUnion
-#define stUnion 27
-#endif
-#ifndef stEnum
-#define stEnum 28
-#endif
- case stStruct:
- case stUnion:
- case stEnum:
-
- case stBlock: /* Either a lexical block, or some type */
- push_parse_stack();
- top_stack->blocktype = stBlock;
- if (sh->sc == scInfo) { /* structure/union/enum def */
- int type_code =
- sh->st == stStruct ? TYPE_CODE_STRUCT
- : sh->st == stUnion ? TYPE_CODE_UNION
- : sh->st == stEnum ? TYPE_CODE_ENUM
- : TYPE_CODE_UNDEF;
- int nfields = 0;
- SYMR *tsym;
- long max_value = 0;
- struct field *f;
-
- s = new_symbol(sh->iss);
- SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_TYPEDEF;
- SYMBOL_VALUE(s) = 0;
- add_symbol(s, top_stack->cur_block);
- /* If this type was expected, use its partial definition */
- if (pend)
- t = is_pending_symbol(cur_fdr, sh)->t;
- else
- t = new_type(sh->iss);
-
- /* First count the number of fields. */
- for (tsym = sh+1; tsym->st != stEnd; tsym++)
- if (tsym->st == stMember) {
- if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
- /* If the type of the member is Void,
- assume the tag is an enumeration. */
- if (tsym->index == indexNil
- || ax[tsym->index].ti.bt == btVoid)
- type_code = TYPE_CODE_ENUM;
- nfields++;
- if (tsym->value > max_value)
- max_value = tsym->value;
- }
- else if (tsym->st == stBlock
- || tsym->st == stParsed) {
- if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/
- if (tsym->index != 0)
- tsym = ((SYMR*)cur_fdr->isymBase)
- + tsym->index-1;
- }
-
-
- /* There is no guaranteed way to distinguish struct,
- unions, and enums at this point. This is a bug in the
- original design (that has been fixed with the
- recent addition of the stStruct, stUnion, and stEnum
- symbol types.) The way you can tell is if/when you
- see a variable or field of that type: In that case
- the variable's type (in the AUX table) says if the
- type is struct, union, or enum,
- and points back to the stBlock here.
- So you can patch the tag kind up later - but only
- if there actually is a variable or field of that type.
-
- So until we know for sure, we will guess at this point.
- The heuristic is:
- If the first member has index==indexNil or a void type,
- assume we have an enumeration.
- Otherwise, if all the members have offset 0,
- assume we have a union.
- Otherwise, assume we have a struct.
-
- The heuristic could guess wrong in the case of
- of an enumeration with no members or a union
- with one (or zero) members, or when all except the
- last field of a struct have width zero.
- These are uncommon and/or illegal situations, and
- in any case guessing wrong probably doesn't matter much.
-
- But if we later do find out we were wrong,
- we fixup the tag kind. Members of an enumeration
- must be handled differently from struct/union fields,
- and that is harder to patch up, but luckily we
- shouldn't need to. (If there are any enumeration
- members, we can tell for sure it's an enum here.) */
-
- if (type_code == TYPE_CODE_UNDEF)
- if (max_value == 0) type_code = TYPE_CODE_UNION;
- else type_code = TYPE_CODE_STRUCT;
-
- TYPE_CODE(t) = type_code;
- TYPE_NFIELDS(t) = nfields;
- TYPE_FIELDS(t) = f = (struct field*)
- obstack_alloc (symbol_obstack,
- nfields * sizeof (struct field));
-
- if (type_code == TYPE_CODE_ENUM) {
- /* This is a non-empty enum. */
- while (sh[1].st == stMember) {
- struct symbol *enum_sym;
- sh++;
- f->bitpos = sh->value;
- f->type = t;
- f->name = (char*)sh->iss;
- f->bitsize = 0;
-
- enum_sym = (struct symbol *)
- obstack_alloc (symbol_obstack,
- sizeof (struct symbol));
- memset (enum_sym, 0, sizeof (struct symbol));
- SYMBOL_NAME (enum_sym) = f->name;
- SYMBOL_CLASS (enum_sym) = LOC_CONST;
- SYMBOL_TYPE (enum_sym) = t;
- SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
- SYMBOL_VALUE (enum_sym) = sh->value;
- add_symbol(enum_sym, top_stack->cur_block);
-
- /* Skip the stMembers that we've handled. */
- count++;
- f++;
- }
- }
- SYMBOL_TYPE(s) = t;
- /* make this the current type */
- top_stack->cur_type = t;
- top_stack->cur_field = 0;
- TYPE_LENGTH(t) = sh->value;
- /* Mark that symbol has a type, and say which one */
- sh->value = (long) t;
- } else {
- /* beginnning of (code) block. Value of symbol
- is the displacement from procedure start */
- b = new_block(top_stack->maxsyms);
- BLOCK_START(b) = sh->value + top_stack->procadr;
- BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
- top_stack->cur_block = b;
- add_block(b, top_stack->cur_st);
- }
- break;
-
- case stEnd: /* end (of anything) */
- if (sh->sc == scInfo) {
- /* Finished with type */
- top_stack->cur_type = 0;
- } else if (sh->sc == scText &&
- (top_stack->blocktype == stProc ||
- top_stack->blocktype == stStaticProc)) {
- /* Finished with procedure */
- struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);
- struct block *b;
- int i;
-
- BLOCK_END(top_stack->cur_block) += sh->value; /* size */
- got_numargs(top_stack->procadr, top_stack->numargs);
- /* Reallocate symbols, saving memory */
- b = shrink_block(top_stack->cur_block, top_stack->cur_st);
-
- /* f77 emits proc-level with address bounds==[0,0],
- So look for such child blocks, and patch them. */
- for (i = 0; i < BLOCKVECTOR_NBLOCKS(bv); i++) {
- struct block *b_bad = BLOCKVECTOR_BLOCK(bv,i);
- if (BLOCK_SUPERBLOCK(b_bad) == b
- && BLOCK_START(b_bad) == top_stack->procadr
- && BLOCK_END(b_bad) == top_stack->procadr) {
- BLOCK_START(b_bad) = BLOCK_START(b);
- BLOCK_END(b_bad) = BLOCK_END(b);
- }
- }
- } else if (sh->sc == scText && top_stack->blocktype == stBlock) {
- /* End of (code) block. The value of the symbol
- is the displacement from the procedure`s start
- address of the end of this block. */
- BLOCK_END(top_stack->cur_block) = sh->value + top_stack->procadr;
- (void) shrink_block(top_stack->cur_block, top_stack->cur_st);
- }
- pop_parse_stack(); /* restore previous lexical context */
- break;
-
- case stMember: /* member of struct or union */
- f = &TYPE_FIELDS(top_stack->cur_type)[top_stack->cur_field++];
- f->name = (char*)sh->iss;
- f->bitpos = sh->value;
- f->bitsize = 0;
- f->type = parse_type(ax + sh->index, sh, &f->bitsize);
- break;
-
- case stTypedef: /* type definition */
- s = new_symbol(sh->iss);
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_TYPEDEF;
- SYMBOL_BLOCK_VALUE(s) = top_stack->cur_block;
- add_symbol(s, top_stack->cur_block);
- SYMBOL_TYPE(s) = parse_type(ax + sh->index, sh, 0);
- sh->value = (long) SYMBOL_TYPE(s);
- break;
-
- case stFile: /* file name */
- push_parse_stack();
- top_stack->blocktype = sh->st;
- break;
-
- /* I`ve never seen these for C */
- case stRegReloc:
- break; /* register relocation */
- case stForward:
- break; /* forwarding address */
- case stConstant:
- break; /* constant */
- default:
- error("Unknown symbol type %x.", sh->st);
- }
- sh->st = stParsed;
- return count;
-}
-
-/* Parse the type information provided in the AX entries for
- the symbol SH. Return the bitfield size in BS, in case. */
+read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
+ struct objfile *objfile)
+{
+ bfd *abfd = objfile->obfd;
+ struct alphacoff_dynsecinfo si;
+ char *sym_secptr;
+ char *str_secptr;
+ char *dyninfo_secptr;
+ char *got_secptr;
+ bfd_size_type sym_secsize;
+ bfd_size_type str_secsize;
+ bfd_size_type dyninfo_secsize;
+ bfd_size_type got_secsize;
+ int sym_count;
+ int i;
+ int stripped;
+ Elfalpha_External_Sym *x_symp;
+ char *dyninfo_p;
+ char *dyninfo_end;
+ int got_entry_size = 8;
+ int dt_mips_local_gotno = -1;
+ int dt_mips_gotsym = -1;
+ struct cleanup *cleanups;
+
+ /* We currently only know how to handle alpha dynamic symbols. */
+ if (bfd_get_arch (abfd) != bfd_arch_alpha)
+ return;
+
+ /* Locate the dynamic symbols sections and read them in. */
+ memset ((char *) &si, 0, sizeof (si));
+ bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si);
+ if (si.sym_sect == NULL || si.str_sect == NULL
+ || si.dyninfo_sect == NULL || si.got_sect == NULL)
+ return;
+
+ sym_secsize = bfd_get_section_size (si.sym_sect);
+ str_secsize = bfd_get_section_size (si.str_sect);
+ dyninfo_secsize = bfd_get_section_size (si.dyninfo_sect);
+ got_secsize = bfd_get_section_size (si.got_sect);
+ sym_secptr = (char *) xmalloc (sym_secsize);
+ cleanups = make_cleanup (xfree, sym_secptr);
+ str_secptr = (char *) xmalloc (str_secsize);
+ make_cleanup (xfree, str_secptr);
+ dyninfo_secptr = (char *) xmalloc (dyninfo_secsize);
+ make_cleanup (xfree, dyninfo_secptr);
+ got_secptr = (char *) xmalloc (got_secsize);
+ make_cleanup (xfree, got_secptr);
+
+ if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
+ (file_ptr) 0, sym_secsize))
+ {
+ do_cleanups (cleanups);
+ return;
+ }
+ if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
+ (file_ptr) 0, str_secsize))
+ {
+ do_cleanups (cleanups);
+ return;
+ }
+ if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
+ (file_ptr) 0, dyninfo_secsize))
+ {
+ do_cleanups (cleanups);
+ return;
+ }
+ if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
+ (file_ptr) 0, got_secsize))
+ {
+ do_cleanups (cleanups);
+ return;
+ }