+swap_sym (struct internal_syment *symbol, union internal_auxent *aux,
+ char **name, char **raw, unsigned int *symnump,
+ struct objfile *objfile)
+{
+ bfd_coff_swap_sym_in (objfile->obfd, *raw, symbol);
+ if (symbol->n_zeroes)
+ {
+ /* If it's exactly E_SYMNMLEN characters long it isn't
+ '\0'-terminated. */
+ if (symbol->n_name[E_SYMNMLEN - 1] != '\0')
+ {
+ /* FIXME: wastes memory for symbols which we don't end up putting
+ into the minimal symbols. */
+ char *p;
+ p = obstack_alloc (&objfile->objfile_obstack, E_SYMNMLEN + 1);
+ strncpy (p, symbol->n_name, E_SYMNMLEN);
+ p[E_SYMNMLEN] = '\0';
+ *name = p;
+ }
+ else
+ /* Point to the unswapped name as that persists as long as the
+ objfile does. */
+ *name = ((struct external_syment *) *raw)->e.e_name;
+ }
+ else if (symbol->n_sclass & 0x80)
+ {
+ *name = ((struct coff_symfile_info *) objfile->deprecated_sym_private)->debugsec
+ + symbol->n_offset;
+ }
+ else
+ {
+ *name = ((struct coff_symfile_info *) objfile->deprecated_sym_private)->strtbl
+ + symbol->n_offset;
+ }
+ ++*symnump;
+ *raw += coff_data (objfile->obfd)->local_symesz;
+ if (symbol->n_numaux > 0)
+ {
+ bfd_coff_swap_aux_in (objfile->obfd, *raw, symbol->n_type,
+ symbol->n_sclass, 0, symbol->n_numaux, aux);
+
+ *symnump += symbol->n_numaux;
+ *raw += coff_data (objfile->obfd)->local_symesz * symbol->n_numaux;
+ }
+}
+
+static void
+function_outside_compilation_unit_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints,
+ _("function `%s' appears to be defined outside of all compilation units"),
+ arg1);
+}
+
+static void
+scan_xcoff_symtab (struct objfile *objfile)
+{
+ CORE_ADDR toc_offset = 0; /* toc offset value in data section. */
+ char *filestring = NULL;
+
+ char *namestring;
+ int past_first_source_file = 0;
+ bfd *abfd;
+ asection *bfd_sect;
+ unsigned int nsyms;
+
+ /* Current partial symtab */
+ struct partial_symtab *pst;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ char *sraw_symbol;
+ struct internal_syment symbol;
+ union internal_auxent main_aux[5];
+ unsigned int ssymnum;
+
+ char *last_csect_name = NULL; /* last seen csect's name and value */
+ CORE_ADDR last_csect_val = 0;
+ int last_csect_sec = 0;
+ int misc_func_recorded = 0; /* true if any misc. function */
+ int textlow_not_set = 1;
+
+ pst = (struct partial_symtab *) 0;
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ last_source_file = NULL;
+
+ abfd = objfile->obfd;
+
+ sraw_symbol = ((struct coff_symfile_info *) objfile->deprecated_sym_private)->symtbl;
+ nsyms = ((struct coff_symfile_info *) objfile->deprecated_sym_private)->symtbl_num_syms;
+ ssymnum = 0;
+ while (ssymnum < nsyms)
+ {
+ int sclass;
+
+ QUIT;
+
+ bfd_coff_swap_sym_in (abfd, sraw_symbol, &symbol);
+ sclass = symbol.n_sclass;
+
+ 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:
+ case XMC_TD:
+ /* 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:
+ {
+ complaint (&symfile_complaints,
+ _("Storage class %d not recognized during scan"), 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:
+ {
+ /* Mark down an include file in the current psymtab */
+ enum language tmp_language;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ tmp_language = deduce_language_from_filename (namestring);
+
+ /* Only change the psymtab's language if we've learned
+ something useful (eg. tmp_language is not language_unknown).
+ In addition, to match what start_subfile does, never change
+ from C++ to C. */
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+ /* In C++, one may expect the same filename to come round many
+ times, when code is coming alternately from the main file
+ and from inline functions in other files. So I check to see
+ if this is a file we've seen before -- either the main
+ source file, or a previously included file.
+
+ This seems to be a lot of time to be spending on N_SOL, but
+ things like "break c-exp.y:435" need to work (I
+ suppose the psymtab_include_list could be hashed or put
+ in a binary tree, if profiling shows this is a major hog). */
+ if (pst && DEPRECATED_STREQ (namestring, pst->filename))
+ continue;
+ {
+ int i;
+ for (i = 0; i < includes_used; i++)
+ if (DEPRECATED_STREQ (namestring, psymtab_include_list[i]))
+ {
+ i = -1;
+ break;
+ }
+ if (i == -1)
+ continue;
+ }
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy (psymtab_include_list, orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
+ 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:
+ {
+ char *p;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ p = (char *) strchr (namestring, ':');
+ if (!p)
+ continue; /* Not a debugging symbol. */
+
+ /* Main processing section for debugging symbols which
+ the initial read through the symbol tables needs to worry
+ about. If we reach this point, the symbol which we are
+ considering is definitely one we are interested in.
+ p must also contain the (valid) index into the namestring
+ which indicates the debugging type symbol. */
+
+ switch (p[1])
+ {
+ case 'S':
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+ namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'G':
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ /* The addresses in these entries are reported to be
+ wrong. See the code that reads 'G's for symtabs. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'T':
+ /* When a 'T' entry is defining an anonymous enum, it
+ may have a name which is the empty string, or a
+ single space. Since they're not really defining a
+ symbol, those shouldn't go in the partial symbol
+ table. We do pick up the elements of such enums at
+ 'check_enum:', below. */
+ if (p >= namestring + 2
+ || (p == namestring + 1
+ && namestring[0] != ' '))
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ STRUCT_DOMAIN, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ if (p[2] == 't')
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ p += 1;
+ }
+ }
+ goto check_enum;
+
+ case 't':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ }
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out the
+ enum in a nameless type. GCC2 does this. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e"
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Also, numbers can come
+ in pairs like (0,26). Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '(' || *p == ',' || *p == ')'
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* The aix4 compiler emits extra crud before the members. */
+ if (*p == '-')
+ {
+ /* Skip over the type (?). */
+ while (*p != ':')
+ p++;
+
+ /* Skip over the colon. */
+ p++;
+ }
+
+ /* We have found an enumerated type. */
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation! */
+ if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+ p = next_symbol_text (objfile);
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ add_psymbol_to_list (p, q - p,
+ VAR_DOMAIN, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, psymtab_language, objfile);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+ continue;
+
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_CONST,
+ &objfile->static_psymbols, symbol.n_value,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'f':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ function_outside_compilation_unit_complaint (name);
+ xfree (name);
+ }
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Global functions were ignored here, but now they
+ are put into the global psymtab like one would expect.
+ They're also in the minimal symbol table. */
+ case 'F':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ function_outside_compilation_unit_complaint (name);
+ xfree (name);
+ }
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_DOMAIN, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Two things show up here (hopefully); static symbols of
+ local scope (static used inside braces) or extensions
+ of structure symbols. We can ignore both. */
+ case 'V':
+ case '(':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '#': /* for symbol identification (used in live ranges) */
+ continue;
+
+ case ':':
+ /* It is a C++ nested symbol. We don't need to record it
+ (I don't think); if we try to look up foo::bar::baz,
+ then symbols for the symtab containing foo should get
+ read in, I think. */
+ /* Someone says sun cc puts out symbols like
+ /foo/baz/maclib::/usr/local/bin/maclib,
+ which would get here with a symbol type of ':'. */
+ continue;
+
+ default:
+ /* Unexpected symbol descriptor. The second and subsequent stabs
+ of a continued stab can show up here. The question is
+ whether they ever can mimic a normal stab--it would be
+ nice if not, since we certainly don't want to spend the
+ time searching to the end of every string looking for
+ a backslash. */
+
+ complaint (&symfile_complaints,
+ _("unknown symbol descriptor `%c'"), p[1]);
+
+ /* Ignore it; perhaps it is an extension that we don't
+ know about. */
+ continue;
+ }
+ }
+ }
+ }
+
+ 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->deprecated_sym_private)->toc_offset = toc_offset;
+}
+
+/* Return the toc offset value for a given objfile. */
+
+CORE_ADDR
+get_toc_offset (struct objfile *objfile)