+ switch (sclass)
+ {
+ case C_EXT:
+ case C_HIDEXT:
+ {
+ /* The CSECT auxent--always the last auxent. */
+ union internal_auxent csect_aux;
+ unsigned int symnum_before = ssymnum;
+
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+ if (symbol.n_numaux > 1)
+ {
+ bfd_coff_swap_aux_in
+ (objfile->obfd,
+ sraw_symbol - coff_data (abfd)->local_symesz,
+ symbol.n_type,
+ symbol.n_sclass,
+ symbol.n_numaux - 1,
+ symbol.n_numaux,
+ &csect_aux);
+ }
+ else
+ csect_aux = main_aux[0];
+
+ /* If symbol name starts with ".$" or "$", ignore it. */
+ if (namestring[0] == '$'
+ || (namestring[0] == '.' && namestring[1] == '$'))
+ break;
+
+ switch (csect_aux.x_csect.x_smtyp & 0x7)
+ {
+ case XTY_SD:
+ switch (csect_aux.x_csect.x_smclas)
+ {
+ case XMC_PR:
+ if (last_csect_name)
+ {
+ /* If no misc. function recorded in the last
+ seen csect, enter it as a function. This
+ will take care of functions like strcmp()
+ compiled by xlc. */
+
+ if (!misc_func_recorded)
+ {
+ RECORD_MINIMAL_SYMBOL
+ (last_csect_name, last_csect_val,
+ mst_text, last_csect_sec,
+ objfile);
+ }
+
+ if (pst != NULL)
+ {
+ /* We have to allocate one psymtab for
+ each program csect, because their text
+ sections need not be adjacent. */
+ xcoff_end_psymtab
+ (pst, psymtab_include_list, includes_used,
+ symnum_before, dependency_list,
+ dependencies_used, textlow_not_set);
+ includes_used = 0;
+ dependencies_used = 0;
+ /* Give all psymtabs for this source file the same
+ name. */
+ pst = xcoff_start_psymtab
+ (objfile,
+ filestring,
+ symnum_before,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+ }
+ /* Activate the misc_func_recorded mechanism for
+ compiler- and linker-generated CSECTs like ".strcmp"
+ and "@FIX1". */
+ if (namestring && (namestring[0] == '.'
+ || namestring[0] == '@'))
+ {
+ last_csect_name = namestring;
+ last_csect_val = symbol.n_value;
+ last_csect_sec =
+ secnum_to_section (symbol.n_scnum, objfile);
+ }
+ if (pst != NULL)
+ {
+ CORE_ADDR highval =
+ symbol.n_value + csect_aux.x_csect.x_scnlen.l;
+ if (highval > pst->texthigh)
+ pst->texthigh = highval;
+ if (pst->textlow == 0 || symbol.n_value < pst->textlow)
+ pst->textlow = symbol.n_value;
+ }
+ misc_func_recorded = 0;
+ break;
+
+ case XMC_RW:
+ /* Data variables are recorded in the minimal symbol
+ table, except for section symbols. */
+ if (*namestring != '.')
+ prim_record_minimal_symbol_and_info
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_data : mst_data,
+ NULL, secnum_to_section (symbol.n_scnum, objfile),
+ NULL, objfile);
+ break;
+
+ case XMC_TC0:
+ if (toc_offset)
+ warning ("More than one XMC_TC0 symbol found.");
+ toc_offset = symbol.n_value;
+
+ /* Make TOC offset relative to start address of section. */
+ bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile);
+ if (bfd_sect)
+ toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect);
+ break;
+
+ case XMC_TC:
+ /* These symbols tell us where the TOC entry for a
+ variable is, not the variable itself. */
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case XTY_LD:
+ switch (csect_aux.x_csect.x_smclas)
+ {
+ case XMC_PR:
+ /* A function entry point. */
+
+ if (first_fun_line_offset == 0 && symbol.n_numaux > 1)
+ first_fun_line_offset =
+ main_aux[0].x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ RECORD_MINIMAL_SYMBOL
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_text : mst_text,
+ secnum_to_section (symbol.n_scnum, objfile),
+ objfile);
+ break;
+
+ case XMC_GL:
+ /* shared library function trampoline code entry
+ point. */
+
+ /* record trampoline code entries as
+ mst_solib_trampoline symbol. When we lookup mst
+ symbols, we will choose mst_text over
+ mst_solib_trampoline. */
+ RECORD_MINIMAL_SYMBOL
+ (namestring, symbol.n_value,
+ mst_solib_trampoline,
+ secnum_to_section (symbol.n_scnum, objfile),
+ objfile);
+ break;
+
+ case XMC_DS:
+ /* The symbols often have the same names as
+ debug symbols for functions, and confuse
+ lookup_symbol. */
+ break;
+
+ default:
+
+ /* xlc puts each variable in a separate csect,
+ so we get an XTY_SD for each variable. But
+ gcc puts several variables in a csect, so
+ that each variable only gets an XTY_LD. We
+ still need to record them. This will
+ typically be XMC_RW; I suspect XMC_RO and
+ XMC_BS might be possible too. */
+ if (*namestring != '.')
+ prim_record_minimal_symbol_and_info
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_data : mst_data,
+ NULL, secnum_to_section (symbol.n_scnum, objfile),
+ NULL, objfile);
+ break;
+ }
+ break;
+
+ case XTY_CM:
+ switch (csect_aux.x_csect.x_smclas)
+ {
+ case XMC_RW:
+ case XMC_BS:
+ /* Common variables are recorded in the minimal symbol
+ table, except for section symbols. */
+ if (*namestring != '.')
+ prim_record_minimal_symbol_and_info
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_bss : mst_bss,
+ NULL, secnum_to_section (symbol.n_scnum, objfile),
+ NULL, objfile);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+ case C_FILE:
+ {
+ unsigned int symnum_before;
+
+ symnum_before = ssymnum;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ /* See if the last csect needs to be recorded. */
+
+ if (last_csect_name && !misc_func_recorded)
+ {
+
+ /* If no misc. function recorded in the last seen csect, enter
+ it as a function. This will take care of functions like
+ strcmp() compiled by xlc. */
+
+ RECORD_MINIMAL_SYMBOL
+ (last_csect_name, last_csect_val,
+ mst_text, last_csect_sec, objfile);
+ }
+
+ if (pst)
+ {
+ xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum_before, dependency_list,
+ dependencies_used, textlow_not_set);
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ first_fun_line_offset = 0;
+
+ /* XCOFF, according to the AIX 3.2 documentation, puts the
+ filename in cs->c_name. But xlc 1.3.0.2 has decided to
+ do things the standard COFF way and put it in the auxent.
+ We use the auxent if the symbol is ".file" and an auxent
+ exists, otherwise use the symbol itself. */
+ if (!strcmp (namestring, ".file") && symbol.n_numaux > 0)
+ {
+ filestring = coff_getfilename (&main_aux[0], objfile);
+ }
+ else
+ filestring = namestring;
+
+ pst = xcoff_start_psymtab (objfile,
+ filestring,
+ symnum_before,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ last_csect_name = NULL;
+ }
+ break;
+
+ default:
+ {
+ static struct complaint msg =
+ {"Storage class %d not recognized during scan", 0, 0};
+ complain (&msg, sclass);
+ }
+ /* FALLTHROUGH */
+
+ /* C_FCN is .bf and .ef symbols. I think it is sufficient
+ to handle only the C_FUN and C_EXT. */
+ case C_FCN:
+
+ case C_BSTAT:
+ case C_ESTAT:
+ case C_ARG:
+ case C_REGPARM:
+ case C_REG:
+ case C_TPDEF:
+ case C_STRTAG:
+ case C_UNTAG:
+ case C_ENTAG:
+ case C_LABEL:
+ case C_NULL:
+
+ /* C_EINCL means we are switching back to the main file. But there
+ is no reason to care; the only thing we want to know about
+ includes is the names of all the included (.h) files. */
+ case C_EINCL:
+
+ case C_BLOCK:
+
+ /* I don't think C_STAT is used in xcoff; C_HIDEXT appears to be
+ used instead. */
+ case C_STAT:
+
+ /* I don't think the name of the common block (as opposed to the
+ variables within it) is something which is user visible
+ currently. */
+ case C_BCOMM:
+ case C_ECOMM:
+
+ case C_PSYM:
+ case C_RPSYM:
+
+ /* I think we can ignore C_LSYM; types on xcoff seem to use C_DECL
+ so C_LSYM would appear to be only for locals. */
+ case C_LSYM:
+
+ case C_AUTO:
+ case C_RSYM:
+ {
+ /* We probably could save a few instructions by assuming that
+ C_LSYM, C_PSYM, etc., never have auxents. */
+ int naux1 = symbol.n_numaux + 1;
+ ssymnum += naux1;
+ sraw_symbol += bfd_coff_symesz (abfd) * naux1;
+ }
+ break;
+
+ case C_BINCL:
+ stype = N_SOL;
+ goto pstab;
+
+ case C_FUN:
+ /* The value of the C_FUN is not the address of the function (it
+ appears to be the address before linking), but as long as it
+ is smaller than the actual address, then find_pc_partial_function
+ will use the minimal symbols instead. I hope. */
+
+ case C_GSYM:
+ case C_ECOML:
+ case C_DECL:
+ case C_STSYM:
+ stype = N_LSYM;
+ pstab:
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+#define CUR_SYMBOL_TYPE stype
+#define CUR_SYMBOL_VALUE symbol.n_value
+
+/* START_PSYMTAB and END_PSYMTAB are never used, because they are only
+ called from DBXREAD_ONLY or N_SO code. Likewise for the symnum
+ variable. */
+#define START_PSYMTAB(ofile,fname,low,symoff,global_syms,static_syms) 0
+#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set)\
+ do {} while (0)
+/* We have already set the namestring. */
+#define SET_NAMESTRING() /* */
+
+#include "partial-stab.h"
+ }
+ }
+
+ if (pst)
+ {
+ xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+ ssymnum, dependency_list,
+ dependencies_used, textlow_not_set);
+ }
+
+ /* Record the toc offset value of this symbol table into objfile structure.
+ If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain
+ this information would be file auxiliary header. */
+
+ ((struct coff_symfile_info *) objfile->sym_private)->toc_offset = toc_offset;
+}
+
+/* Return the toc offset value for a given objfile. */
+
+CORE_ADDR
+get_toc_offset (struct objfile *objfile)
+{
+ if (objfile)
+ return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset;
+ return 0;
+}
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to dbx_symfile_init, which
+ put all the relevant info into a "struct dbx_symfile_info",
+ hung off the objfile structure.
+
+ SECTION_OFFSETS contains offsets relative to which the symbols in the
+ various sections are (depending where the sections were actually loaded).
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file). */