/* Read coff symbol tables and convert to internal format, for GDB.
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "symtab.h"
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "libcoff.h" /* FIXME secret internal data from BFD */
-
-#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "gdb-stabs.h"
#include "coff-pe-read.h"
+#include "psymtab.h"
+
extern void _initialize_coffread (void);
struct coff_symfile_info
extern void stabsread_clear_cache (void);
-static struct type *coff_read_struct_type (int, int, int);
+static struct type *coff_read_struct_type (int, int, int,
+ struct objfile *);
static struct type *decode_base_type (struct coff_symbol *,
- unsigned int, union internal_auxent *);
+ unsigned int, union internal_auxent *,
+ struct objfile *);
static struct type *decode_type (struct coff_symbol *, unsigned int,
- union internal_auxent *);
+ union internal_auxent *,
+ struct objfile *);
static struct type *decode_function_type (struct coff_symbol *,
unsigned int,
- union internal_auxent *);
+ union internal_auxent *,
+ struct objfile *);
-static struct type *coff_read_enum_type (int, int, int);
+static struct type *coff_read_enum_type (int, int, int,
+ struct objfile *);
static struct symbol *process_coff_symbol (struct coff_symbol *,
union internal_auxent *,
static void
coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
{
- register struct coff_symfile_info *csi;
+ struct coff_symfile_info *csi;
const char *name;
csi = (struct coff_symfile_info *) csip;
name = bfd_get_section_name (abfd, sectp);
- if (STREQ (name, ".text"))
+ if (strcmp (name, ".text") == 0)
{
csi->textaddr = bfd_section_vma (abfd, sectp);
csi->textsize += bfd_section_size (abfd, sectp);
{
csi->textsize += bfd_section_size (abfd, sectp);
}
- else if (STREQ (name, ".stabstr"))
+ else if (strcmp (name, ".stabstr") == 0)
{
csi->stabstrsect = sectp;
}
find_targ_sec (bfd *abfd, asection *sect, void *obj)
{
struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+
if (sect->target_index == args->targ_index)
*args->resultp = sect;
}
-/* Return the section number (SECT_OFF_*) that CS points to. */
-static int
-cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
+/* Return the bfd_section that CS points to. */
+static struct bfd_section*
+cs_to_bfd_section (struct coff_symbol *cs, struct objfile *objfile)
{
asection *sect = NULL;
struct find_targ_sec_arg args;
- int off = SECT_OFF_TEXT (objfile);
args.targ_index = cs->c_secnum;
args.resultp = §
bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
- if (sect != NULL)
- {
- /* This is the section. Figure out what SECT_OFF_* code it is. */
- if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
- off = SECT_OFF_TEXT (objfile);
- else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
- off = SECT_OFF_DATA (objfile);
- else
- /* Just return the bfd section index. */
- off = sect->index;
- }
- return off;
+ return sect;
+}
+
+/* Return the section number (SECT_OFF_*) that CS points to. */
+static int
+cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
+{
+ asection *sect = cs_to_bfd_section (cs, objfile);
+
+ if (sect == NULL)
+ return SECT_OFF_TEXT (objfile);
+ return sect->index;
}
/* Return the address of the section of a COFF symbol. */
or for associating a new type with the index. */
static struct type **
-coff_lookup_type (register int index)
+coff_lookup_type (int index)
{
if (index >= type_vector_length)
{
static struct type *
coff_alloc_type (int index)
{
- register struct type **type_addr = coff_lookup_type (index);
- register struct type *type = *type_addr;
+ struct type **type_addr = coff_lookup_type (index);
+ struct type *type = *type_addr;
/* If we are referring to a type not known at all yet,
allocate an empty type for it.
this pointer into last_source_file and we put it in
subfiles->name, which end_symtab frees; that's why
it must be malloc'd. */
- savestring (name, strlen (name)),
+ xstrdup (name),
/* We never know the directory name for COFF. */
NULL,
/* The start address is irrelevant, since we set
{
if (last_source_file != NULL)
xfree (last_source_file);
- last_source_file = savestring (name, strlen (name));
+ last_source_file = xstrdup (name);
current_source_start_addr = start_addr;
current_source_end_addr = start_addr + size;
-
- if (current_objfile->ei.entry_point >= current_source_start_addr &&
- current_objfile->ei.entry_point < current_source_end_addr)
- {
- current_objfile->ei.entry_file_lowpc = current_source_start_addr;
- current_objfile->ei.entry_file_highpc = current_source_end_addr;
- }
}
/* Finish the symbol definitions for one main source file,
symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
- if (symtab != NULL)
- free_named_symtabs (symtab->filename);
-
/* Reinitialize for beginning of new file. */
last_source_file = NULL;
}
\f
-static void
-record_minimal_symbol (char *name, CORE_ADDR address,
- enum minimal_symbol_type type, struct objfile *objfile)
+static struct minimal_symbol *
+record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
+ enum minimal_symbol_type type, int section,
+ struct objfile *objfile)
{
+ struct bfd_section *bfd_section;
+
/* We don't want TDESC entry points in the minimal symbol table */
- if (name[0] == '@')
- return;
+ if (cs->c_name[0] == '@')
+ return NULL;
- prim_record_minimal_symbol (name, address, type, objfile);
+ bfd_section = cs_to_bfd_section (cs, objfile);
+ return prim_record_minimal_symbol_and_info (cs->c_name, address, type,
+ section, bfd_section, objfile);
}
\f
/* coff_symfile_init ()
coff_symfile_init (struct objfile *objfile)
{
/* Allocate struct to keep track of stab reading. */
- objfile->sym_stab_info = (struct dbx_symfile_info *)
- xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+ objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *)
+ xmalloc (sizeof (struct dbx_symfile_info));
- memset (objfile->sym_stab_info, 0,
+ memset (objfile->deprecated_sym_stab_info, 0,
sizeof (struct dbx_symfile_info));
/* Allocate struct to keep track of the symfile */
- objfile->sym_private = xmmalloc (objfile->md,
- sizeof (struct coff_symfile_info));
+ objfile->deprecated_sym_private = xmalloc (sizeof (struct coff_symfile_info));
- memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info));
+ memset (objfile->deprecated_sym_private, 0, sizeof (struct coff_symfile_info));
/* COFF objects may be reordered, so set OBJF_REORDERED. If we
find this causes a significant slowdown in gdb then we could
of the line table (minimum and maximum file offset) so that the
mainline code can read the whole thing for efficiency. */
-/* ARGSUSED */
static void
-find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
+find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
{
struct coff_symfile_info *info;
int size, count;
/* Read a symbol file, after initialization by coff_symfile_init. */
-/* ARGSUSED */
static void
-coff_symfile_read (struct objfile *objfile, int mainline)
+coff_symfile_read (struct objfile *objfile, int symfile_flags)
{
struct coff_symfile_info *info;
struct dbx_symfile_info *dbxinfo;
bfd *abfd = objfile->obfd;
coff_data_type *cdata = coff_data (abfd);
char *name = bfd_get_filename (abfd);
- register int val;
+ int val;
unsigned int num_symbols;
int symtab_offset;
int stringtab_offset;
struct cleanup *back_to, *cleanup_minimal_symbols;
int stabstrsize;
- int len;
- char * target;
- info = (struct coff_symfile_info *) objfile->sym_private;
- dbxinfo = objfile->sym_stab_info;
+ info = (struct coff_symfile_info *) objfile->deprecated_sym_private;
+ dbxinfo = objfile->deprecated_sym_stab_info;
symfile_bfd = abfd; /* Kludge for swap routines */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
val = init_lineno (abfd, info->min_lineno_offset,
info->max_lineno_offset - info->min_lineno_offset);
if (val < 0)
- error ("\"%s\": error reading line numbers\n", name);
+ error (_("\"%s\": error reading line numbers."), name);
}
/* Now read the string table, all at once. */
make_cleanup (free_stringtab_cleanup, 0 /*ignore*/);
val = init_stringtab (abfd, stringtab_offset);
if (val < 0)
- error ("\"%s\": can't get string table", name);
+ error (_("\"%s\": can't get string table"), name);
init_minimal_symbol_collection ();
cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
{
if (!info->stabstrsect)
{
- error (("The debugging information in `%s' is corrupted.\n"
- "The file has a `.stabs' section, but no `.stabstr' "
- "section."),
+ error (_("The debugging information in `%s' is corrupted.\n"
+ "The file has a `.stabs' section, but no `.stabstr' section."),
name);
}
stabstrsize = bfd_section_size (abfd, info->stabstrsect);
coffstab_build_psymtabs (objfile,
- mainline,
info->textaddr, info->textsize,
info->stabsects,
info->stabstrsect->filepos, stabstrsize);
}
- if (dwarf2_has_info (abfd))
+ if (dwarf2_has_info (objfile))
{
/* DWARF2 sections. */
- dwarf2_build_psymtabs (objfile, mainline);
+ dwarf2_build_psymtabs (objfile);
+ }
+
+ dwarf2_build_frame_info (objfile);
+
+ /* Try to add separate debug file if no symbols table found. */
+ if (!objfile_has_partial_symbols (objfile))
+ {
+ char *debugfile;
+
+ debugfile = find_separate_debug_file_by_debuglink (objfile);
+
+ if (debugfile)
+ {
+ bfd *abfd = symfile_bfd_open (debugfile);
+
+ symbol_file_add_separate (abfd, symfile_flags, objfile);
+ xfree (debugfile);
+ }
}
do_cleanups (back_to);
static void
coff_symfile_finish (struct objfile *objfile)
{
- if (objfile->sym_private != NULL)
+ if (objfile->deprecated_sym_private != NULL)
{
- xmfree (objfile->md, objfile->sym_private);
+ xfree (objfile->deprecated_sym_private);
}
/* Let stabs reader clean up */
stabsread_clear_cache ();
+
+ dwarf2_free_objfile (objfile);
}
\f
coff_symtab_read (long symtab_offset, unsigned int nsyms,
struct objfile *objfile)
{
- register struct context_stack *new;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct context_stack *new;
struct coff_symbol coff_symbol;
- register struct coff_symbol *cs = &coff_symbol;
+ struct coff_symbol *cs = &coff_symbol;
static struct internal_syment main_sym;
static union internal_auxent main_aux;
struct coff_symbol fcn_cs_saved;
long fcn_line_ptr = 0;
int val;
CORE_ADDR tmpaddr;
+ struct minimal_symbol *msym;
/* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
it's hard to know I've really worked around it. The fix should be
coff_end_symtab (objfile);
coff_start_symtab ("_globals_");
+ /* coff_start_symtab will set the language of this symtab to
+ language_unknown, since such a ``file name'' is not
+ recognized. Override that with the minimal language to
+ allow printing values in this symtab. */
+ current_subfile->language = language_minimal;
complete_symtab ("_globals_", 0, 0);
/* done with all files, everything from here on out is globals */
}
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
/* Record all functions -- external and static -- in minsyms. */
+ int section = cs_to_section (cs, objfile);
+
tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile);
+ record_minimal_symbol (cs, tmpaddr, mst_text, section, objfile);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = tmpaddr;
case C_LINE:
case C_ALIAS:
case C_HIDDEN:
- complaint (&symfile_complaints, "Bad n_sclass for symbol %s",
+ complaint (&symfile_complaints, _("Bad n_sclass for symbol %s"),
cs->c_name);
break;
case C_THUMBSTATFUNC:
if (cs->c_name[0] == '.')
{
- if (STREQ (cs->c_name, ".text"))
+ if (strcmp (cs->c_name, ".text") == 0)
{
/* FIXME: don't wire in ".text" as section name
or symbol name! */
/* This is a common symbol. See if the target
environment knows where it has been relocated to. */
CORE_ADDR reladdr;
+
if (target_lookup_symbol (cs->c_name, &reladdr))
{
/* Error in lookup; ignore symbol. */
}
else
{
+ asection *bfd_section = cs_to_bfd_section (cs, objfile);
+
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
/* Statics in a PE file also get relocated */
|| (pe_file && (cs->c_sclass == C_STAT)))
tmpaddr += ANOFFSET (objfile->section_offsets, sec);
- if (sec == SECT_OFF_TEXT (objfile))
+ if (bfd_section->flags & SEC_CODE)
{
ms_type =
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT ?
mst_text : mst_file_text;
- tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
+ tmpaddr = gdbarch_smash_text_address (gdbarch, tmpaddr);
}
- else if (sec == SECT_OFF_DATA (objfile))
+ else if (bfd_section->flags & SEC_ALLOC
+ && bfd_section->flags & SEC_LOAD)
{
ms_type =
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
mst_data : mst_file_data;
}
- else if (sec == SECT_OFF_BSS (objfile))
+ else if (bfd_section->flags & SEC_ALLOC)
{
ms_type =
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
- mst_data : mst_file_data;
+ mst_bss : mst_file_bss;
}
else
ms_type = mst_unknown;
}
- if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
- {
- struct minimal_symbol *msym;
-
- /* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
- -> (void*) cast is to ensure that that the value of
- cs->c_sclass can be correctly stored in a void
- pointer in MSYMBOL_INFO. Better solutions
- welcome. */
- gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
- msym = prim_record_minimal_symbol_and_info
- (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
- sec, NULL, objfile);
- if (msym)
- COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
- }
+ msym = record_minimal_symbol (cs, tmpaddr, ms_type, sec, objfile);
+ if (msym)
+ gdbarch_coff_make_msymbol_special (gdbarch, cs->c_sclass, msym);
+
if (SDB_TYPE (cs->c_type))
{
struct symbol *sym;
+
sym = process_coff_symbol
(cs, &main_aux, objfile);
SYMBOL_VALUE (sym) = tmpaddr;
break;
case C_FCN:
- if (STREQ (cs->c_name, ".bf"))
+ if (strcmp (cs->c_name, ".bf") == 0)
{
within_function = 1;
contains line number of '{' } */
if (cs->c_naux != 1)
complaint (&symfile_complaints,
- "`.bf' symbol %d has no aux entry", cs->c_symnum);
+ _("`.bf' symbol %d has no aux entry"), cs->c_symnum);
fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
fcn_first_line_addr = cs->c_value;
new->name =
process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
}
- else if (STREQ (cs->c_name, ".ef"))
+ else if (strcmp (cs->c_name, ".ef") == 0)
{
if (!within_function)
- error ("Bad coff function information\n");
+ error (_("Bad coff function information."));
/* the value of .ef is the address of epilogue code;
not useful for gdb. */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */
complaint (&symfile_complaints,
- "`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d",
+ _("`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d"),
cs->c_symnum);
within_function = 0;
break;
if (context_stack_depth > 0 || new == NULL)
{
complaint (&symfile_complaints,
- "Unmatched .ef symbol(s) ignored starting at symnum %d",
+ _("Unmatched .ef symbol(s) ignored starting at symnum %d"),
cs->c_symnum);
within_function = 0;
break;
if (cs->c_naux != 1)
{
complaint (&symfile_complaints,
- "`.ef' symbol %d has no aux entry", cs->c_symnum);
+ _("`.ef' symbol %d has no aux entry"), cs->c_symnum);
fcn_last_line = 0x7FFFFFFF;
}
else
for which we do not have any other statement-line-number. */
if (fcn_last_line == 1)
record_line (current_subfile, fcn_first_line,
- fcn_first_line_addr);
+ gdbarch_addr_bits_remove (gdbarch,
+ fcn_first_line_addr));
else
enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
objfile);
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr,
-#if defined (FUNCTION_EPILOGUE_SIZE)
- /* This macro should be defined only on
- machines where the
- fcn_aux_saved.x_sym.x_misc.x_fsize
- field is always zero.
- So use the .bf record information that
- points to the epilogue and add the size
- of the epilogue. */
- cs->c_value
- + FUNCTION_EPILOGUE_SIZE
- + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
-#else
fcn_cs_saved.c_value
+ fcn_aux_saved.x_sym.x_misc.x_fsize
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
-#endif
objfile
);
within_function = 0;
break;
case C_BLOCK:
- if (STREQ (cs->c_name, ".bb"))
+ if (strcmp (cs->c_name, ".bb") == 0)
{
tmpaddr = cs->c_value;
tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
push_context (++depth, tmpaddr);
}
- else if (STREQ (cs->c_name, ".eb"))
+ else if (strcmp (cs->c_name, ".eb") == 0)
{
if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */
complaint (&symfile_complaints,
- "`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d",
+ _("`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d"),
cs->c_symnum);
break;
}
if (depth-- != new->depth)
{
complaint (&symfile_complaints,
- "Mismatched .eb symbol ignored starting at symnum %d",
+ _("Mismatched .eb symbol ignored starting at symnum %d"),
symnum);
break;
}
if ((nsyms == 0) && (pe_file))
{
- /* We've got no debugging symbols, but it's is a portable
+ /* We've got no debugging symbols, but it's a portable
executable, so try to read the export table */
read_pe_exported_syms (objfile);
}
in internal_auxent form, and skip any other auxents. */
static void
-read_one_sym (register struct coff_symbol *cs,
- register struct internal_syment *sym,
- register union internal_auxent *aux)
+read_one_sym (struct coff_symbol *cs,
+ struct internal_syment *sym,
+ union internal_auxent *aux)
{
int i;
+ bfd_size_type bytes;
cs->c_symnum = symnum;
- bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+ bytes = bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+ if (bytes != local_symesz)
+ error ("%s: error reading symbols", current_objfile->name);
bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
cs->c_naux = sym->n_numaux & 0xff;
if (cs->c_naux >= 1)
{
- bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ if (bytes != local_auxesz)
+ error ("%s: error reading symbols", current_objfile->name);
bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
0, cs->c_naux, (char *) aux);
/* If more than one aux entry, read past it (only the first aux
is important). */
for (i = 1; i < cs->c_naux; i++)
- bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ {
+ bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ if (bytes != local_auxesz)
+ error ("%s: error reading symbols", current_objfile->name);
+ }
}
cs->c_name = getsymname (sym);
cs->c_value = sym->n_value;
#if 0
if (cs->c_sclass & 128)
- printf ("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
+ printf (_("thumb symbol %s, class 0x%x\n"), cs->c_name, cs->c_sclass);
#endif
symnum += 1 + cs->c_naux;
coff_getfilename (union internal_auxent *aux_entry)
{
static char buffer[BUFSIZ];
- register char *temp;
+ char *temp;
char *result;
if (aux_entry->x_file.x_n.x_zeroes == 0)
#endif
static void
-enter_linenos (long file_offset, register int first_line,
- register int last_line, struct objfile *objfile)
+enter_linenos (long file_offset, int first_line,
+ int last_line, struct objfile *objfile)
{
- register char *rawptr;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ char *rawptr;
struct internal_lineno lptr;
if (!linetab)
if (file_offset < linetab_offset)
{
complaint (&symfile_complaints,
- "Line number pointer %ld lower than start of line numbers",
+ _("Line number pointer %ld lower than start of line numbers"),
file_offset);
if (file_offset > linetab_size) /* Too big to be an offset? */
return;
/* line numbers start at one for the first line of the function */
first_line--;
- for (;;)
+ /* If the line number table is full (e.g. 64K lines in COFF debug
+ info), the next function's L_LNNO32 might not be zero, so don't
+ overstep the table's end in any case. */
+ while (rawptr <= &linetab[0] + linetab_size)
{
bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
rawptr += local_linesz;
- /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
+ /* The next function, or the sentinel, will have L_LNNO32 zero;
+ we exit. */
if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
- record_line (current_subfile, first_line + L_LNNO32 (&lptr),
- lptr.l_addr.l_paddr
- + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)));
+ {
+ CORE_ADDR addr = lptr.l_addr.l_paddr;
+ addr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ record_line (current_subfile, first_line + L_LNNO32 (&lptr),
+ gdbarch_addr_bits_remove (gdbarch, addr));
+ }
else
break;
}
static void
patch_type (struct type *type, struct type *real_type)
{
- register struct type *target = TYPE_TARGET_TYPE (type);
- register struct type *real_target = TYPE_TARGET_TYPE (real_type);
+ struct type *target = TYPE_TARGET_TYPE (type);
+ struct type *real_target = TYPE_TARGET_TYPE (real_type);
int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
{
if (TYPE_NAME (target))
xfree (TYPE_NAME (target));
- TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);
+ TYPE_NAME (target) = concat (TYPE_NAME (real_target), (char *)NULL);
}
}
static void
patch_opaque_types (struct symtab *s)
{
- register struct block *b;
+ struct block *b;
struct dict_iterator iter;
- register struct symbol *real_sym;
+ struct symbol *real_sym;
/* Go through the per-file symbols only */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
Remove syms from the chain when their types are stored,
but search the whole chain, as there may be several syms
from different files with the same name. */
- if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
- SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN &&
- TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
+ if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF
+ && SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN
+ && TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
{
- register char *name = DEPRECATED_SYMBOL_NAME (real_sym);
- register int hash = hashname (name);
- register struct symbol *sym, *prev;
+ char *name = SYMBOL_LINKAGE_NAME (real_sym);
+ int hash = hashname (name);
+ struct symbol *sym, *prev;
prev = 0;
for (sym = opaque_type_chain[hash]; sym;)
{
- if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
- STREQ (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1))
+ if (name[0] == SYMBOL_LINKAGE_NAME (sym)[0]
+ && strcmp (name + 1, SYMBOL_LINKAGE_NAME (sym) + 1) == 0)
{
if (prev)
{
}
}
\f
+static int
+coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+ return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops coff_register_funcs = {
+ coff_reg_to_regnum
+};
+
static struct symbol *
-process_coff_symbol (register struct coff_symbol *cs,
- register union internal_auxent *aux,
+process_coff_symbol (struct coff_symbol *cs,
+ union internal_auxent *aux,
struct objfile *objfile)
{
- register struct symbol *sym
- = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
- sizeof (struct symbol));
+ struct symbol *sym
+ = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct symbol));
char *name;
memset (sym, 0, sizeof (struct symbol));
name = cs->c_name;
name = EXTERNAL_NAME (name, objfile->obfd);
- SYMBOL_LANGUAGE (sym) = language_auto;
- SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
+ SYMBOL_SET_LANGUAGE (sym, current_subfile->language);
+ SYMBOL_SET_NAMES (sym, name, strlen (name), 1, objfile);
/* default assumptions */
SYMBOL_VALUE (sym) = cs->c_value;
{
SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
SYMBOL_TYPE (sym) =
- lookup_function_type (decode_function_type (cs, cs->c_type, aux));
+ lookup_function_type (decode_function_type (cs, cs->c_type, aux, objfile));
SYMBOL_CLASS (sym) = LOC_BLOCK;
if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
}
else
{
- SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
+ SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux, objfile);
switch (cs->c_sclass)
{
case C_NULL:
#endif
case C_REG:
SYMBOL_CLASS (sym) = LOC_REGISTER;
- SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+ SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+ SYMBOL_VALUE (sym) = cs->c_value;
add_symbol_to_list (sym, &local_symbols);
break;
case C_ARG:
SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_IS_ARGUMENT (sym) = 1;
add_symbol_to_list (sym, &local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- {
- /* If PCC says a parameter is a short or a char,
- aligned on an int boundary, realign it to the
- "little end" of the int. */
- struct type *temptype;
- temptype = lookup_fundamental_type (current_objfile,
- FT_INTEGER);
- if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
- && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
- && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
- {
- SYMBOL_VALUE (sym) +=
- TYPE_LENGTH (temptype)
- - TYPE_LENGTH (SYMBOL_TYPE (sym));
- }
- }
-#endif
break;
case C_REGPARM:
- SYMBOL_CLASS (sym) = LOC_REGPARM;
- SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+ SYMBOL_IS_ARGUMENT (sym) = 1;
+ SYMBOL_VALUE (sym) = cs->c_value;
add_symbol_to_list (sym, &local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
- /* FIXME: This should retain the current type, since it's just
- a register value. gnu@adobe, 26Feb93 */
- {
- /* If PCC says a parameter is a short or a char,
- it is really an int. */
- struct type *temptype;
- temptype =
- lookup_fundamental_type (current_objfile, FT_INTEGER);
- if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
- && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
- {
- SYMBOL_TYPE (sym) =
- (TYPE_UNSIGNED (SYMBOL_TYPE (sym))
- ? lookup_fundamental_type (current_objfile,
- FT_UNSIGNED_INTEGER)
- : temptype);
- }
- }
-#endif
break;
case C_TPDEF:
}
else
TYPE_NAME (SYMBOL_TYPE (sym)) =
- concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
+ concat (SYMBOL_LINKAGE_NAME (sym), (char *)NULL);
}
-#ifdef CXUX_TARGET
- /* Ignore vendor section for Harris CX/UX targets. */
- else if (cs->c_name[0] == '$')
- break;
-#endif /* CXUX_TARGET */
/* Keep track of any type which points to empty structured type,
so it can be filled from a definition from another file. A
simple forward reference (TYPE_CODE_UNDEF) is not an
empty structured type, though; the forward references
work themselves out via the magic of coff_lookup_type. */
- if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
- TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
- TYPE_CODE_UNDEF)
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0
+ && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym)))
+ != TYPE_CODE_UNDEF)
{
- register int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
+ int i = hashname (SYMBOL_LINKAGE_NAME (sym));
SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
opaque_type_chain[i] = sym;
names for anonymous enums, structures, and unions, like
"~0fake" or ".0fake". Thanks, but no thanks... */
if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
- if (DEPRECATED_SYMBOL_NAME (sym) != NULL
- && *DEPRECATED_SYMBOL_NAME (sym) != '~'
- && *DEPRECATED_SYMBOL_NAME (sym) != '.')
+ if (SYMBOL_LINKAGE_NAME (sym) != NULL
+ && *SYMBOL_LINKAGE_NAME (sym) != '~'
+ && *SYMBOL_LINKAGE_NAME (sym) != '.')
TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
- concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
+ concat (SYMBOL_LINKAGE_NAME (sym), (char *)NULL);
add_symbol_to_list (sym, &file_symbols);
break;
/* Decode a coff type specifier; return the type that is meant. */
static struct type *
-decode_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux, struct objfile *objfile)
{
- register struct type *type = 0;
+ struct type *type = 0;
unsigned int new_c_type;
if (c_type & ~N_BTMASK)
new_c_type = DECREF (c_type);
if (ISPTR (c_type))
{
- type = decode_type (cs, new_c_type, aux);
+ type = decode_type (cs, new_c_type, aux, objfile);
type = lookup_pointer_type (type);
}
else if (ISFCN (c_type))
{
- type = decode_type (cs, new_c_type, aux);
+ type = decode_type (cs, new_c_type, aux, objfile);
type = lookup_function_type (type);
}
else if (ISARY (c_type))
{
int i, n;
- register unsigned short *dim;
+ unsigned short *dim;
struct type *base_type, *index_type, *range_type;
/* Define an array type. */
*dim = *(dim + 1);
*dim = 0;
- base_type = decode_type (cs, new_c_type, aux);
- index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+ base_type = decode_type (cs, new_c_type, aux, objfile);
+ index_type = objfile_type (objfile)->builtin_int;
range_type =
create_range_type ((struct type *) NULL, index_type, 0, n - 1);
type =
else
{
complaint (&symfile_complaints,
- "Symbol table entry for %s has bad tagndx value",
+ _("Symbol table entry for %s has bad tagndx value"),
cs->c_name);
/* And fall through to decode_base_type... */
}
}
- return decode_base_type (cs, BTYPE (c_type), aux);
+ return decode_base_type (cs, BTYPE (c_type), aux, objfile);
}
/* Decode a coff type specifier for function definition;
return the type that the function returns. */
static struct type *
-decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_function_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux, struct objfile *objfile)
{
if (aux->x_sym.x_tagndx.l == 0)
cs->c_naux = 0; /* auxent refers to function, not base type */
- return decode_type (cs, DECREF (c_type), aux);
+ return decode_type (cs, DECREF (c_type), aux, objfile);
}
\f
/* basic C types */
static struct type *
-decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_base_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux, struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type;
switch (c_type)
{
case T_NULL:
/* shows up with "void (*foo)();" structure members */
- return lookup_fundamental_type (current_objfile, FT_VOID);
-
-#if 0
-/* DGUX actually defines both T_ARG and T_VOID to the same value. */
-#ifdef T_ARG
- case T_ARG:
- /* Shows up in DGUX, I think. Not sure where. */
- return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */
-#endif
-#endif /* 0 */
+ return objfile_type (objfile)->builtin_void;
#ifdef T_VOID
case T_VOID:
/* Intel 960 COFF has this symbol and meaning. */
- return lookup_fundamental_type (current_objfile, FT_VOID);
+ return objfile_type (objfile)->builtin_void;
#endif
case T_CHAR:
- return lookup_fundamental_type (current_objfile, FT_CHAR);
+ return objfile_type (objfile)->builtin_char;
case T_SHORT:
- return lookup_fundamental_type (current_objfile, FT_SHORT);
+ return objfile_type (objfile)->builtin_short;
case T_INT:
- return lookup_fundamental_type (current_objfile, FT_INTEGER);
+ return objfile_type (objfile)->builtin_int;
case T_LONG:
if (cs->c_sclass == C_FIELD
- && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
- return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+ && aux->x_sym.x_misc.x_lnsz.x_size
+ > gdbarch_long_bit (gdbarch))
+ return objfile_type (objfile)->builtin_long_long;
else
- return lookup_fundamental_type (current_objfile, FT_LONG);
+ return objfile_type (objfile)->builtin_long;
case T_FLOAT:
- return lookup_fundamental_type (current_objfile, FT_FLOAT);
+ return objfile_type (objfile)->builtin_float;
case T_DOUBLE:
- return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+ return objfile_type (objfile)->builtin_double;
case T_LNGDBL:
- return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+ return objfile_type (objfile)->builtin_long_double;
case T_STRUCT:
if (cs->c_naux != 1)
{
type = coff_read_struct_type (cs->c_symnum,
aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ objfile);
}
return type;
{
type = coff_read_struct_type (cs->c_symnum,
aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ objfile);
}
TYPE_CODE (type) = TYPE_CODE_UNION;
return type;
{
type = coff_read_enum_type (cs->c_symnum,
aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ objfile);
}
return type;
break;
case T_UCHAR:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+ return objfile_type (objfile)->builtin_unsigned_char;
case T_USHORT:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+ return objfile_type (objfile)->builtin_unsigned_short;
case T_UINT:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+ return objfile_type (objfile)->builtin_unsigned_int;
case T_ULONG:
if (cs->c_sclass == C_FIELD
- && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+ && aux->x_sym.x_misc.x_lnsz.x_size
+ > gdbarch_long_bit (gdbarch))
+ return objfile_type (objfile)->builtin_unsigned_long_long;
else
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+ return objfile_type (objfile)->builtin_unsigned_long;
}
- complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name);
- return lookup_fundamental_type (current_objfile, FT_VOID);
+ complaint (&symfile_complaints, _("Unexpected type for symbol %s"), cs->c_name);
+ return objfile_type (objfile)->builtin_void;
}
\f
/* This page contains subroutines of read_type. */
object describing the type. */
static struct type *
-coff_read_struct_type (int index, int length, int lastsym)
+coff_read_struct_type (int index, int length, int lastsym,
+ struct objfile *objfile)
{
struct nextfield
{
struct field field;
};
- register struct type *type;
- register struct nextfield *list = 0;
+ struct type *type;
+ struct nextfield *list = 0;
struct nextfield *new;
int nfields = 0;
- register int n;
+ int n;
char *name;
struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
+ struct coff_symbol *ms = &member_sym;
struct internal_syment sub_sym;
union internal_auxent sub_aux;
int done = 0;
{
read_one_sym (ms, &sub_sym, &sub_aux);
name = ms->c_name;
- name = EXTERNAL_NAME (name, current_objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd);
switch (ms->c_sclass)
{
/* Save the data. */
list->field.name =
- obsavestring (name,
- strlen (name),
- ¤t_objfile->symbol_obstack);
- FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
- FIELD_BITPOS (list->field) = 8 * ms->c_value;
+ obsavestring (name, strlen (name), &objfile->objfile_obstack);
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux,
+ objfile);
+ SET_FIELD_BITPOS (list->field, 8 * ms->c_value);
FIELD_BITSIZE (list->field) = 0;
- FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;
/* Save the data. */
list->field.name =
- obsavestring (name,
- strlen (name),
- ¤t_objfile->symbol_obstack);
- FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
- FIELD_BITPOS (list->field) = ms->c_value;
+ obsavestring (name, strlen (name), &objfile->objfile_obstack);
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux,
+ objfile);
+ SET_FIELD_BITPOS (list->field, ms->c_value);
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
- FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;
and create and return a suitable type object.
Also defines the symbols that represent the values of the type. */
-/* ARGSUSED */
static struct type *
-coff_read_enum_type (int index, int length, int lastsym)
+coff_read_enum_type (int index, int length, int lastsym,
+ struct objfile *objfile)
{
- register struct symbol *sym;
- register struct type *type;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct symbol *sym;
+ struct type *type;
int nsyms = 0;
int done = 0;
struct pending **symlist;
struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
+ struct coff_symbol *ms = &member_sym;
struct internal_syment sub_sym;
union internal_auxent sub_aux;
struct pending *osyms, *syms;
int o_nsyms;
- register int n;
+ int n;
char *name;
int unsigned_enum = 1;
{
read_one_sym (ms, &sub_sym, &sub_aux);
name = ms->c_name;
- name = EXTERNAL_NAME (name, current_objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd);
switch (ms->c_sclass)
{
case C_MOE:
sym = (struct symbol *) obstack_alloc
- (¤t_objfile->symbol_obstack,
- sizeof (struct symbol));
+ (&objfile->objfile_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
- DEPRECATED_SYMBOL_NAME (sym) =
- obsavestring (name, strlen (name),
- ¤t_objfile->symbol_obstack);
+ SYMBOL_SET_LINKAGE_NAME (sym,
+ obsavestring (name, strlen (name),
+ &objfile->objfile_obstack));
SYMBOL_CLASS (sym) = LOC_CONST;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_VALUE (sym) = ms->c_value;
if (length > 0)
TYPE_LENGTH (type) = length;
- else
- TYPE_LENGTH (type) = TARGET_INT_BIT / TARGET_CHAR_BIT; /* Assume ints */
+ else /* Assume ints. */
+ TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_NFIELDS (type) = nsyms;
TYPE_FIELDS (type) = (struct field *)
for (; j < syms->nsyms; j++, n++)
{
struct symbol *xsym = syms->symbol[j];
+
SYMBOL_TYPE (xsym) = type;
- TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
- TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ TYPE_FIELD_NAME (type, n) = SYMBOL_LINKAGE_NAME (xsym);
+ SET_FIELD_BITPOS (TYPE_FIELD (type, n), SYMBOL_VALUE (xsym));
if (SYMBOL_VALUE (xsym) < 0)
unsigned_enum = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
- TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
if (syms == osyms)
break;
}
if (unsigned_enum)
- TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_UNSIGNED (type) = 1;
return type;
}
coff_symfile_read, /* sym_read: read a symbol file into symtab */
coff_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
+ NULL, /* sym_read_linetable */
+ default_symfile_relocate, /* sym_relocate: Relocate a debug section. */
+ &psym_functions,
NULL /* next: pointer to next struct sym_fns */
};