-
-/* Utility stack, used to nest procedures and blocks properly.
- It is a doubly linked list, to avoid too many alloc/free.
- Since we might need it quite a few times it is NOT deallocated
- after use. */
-
-static struct parse_stack {
- struct parse_stack *next, *prev;
- struct symtab *cur_st; /* Current symtab. */
- struct block *cur_block; /* Block in it. */
- int blocktype; /* What are we parsing. */
- int maxsyms; /* Max symbols in this block. */
- struct type *cur_type; /* Type we parse fields for. */
- int cur_field; /* Field number in cur_type. */
- int procadr; /* Start addres of this procedure */
- int numargs; /* Its argument count */
-} *top_stack; /* Top stack ptr */
-
-
-/* Enter a new lexical context */
-
-static void
-push_parse_stack()
-{
- struct parse_stack *new;
-
- /* Reuse frames if possible */
- if (top_stack && top_stack->prev)
- new = top_stack->prev;
- else
- new = (struct parse_stack *) xzalloc(sizeof(struct parse_stack));
- /* Initialize new frame with previous content */
- if (top_stack) {
- register struct parse_stack *prev = new->prev;
-
- *new = *top_stack;
- top_stack->prev = new;
- new->prev = prev;
- new->next = top_stack;
- }
- top_stack = new;
-}
-
-/* Exit a lexical context */
-
-static void
-pop_parse_stack()
-{
- if (!top_stack)
- return;
- if (top_stack->next)
- top_stack = top_stack->next;
-}
-
-
-/* Cross-references might be to things we haven't looked at
- yet, e.g. type references. To avoid too many type
- duplications we keep a quick fixup table, an array
- of lists of references indexed by file descriptor */
-
-static struct mips_pending {
- struct mips_pending *next; /* link */
- SYMR *s; /* the symbol */
- struct type *t; /* its partial type descriptor */
-} **pending_list;
-
-
-/* Check whether we already saw symbol SH in file FH as undefined */
-
-static struct mips_pending *
-is_pending_symbol(fh, sh)
- FDR *fh;
- SYMR *sh;
-{
- int f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
- register struct mips_pending *p;
-
- /* Linear search is ok, list is typically no more than 10 deep */
- for (p = pending_list[f_idx]; p; p = p->next)
- if (p->s == sh)
- break;
- return p;
-}
-
-/* Add a new undef symbol SH of type T */
-
-static void
-add_pending(fh, sh, t)
- FDR *fh;
- SYMR *sh;
- struct type *t;
-{
- int f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
- struct mips_pending *p = is_pending_symbol(fh, sh);
-
- /* Make sure we do not make duplicates */
- if (!p) {
- p = (struct mips_pending *) xmalloc(sizeof(*p));
- p->s = sh;
- p->t = t;
- p->next = pending_list[f_idx];
- pending_list[f_idx] = p;
- }
- sh->reserved = 1; /* for quick check */
-}
-
-/* Throw away undef entries when done with file index F_IDX */
-/* FIXME -- storage leak. This is never called!!! --gnu */
-
-#if 0
-
-static void
-free_pending(f_idx)
- int f_idx;
-{
- register struct mips_pending *p, *q;
-
- for (p = pending_list[f_idx]; p; p = q) {
- q = p->next;
- free((PTR)p);
- }
- pending_list[f_idx] = 0;
-}
-
-#endif
-
-static char *
-prepend_tag_kind(tag_name, type_code)
- char *tag_name;
- enum type_code type_code;
-{
- char *prefix;
- char *result;
- switch (type_code) {
- case TYPE_CODE_ENUM:
- prefix = "enum ";
- break;
- case TYPE_CODE_STRUCT:
- prefix = "struct ";
- break;
- case TYPE_CODE_UNION:
- prefix = "union ";
- break;
- default:
- prefix = "";
- }
-
- result = (char*)obstack_alloc (¤t_objfile->symbol_obstack,
- strlen(prefix) + strlen(tag_name) + 1);
- sprintf(result, "%s%s", prefix, tag_name);
- return result;
-}
-
-\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.
- Argument AX is the base pointer of aux symbols for this file (fh->iauxBase).
- BIGEND says whether aux symbols are big-endian or little-endian.
- Return count of SYMR's handled (normally one). */
-
-static int
-parse_symbol(sh, ax, bigend)
- SYMR *sh;
- union aux_ext *ax;
- int bigend;
-{
- 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;
- TIR tir;
-
- 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((char *)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((char *)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 += FP0_REGNUM-32;
- } else
- class = LOC_LOCAL;
- b = top_stack->cur_block;
- s = new_symbol((char *)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, 0, bigend);
- /* 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"; /* FIXME, not alloc'd in obstack */
- s = new_symbol(name);
-
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- if (sh->sc == scRegister) {
- SYMBOL_CLASS(s) = LOC_REGPARM;
- if (sh->value > 31)
- sh->value += FP0_REGNUM-32;
- } else
- SYMBOL_CLASS(s) = LOC_ARG;
- SYMBOL_VALUE(s) = sh->value;
- SYMBOL_TYPE(s) = parse_type(ax + sh->index, 0, bigend);
- 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((char *)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((char *)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 + 1, 0, bigend);
- 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;
-
- /* Beginning of code for structure, union, and enum definitions.
- They all share a common set of local variables, defined here. */
- {
- enum type_code type_code;
- SYMR *tsym;
- int nfields;
- long max_value;
- struct field *f;
-
- case stStruct: /* Start a block defining a struct type */
- type_code = TYPE_CODE_STRUCT;
- goto structured_common;
-
- case stUnion: /* Start a block defining a union type */
- type_code = TYPE_CODE_UNION;
- goto structured_common;
-
- case stEnum: /* Start a block defining an enum type */
- type_code = TYPE_CODE_ENUM;
- goto structured_common;
-
- case stBlock: /* Either a lexical block, or some type */
- if (sh->sc != scInfo)
- goto case_stBlock_code; /* Lexical block */
-
- type_code = TYPE_CODE_UNDEF; /* We have a type. */
-
- /* Common code for handling struct, union, enum, and/or as-yet-
- unknown-type blocks of info about structured data. `type_code'
- has been set to the proper TYPE_CODE, if we know it. */
- structured_common:
- push_parse_stack();
- top_stack->blocktype = stBlock;
-
- s = new_symbol((char *)sh->iss);
- SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_TYPEDEF;
- SYMBOL_VALUE(s) = 0;
- add_symbol(s, top_stack->cur_block);
-
- /* First count the number of fields and the highest value. */
- nfields = 0;
- max_value = 0;
- 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 Nil (or Void),
- without qualifiers, assume the tag is an
- enumeration. */
- if (tsym->index == indexNil)
- type_code = TYPE_CODE_ENUM;
- else {
- ecoff_swap_tir_in (bigend,
- &ax[tsym->index].a_ti,
- &tir);
- if ((tir.bt == btNil || tir.bt == btVoid)
- && tir.tq0 == tqNil)
- type_code = TYPE_CODE_ENUM;
- }
- nfields++;
- if (tsym->value > max_value)
- max_value = tsym->value;
- }
- else if (tsym->st == stBlock
- || tsym->st == stUnion
- || tsym->st == stEnum
- || tsym->st == stStruct
- || tsym->st == stParsed) {
- if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/
- if (tsym->index != 0)
- tsym = ((SYMR*)cur_fdr->isymBase)
- + tsym->index-1;
- }
- else complain (&block_member_complaint, tsym->st);
- }
-
- /* In an stBlock, there is no way to distinguish structs,
- 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 there is more than one member, and 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 (nfields > 1 && max_value == 0)
- type_code = TYPE_CODE_UNION;
- else
- type_code = TYPE_CODE_STRUCT;
-
- /* If this type was expected, use its partial definition */
- if (pend)
- t = is_pending_symbol(cur_fdr, sh)->t;
- else
- t = new_type(prepend_tag_kind((char *)sh->iss,
- type_code));
-
- TYPE_CODE(t) = type_code;
- TYPE_LENGTH(t) = sh->value;
- TYPE_NFIELDS(t) = nfields;
- TYPE_FIELDS(t) = f = (struct field*)
- TYPE_ALLOC (t, nfields * sizeof (struct field));
-
- if (type_code == TYPE_CODE_ENUM) {
- /* This is a non-empty enum. */
- for (tsym = sh + 1; tsym->st == stMember; tsym++) {
- struct symbol *enum_sym;
- f->bitpos = tsym->value;
- f->type = t;
- f->name = (char*)tsym->iss;
- f->bitsize = 0;
-
- enum_sym = (struct symbol *)
- obstack_alloc (¤t_objfile->symbol_obstack,
- sizeof (struct symbol));
- memset ((PTR)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) = tsym->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;
- /* Mark that symbol has a type, and say which one */
- sh->value = (long) t;
- break;
-
- /* End of local variables shared by struct, union, enum, and
- block (as yet unknown struct/union/enum) processing. */
- }
-
- case_stBlock_code:
- /* beginnning of (code) block. Value of symbol
- is the displacement from procedure start */
- push_parse_stack();
- top_stack->blocktype = stBlock;
- 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 mips_extra_func_info *e;
- struct block *b;
- int i;
-
- BLOCK_END(top_stack->cur_block) += sh->value; /* size */
-
- /* Make up special symbol to contain procedure specific
- info */
- s = new_symbol(MIPS_EFI_SYMBOL_NAME);
- SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_CONST;
- SYMBOL_TYPE(s) = builtin_type_void;
- e = (struct mips_extra_func_info *)
- obstack_alloc (¤t_objfile->symbol_obstack,
- sizeof (struct mips_extra_func_info));
- SYMBOL_VALUE(s) = (int)e;
- e->numargs = top_stack->numargs;
- add_symbol(s, top_stack->cur_block);
-
- /* 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;
- shrink_block(top_stack->cur_block, top_stack->cur_st);
- } else if (sh->sc == scText && top_stack->blocktype == stFile) {
- /* End of file. Pop parse stack and ignore. Higher
- level code deals with this. */
- ;
- } else complain (&stEnd_complaint, sh->sc);
-
- 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, &f->bitsize, bigend);
- break;
-
- case stTypedef: /* type definition */
- s = new_symbol((char *)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, 0, bigend);
- 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:
- complain(&unknown_mips_symtype_complaint, sh->st);
- break;
- }
- sh->st = stParsed;
- return count;
-}
-
-/* Parse the type information provided in the raw AX entries for
- the symbol SH. Return the bitfield size in BS, in case.
- We must byte-swap the AX entries before we use them; BIGEND says whether
- they are big-endian or little-endian (from fh->fBigendian). */
-
-static struct type *
-parse_type(ax, bs, bigend)
- union aux_ext *ax;
- int *bs;
- int bigend;
-{
- /* Null entries in this map are treated specially */
- static struct type **map_bt[] =
- {
- &builtin_type_void, /* btNil */
- 0, /* btAdr */
- &builtin_type_char, /* btChar */
- &builtin_type_unsigned_char, /* btUChar */
- &builtin_type_short, /* btShort */
- &builtin_type_unsigned_short, /* btUShort */
- &builtin_type_int, /* btInt */
- &builtin_type_unsigned_int, /* btUInt */
- &builtin_type_long, /* btLong */
- &builtin_type_unsigned_long, /* btULong */
- &builtin_type_float, /* btFloat */
- &builtin_type_double, /* btDouble */
- 0, /* btStruct */
- 0, /* btUnion */
- 0, /* btEnum */
- 0, /* btTypedef */
- 0, /* btRange */
- 0, /* btSet */
- &builtin_type_complex, /* btComplex */
- &builtin_type_double_complex, /* btDComplex */
- 0, /* btIndirect */
- &builtin_type_fixed_dec, /* btFixedDec */
- &builtin_type_float_dec, /* btFloatDec */
- &builtin_type_string, /* btString */
- 0, /* btBit */
- 0, /* btPicture */
- &builtin_type_void, /* btVoid */
- &builtin_type_long_long, /* btLongLong */
- &builtin_type_unsigned_long_long,/* btULongLong */
- };
-
- TIR t[1];
- struct type *tp = 0;
- char *fmt;
- union aux_ext *tax;
- enum type_code type_code;
-
- /* Use aux as a type information record, map its basic type. */
- tax = ax;
- ecoff_swap_tir_in (bigend, &tax->a_ti, t);
- if (t->bt > (sizeof (map_bt)/sizeof (*map_bt))) {
- complain (&basic_type_complaint, t->bt);
- return builtin_type_int;
- }
- if (map_bt[t->bt]) {
- tp = *map_bt[t->bt];
- fmt = "%s";
- } else {
- tp = NULL;
- /* Cannot use builtin types -- build our own */
- switch (t->bt) {
- case btAdr:
- tp = lookup_pointer_type (builtin_type_void);
- fmt = "%s";
- break;
- case btStruct:
- type_code = TYPE_CODE_STRUCT;
- fmt = "struct %s";
- break;
- case btUnion:
- type_code = TYPE_CODE_UNION;
- fmt = "union %s";
- break;
- case btEnum:
- type_code = TYPE_CODE_ENUM;
- fmt = "enum %s";
- break;
- case btRange:
- type_code = TYPE_CODE_RANGE;
- fmt = "%s";
- break;
- case btSet:
- type_code = TYPE_CODE_SET;
- fmt = "set %s";
- break;
- case btTypedef:
- default:
- complain (&basic_type_complaint, t->bt);
- return builtin_type_int;
- }
- }
-
- /* Skip over any further type qualifiers (FIXME). */
- if (t->continued) {
- /* This is the way it would work if the compiler worked */
- TIR t1[1];
- do {
- ax++;
- ecoff_swap_tir_in (bigend, ax, t1);
- } while (t1->continued);
- }
-
- /* Move on to next aux */
- ax++;
-
- if (t->fBitfield) {
- *bs = AUX_GET_WIDTH (bigend, ax);
- ax++;
- }
-
- /* All these types really point to some (common) MIPS type
- definition, and only the type-qualifiers fully identify
- them. We'll make the same effort at sharing. */
- if (t->bt == btIndirect ||
- t->bt == btStruct ||
- t->bt == btUnion ||
- t->bt == btEnum ||
- t->bt == btTypedef ||
- t->bt == btRange ||
- t->bt == btSet) {
- char name[256], *pn;
-
- /* Try to cross reference this type */
- ax += cross_ref(ax, &tp, type_code, &pn, bigend);
- /* reading .o file ? */
- if (UNSAFE_DATA_ADDR(tp))
- tp = init_type(type_code, 0, 0, (char *) NULL,
- (struct objfile *) NULL);
- /* SOMEONE OUGHT TO FIX DBXREAD TO DROP "STRUCT" */
- sprintf(name, fmt, pn);
-
- /* Usually, TYPE_CODE(tp) is already type_code. The main
- exception is if we guessed wrong re struct/union/enum. */
- if (TYPE_CODE(tp) != type_code) {
- complain (&bad_tag_guess_complaint, name);
- TYPE_CODE(tp) = type_code;
- }
- if (TYPE_NAME(tp) == NULL || strcmp(TYPE_NAME(tp), name) != 0)
- TYPE_NAME(tp) = obsavestring(name, strlen(name),
- ¤t_objfile -> type_obstack);
- }
-
- /* Deal with range types */
- if (t->bt == btRange) {
- TYPE_NFIELDS (tp) = 2;
- TYPE_FIELDS (tp) = (struct field *)
- TYPE_ALLOC (tp, 2 * sizeof (struct field));
- TYPE_FIELD_NAME (tp, 0) = obsavestring ("Low", strlen ("Low"),
- ¤t_objfile -> type_obstack);
- TYPE_FIELD_BITPOS (tp, 0) = AUX_GET_DNLOW (bigend, ax);
- ax++;
- TYPE_FIELD_NAME (tp, 1) = obsavestring ("High", strlen ("High"),
- ¤t_objfile -> type_obstack);
- TYPE_FIELD_BITPOS (tp, 1) = AUX_GET_DNHIGH (bigend, ax);
- ax++;
- }
-
- /* Parse all the type qualifiers now. If there are more
- than 6 the game will continue in the next aux */
-
-#define PARSE_TQ(tq) \
- if (t->tq != tqNil) ax += upgrade_type(&tp, t->tq, ax, bigend);
-
-again: PARSE_TQ(tq0);
- PARSE_TQ(tq1);
- PARSE_TQ(tq2);
- PARSE_TQ(tq3);
- PARSE_TQ(tq4);
- PARSE_TQ(tq5);
-#undef PARSE_TQ
-
- if (t->continued) {
- tax++;
- ecoff_swap_tir_in (bigend, &tax->a_ti, t);
- goto again;
- }
- return tp;
-}
-
-/* Make up a complex type from a basic one. Type is passed by
- reference in TPP and side-effected as necessary. The type
- qualifier TQ says how to handle the aux symbols at AX for
- the symbol SX we are currently analyzing. BIGEND says whether
- aux symbols are big-endian or little-endian.
- Returns the number of aux symbols we parsed. */
-
-static int
-upgrade_type(tpp, tq, ax, bigend)
- struct type **tpp;
- int tq;
- union aux_ext *ax;
- int bigend;
-{
- int off;
- struct type *t;
-
- /* Used in array processing */
- int rf, id;
- FDR *fh;
- struct field *f;
- int lower, upper;
- RNDXR rndx;
-
- switch (tq) {
- case tqPtr:
- t = lookup_pointer_type (*tpp);
- *tpp = t;
- return 0;
-
- case tqProc:
- t = lookup_function_type (*tpp);
- *tpp = t;
- return 0;
-
- case tqArray:
- /* We should probably try to use create_range_type and
- create_array_type here. FIXME! */
- off = 0;
- t = init_type(TYPE_CODE_ARRAY, 0, 0, (char *) NULL,
- (struct objfile *) NULL);
- TYPE_TARGET_TYPE(t) = *tpp;
-
- /* Determine and record the domain type (type of index) */
- ecoff_swap_rndx_in (bigend, ax, &rndx);
- id = rndx.index;
- rf = rndx.rfd;
- if (rf == 0xfff) {
- ax++;
- rf = AUX_GET_ISYM (bigend, ax);
- off++;
- }
- fh = get_rfd(cur_fd, rf);
-
- /* Fields are kept in an array */
- /* FIXME - Memory leak! */
- if (TYPE_NFIELDS(t))
- TYPE_FIELDS(t) = (struct field*)
- xrealloc((PTR) TYPE_FIELDS(t),
- (TYPE_NFIELDS(t)+1) * sizeof(struct field));
- else
- TYPE_FIELDS(t) = (struct field*)
- xzalloc(sizeof(struct field));
- f = &(TYPE_FIELD(t,TYPE_NFIELDS(t)));
- TYPE_NFIELDS(t)++;
- memset((PTR)f, 0, sizeof(struct field));
-
-/* XXX */ f->type = parse_type(id + (union aux_ext *)fh->iauxBase,
- &f->bitsize, bigend);
-
- ax++;
- lower = AUX_GET_DNLOW (bigend, ax);
- ax++;
- upper = AUX_GET_DNHIGH (bigend, ax);
- ax++;
- rf = AUX_GET_WIDTH (bigend, ax); /* bit size of array element */
-
- /* Check whether supplied array element bit size matches
- the known size of the element type. If this complaint
- ends up not happening, we can remove this code. It's
- here because we aren't sure we understand this *&%&$
- symbol format. */
- id = TYPE_LENGTH(TYPE_TARGET_TYPE(t)) << 3; /* bitsize */
- if (id == 0) {
- /* Most likely an undefined type */
- id = rf;
- TYPE_LENGTH(TYPE_TARGET_TYPE(t)) = id >> 3;
- }
- if (id != rf)
- complain (&array_bitsize_complaint, rf);
-
- TYPE_LENGTH(t) = (upper < 0) ? 0 :
- (upper - lower + 1) * (rf >> 3);
- *tpp = t;
- return 4 + off;
-
- case tqVol:
- /* Volatile -- currently ignored */
- return 0;
-
- case tqConst:
- /* Const -- currently ignored */
- return 0;
-
- default:
- complain (&unknown_type_qual_complaint, tq);
- return 0;
- }
-}
-
-
-/* Parse a procedure descriptor record PR. Note that the procedure
- is parsed _after_ the local symbols, now we just insert the extra
- information we need into a MIPS_EFI_SYMBOL_NAME symbol that has already
- been placed in the procedure's main block. Note also that images that
- have been partially stripped (ld -x) have been deprived
- of local symbols, and we have to cope with them here.
- The procedure's code ends at BOUND */
-
-static void
-parse_procedure (pr, bound, have_stabs)
- PDR *pr;
- int bound;
- int have_stabs;
-{
- struct symbol *s, *i;
- SYMR *sh = (SYMR*)pr->isym;
- struct block *b;
- struct mips_extra_func_info *e;
- char *sh_name;
-
- /* Static procedure at address pr->adr. Sigh. */
- if (sh == (SYMR*)-1) {
- complain (&pdr_static_symbol_complaint, pr->adr);
- return;
- }
- sh_name = (char*)sh->iss;
- if (have_stabs)
- s = lookup_symbol(sh_name, NULL, VAR_NAMESPACE, 0, NULL);
- else
- s = mylookup_symbol(sh_name, top_stack->cur_block,
- VAR_NAMESPACE, LOC_BLOCK);
-
- if (s != 0) {
- b = SYMBOL_BLOCK_VALUE(s);
- } else {
- complain (&pdr_for_nonsymbol_complaint, sh_name);
-#if 1
- return;
-#else
-/* FIXME -- delete. We can't do symbol allocation now; it's all done. */
- s = new_symbol(sh_name);
- SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
- SYMBOL_CLASS(s) = LOC_BLOCK;
- /* Donno its type, hope int is ok */
- SYMBOL_TYPE(s) = lookup_function_type (builtin_type_int);
- add_symbol(s, top_stack->cur_block);
- /* Wont have symbols for this one */
- b = new_block(2);
- SYMBOL_BLOCK_VALUE(s) = b;
- BLOCK_FUNCTION(b) = s;
- BLOCK_START(b) = pr->adr;
- BLOCK_END(b) = bound;
- BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
- add_block(b, top_stack->cur_st);
-#endif
- }
-
- i = mylookup_symbol(MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, LOC_CONST);
-
- if (i)
- {
- e = (struct mips_extra_func_info *)SYMBOL_VALUE(i);
- e->pdr = *pr;
- e->pdr.isym = (long)s;
- }
-}
-
-/* Parse the external symbol ES. Just call parse_symbol() after
- making sure we know where the aux are for it. For procedures,
- parsing of the PDRs has already provided all the needed
- information, we only parse them if SKIP_PROCEDURES is false,
- and only if this causes no symbol duplication.
- BIGEND says whether aux entries are big-endian or little-endian.
-
- This routine clobbers top_stack->cur_block and ->cur_st. */