/* Generic symbol-table support for the BFD library.
   Copyright (C) 1990-2023 Free Software Foundation, Inc.
   Written by Cygnus Support.

   This file is part of BFD, the Binary File Descriptor library.

   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 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/*
SECTION
	Symbols

	BFD tries to maintain as much symbol information as it can when
	it moves information from file to file. BFD passes information
	to applications though the <<asymbol>> structure. When the
	application requests the symbol table, BFD reads the table in
	the native form and translates parts of it into the internal
	format. To maintain more than the information passed to
	applications, some targets keep some information ``behind the
	scenes'' in a structure only the particular back end knows
	about. For example, the coff back end keeps the original
	symbol table structure as well as the canonical structure when
	a BFD is read in. On output, the coff back end can reconstruct
	the output symbol table so that no information is lost, even
	information unique to coff which BFD doesn't know or
	understand. If a coff symbol table were read, but were written
	through an a.out back end, all the coff specific information
	would be lost. The symbol table of a BFD
	is not necessarily read in until a canonicalize request is
	made. Then the BFD back end fills in a table provided by the
	application with pointers to the canonical information.  To
	output symbols, the application provides BFD with a table of
	pointers to pointers to <<asymbol>>s. This allows applications
	like the linker to output a symbol as it was read, since the ``behind
	the scenes'' information will be still available.
@menu
@* Reading Symbols::
@* Writing Symbols::
@* Mini Symbols::
@* typedef asymbol::
@* symbol handling functions::
@end menu

INODE
Reading Symbols, Writing Symbols, Symbols, Symbols
SUBSECTION
	Reading symbols

	There are two stages to reading a symbol table from a BFD:
	allocating storage, and the actual reading process. This is an
	excerpt from an application which reads the symbol table:

|         long storage_needed;
|         asymbol **symbol_table;
|         long number_of_symbols;
|         long i;
|
|         storage_needed = bfd_get_symtab_upper_bound (abfd);
|
|         if (storage_needed < 0)
|           FAIL
|
|         if (storage_needed == 0)
|           return;
|
|         symbol_table = xmalloc (storage_needed);
|           ...
|         number_of_symbols =
|            bfd_canonicalize_symtab (abfd, symbol_table);
|
|         if (number_of_symbols < 0)
|           FAIL
|
|         for (i = 0; i < number_of_symbols; i++)
|           process_symbol (symbol_table[i]);

	All storage for the symbols themselves is in an objalloc
	connected to the BFD; it is freed when the BFD is closed.

INODE
Writing Symbols, Mini Symbols, Reading Symbols, Symbols
SUBSECTION
	Writing symbols

	Writing of a symbol table is automatic when a BFD open for
	writing is closed. The application attaches a vector of
	pointers to pointers to symbols to the BFD being written, and
	fills in the symbol count. The close and cleanup code reads
	through the table provided and performs all the necessary
	operations. The BFD output code must always be provided with an
	``owned'' symbol: one which has come from another BFD, or one
	which has been created using <<bfd_make_empty_symbol>>.  Here is an
	example showing the creation of a symbol table with only one element:

|       #include "sysdep.h"
|       #include "bfd.h"
|       int main (void)
|       {
|         bfd *abfd;
|         asymbol *ptrs[2];
|         asymbol *new;
|
|         abfd = bfd_openw ("foo","a.out-sunos-big");
|         bfd_set_format (abfd, bfd_object);
|         new = bfd_make_empty_symbol (abfd);
|         new->name = "dummy_symbol";
|         new->section = bfd_make_section_old_way (abfd, ".text");
|         new->flags = BSF_GLOBAL;
|         new->value = 0x12345;
|
|         ptrs[0] = new;
|         ptrs[1] = 0;
|
|         bfd_set_symtab (abfd, ptrs, 1);
|         bfd_close (abfd);
|         return 0;
|       }
|
|       ./makesym
|       nm foo
|       00012345 A dummy_symbol

	Many formats cannot represent arbitrary symbol information; for
	instance, the <<a.out>> object format does not allow an
	arbitrary number of sections. A symbol pointing to a section
	which is not one  of <<.text>>, <<.data>> or <<.bss>> cannot
	be described.

INODE
Mini Symbols, typedef asymbol, Writing Symbols, Symbols
SUBSECTION
	Mini Symbols

	Mini symbols provide read-only access to the symbol table.
	They use less memory space, but require more time to access.
	They can be useful for tools like nm or objdump, which may
	have to handle symbol tables of extremely large executables.

	The <<bfd_read_minisymbols>> function will read the symbols
	into memory in an internal form.  It will return a <<void *>>
	pointer to a block of memory, a symbol count, and the size of
	each symbol.  The pointer is allocated using <<malloc>>, and
	should be freed by the caller when it is no longer needed.

	The function <<bfd_minisymbol_to_symbol>> will take a pointer
	to a minisymbol, and a pointer to a structure returned by
	<<bfd_make_empty_symbol>>, and return a <<asymbol>> structure.
	The return value may or may not be the same as the value from
	<<bfd_make_empty_symbol>> which was passed in.

*/

/*
DOCDD
INODE
typedef asymbol, symbol handling functions, Mini Symbols, Symbols

*/
/*
SUBSECTION
	typedef asymbol

	An <<asymbol>> has the form:

*/

/*
CODE_FRAGMENT

.
.typedef struct bfd_symbol
.{
.  {* A pointer to the BFD which owns the symbol. This information
.     is necessary so that a back end can work out what additional
.     information (invisible to the application writer) is carried
.     with the symbol.
.
.     This field is *almost* redundant, since you can use section->owner
.     instead, except that some symbols point to the global sections
.     bfd_{abs,com,und}_section.  This could be fixed by making
.     these globals be per-bfd (or per-target-flavor).  FIXME.  *}
.  struct bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field.  *}
.
.  {* The text of the symbol. The name is left alone, and not copied; the
.     application may not alter it.  *}
.  const char *name;
.
.  {* The value of the symbol.  This really should be a union of a
.     numeric value with a pointer, since some flags indicate that
.     a pointer to another symbol is stored here.  *}
.  symvalue value;
.
.  {* Attributes of a symbol.  *}
.#define BSF_NO_FLAGS            0
.
.  {* The symbol has local scope; <<static>> in <<C>>. The value
.     is the offset into the section of the data.  *}
.#define BSF_LOCAL               (1 << 0)
.
.  {* The symbol has global scope; initialized data in <<C>>. The
.     value is the offset into the section of the data.  *}
.#define BSF_GLOBAL              (1 << 1)
.
.  {* The symbol has global scope and is exported. The value is
.     the offset into the section of the data.  *}
.#define BSF_EXPORT              BSF_GLOBAL {* No real difference.  *}
.
.  {* A normal C symbol would be one of:
.     <<BSF_LOCAL>>, <<BSF_UNDEFINED>> or <<BSF_GLOBAL>>.  *}
.
.  {* The symbol is a debugging record. The value has an arbitrary
.     meaning, unless BSF_DEBUGGING_RELOC is also set.  *}
.#define BSF_DEBUGGING           (1 << 2)
.
.  {* The symbol denotes a function entry point.  Used in ELF,
.     perhaps others someday.  *}
.#define BSF_FUNCTION            (1 << 3)
.
.  {* Used by the linker.  *}
.#define BSF_KEEP                (1 << 5)
.
.  {* An ELF common symbol.  *}
.#define BSF_ELF_COMMON          (1 << 6)
.
.  {* A weak global symbol, overridable without warnings by
.     a regular global symbol of the same name.  *}
.#define BSF_WEAK                (1 << 7)
.
.  {* This symbol was created to point to a section, e.g. ELF's
.     STT_SECTION symbols.  *}
.#define BSF_SECTION_SYM         (1 << 8)
.
.  {* The symbol used to be a common symbol, but now it is
.     allocated.  *}
.#define BSF_OLD_COMMON          (1 << 9)
.
.  {* In some files the type of a symbol sometimes alters its
.     location in an output file - ie in coff a <<ISFCN>> symbol
.     which is also <<C_EXT>> symbol appears where it was
.     declared and not at the end of a section.  This bit is set
.     by the target BFD part to convey this information.  *}
.#define BSF_NOT_AT_END          (1 << 10)
.
.  {* Signal that the symbol is the label of constructor section.  *}
.#define BSF_CONSTRUCTOR         (1 << 11)
.
.  {* Signal that the symbol is a warning symbol.  The name is a
.     warning.  The name of the next symbol is the one to warn about;
.     if a reference is made to a symbol with the same name as the next
.     symbol, a warning is issued by the linker.  *}
.#define BSF_WARNING             (1 << 12)
.
.  {* Signal that the symbol is indirect.  This symbol is an indirect
.     pointer to the symbol with the same name as the next symbol.  *}
.#define BSF_INDIRECT            (1 << 13)
.
.  {* BSF_FILE marks symbols that contain a file name.  This is used
.     for ELF STT_FILE symbols.  *}
.#define BSF_FILE                (1 << 14)
.
.  {* Symbol is from dynamic linking information.  *}
.#define BSF_DYNAMIC             (1 << 15)
.
.  {* The symbol denotes a data object.  Used in ELF, and perhaps
.     others someday.  *}
.#define BSF_OBJECT              (1 << 16)
.
.  {* This symbol is a debugging symbol.  The value is the offset
.     into the section of the data.  BSF_DEBUGGING should be set
.     as well.  *}
.#define BSF_DEBUGGING_RELOC     (1 << 17)
.
.  {* This symbol is thread local.  Used in ELF.  *}
.#define BSF_THREAD_LOCAL        (1 << 18)
.
.  {* This symbol represents a complex relocation expression,
.     with the expression tree serialized in the symbol name.  *}
.#define BSF_RELC                (1 << 19)
.
.  {* This symbol represents a signed complex relocation expression,
.     with the expression tree serialized in the symbol name.  *}
.#define BSF_SRELC               (1 << 20)
.
.  {* This symbol was created by bfd_get_synthetic_symtab.  *}
.#define BSF_SYNTHETIC           (1 << 21)
.
.  {* This symbol is an indirect code object.  Unrelated to BSF_INDIRECT.
.     The dynamic linker will compute the value of this symbol by
.     calling the function that it points to.  BSF_FUNCTION must
.     also be also set.  *}
.#define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
.  {* This symbol is a globally unique data object.  The dynamic linker
.     will make sure that in the entire process there is just one symbol
.     with this name and type in use.  BSF_OBJECT must also be set.  *}
.#define BSF_GNU_UNIQUE          (1 << 23)
.
.  {* This section symbol should be included in the symbol table.  *}
.#define BSF_SECTION_SYM_USED    (1 << 24)
.
.  flagword flags;
.
.  {* A pointer to the section to which this symbol is
.     relative.  This will always be non NULL, there are special
.     sections for undefined and absolute symbols.  *}
.  struct bfd_section *section;
.
.  {* Back end special data.  *}
.  union
.    {
.      void *p;
.      bfd_vma i;
.    }
.  udata;
.}
.asymbol;
.
*/

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "safe-ctype.h"
#include "bfdlink.h"
#include "aout/stab_gnu.h"

/*
DOCDD
INODE
symbol handling functions,  , typedef asymbol, Symbols
SUBSECTION
	Symbol handling functions
*/

/*
FUNCTION
	bfd_get_symtab_upper_bound

DESCRIPTION
	Return the number of bytes required to store a vector of pointers
	to <<asymbols>> for all the symbols in the BFD @var{abfd},
	including a terminal NULL pointer. If there are no symbols in
	the BFD, then return 0.  If an error occurs, return -1.

.#define bfd_get_symtab_upper_bound(abfd) \
.	BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
.
*/

/*
FUNCTION
	bfd_is_local_label

SYNOPSIS
	bool bfd_is_local_label (bfd *abfd, asymbol *sym);

DESCRIPTION
	Return TRUE if the given symbol @var{sym} in the BFD @var{abfd} is
	a compiler generated local label, else return FALSE.
*/

bool
bfd_is_local_label (bfd *abfd, asymbol *sym)
{
  /* The BSF_SECTION_SYM check is needed for IA-64, where every label that
     starts with '.' is local.  This would accidentally catch section names
     if we didn't reject them here.  */
  if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_FILE | BSF_SECTION_SYM)) != 0)
    return false;
  if (sym->name == NULL)
    return false;
  return bfd_is_local_label_name (abfd, sym->name);
}

/*
FUNCTION
	bfd_is_local_label_name

SYNOPSIS
	bool bfd_is_local_label_name (bfd *abfd, const char *name);

DESCRIPTION
	Return TRUE if a symbol with the name @var{name} in the BFD
	@var{abfd} is a compiler generated local label, else return
	FALSE.  This just checks whether the name has the form of a
	local label.

.#define bfd_is_local_label_name(abfd, name) \
.	BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
.
*/

/*
FUNCTION
	bfd_is_target_special_symbol

SYNOPSIS
	bool bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);

DESCRIPTION
	Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something
	special to the particular target represented by the BFD.  Such symbols
	should normally not be mentioned to the user.

.#define bfd_is_target_special_symbol(abfd, sym) \
.	BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
.
*/

/*
FUNCTION
	bfd_canonicalize_symtab

DESCRIPTION
	Read the symbols from the BFD @var{abfd}, and fills in
	the vector @var{location} with pointers to the symbols and
	a trailing NULL.
	Return the actual number of symbol pointers, not
	including the NULL.

.#define bfd_canonicalize_symtab(abfd, location) \
.	BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location))
.
*/

/*
FUNCTION
	bfd_set_symtab

SYNOPSIS
	bool bfd_set_symtab
	  (bfd *abfd, asymbol **location, unsigned int count);

DESCRIPTION
	Arrange that when the output BFD @var{abfd} is closed,
	the table @var{location} of @var{count} pointers to symbols
	will be written.
*/

bool
bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int symcount)
{
  if (abfd->format != bfd_object || bfd_read_p (abfd))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }

  abfd->outsymbols = location;
  abfd->symcount = symcount;
  return true;
}

/*
FUNCTION
	bfd_print_symbol_vandf

SYNOPSIS
	void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol);

DESCRIPTION
	Print the value and flags of the @var{symbol} supplied to the
	stream @var{file}.
*/
void
bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
{
  FILE *file = (FILE *) arg;

  flagword type = symbol->flags;

  if (symbol->section != NULL)
    bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma);
  else
    bfd_fprintf_vma (abfd, file, symbol->value);

  /* This presumes that a symbol can not be both BSF_DEBUGGING and
     BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and
     BSF_OBJECT.  */
  fprintf (file, " %c%c%c%c%c%c%c",
	   ((type & BSF_LOCAL)
	    ? (type & BSF_GLOBAL) ? '!' : 'l'
	    : (type & BSF_GLOBAL) ? 'g'
	    : (type & BSF_GNU_UNIQUE) ? 'u' : ' '),
	   (type & BSF_WEAK) ? 'w' : ' ',
	   (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
	   (type & BSF_WARNING) ? 'W' : ' ',
	   (type & BSF_INDIRECT) ? 'I' : (type & BSF_GNU_INDIRECT_FUNCTION) ? 'i' : ' ',
	   (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
	   ((type & BSF_FUNCTION)
	    ? 'F'
	    : ((type & BSF_FILE)
	       ? 'f'
	       : ((type & BSF_OBJECT) ? 'O' : ' '))));
}

/*
FUNCTION
	bfd_make_empty_symbol

DESCRIPTION
	Create a new <<asymbol>> structure for the BFD @var{abfd}
	and return a pointer to it.

	This routine is necessary because each back end has private
	information surrounding the <<asymbol>>. Building your own
	<<asymbol>> and pointing to it will not create the private
	information, and will cause problems later on.

.#define bfd_make_empty_symbol(abfd) \
.	BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
.
*/

/*
FUNCTION
	_bfd_generic_make_empty_symbol

SYNOPSIS
	asymbol *_bfd_generic_make_empty_symbol (bfd *);

DESCRIPTION
	Create a new <<asymbol>> structure for the BFD @var{abfd}
	and return a pointer to it.  Used by core file routines,
	binary back-end and anywhere else where no private info
	is needed.
*/

asymbol *
_bfd_generic_make_empty_symbol (bfd *abfd)
{
  size_t amt = sizeof (asymbol);
  asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);
  if (new_symbol)
    new_symbol->the_bfd = abfd;
  return new_symbol;
}

/*
FUNCTION
	bfd_make_debug_symbol

DESCRIPTION
	Create a new <<asymbol>> structure for the BFD @var{abfd},
	to be used as a debugging symbol.  Further details of its use have
	yet to be worked out.

.#define bfd_make_debug_symbol(abfd,ptr,size) \
.	BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
.
*/

struct section_to_type
{
  const char *section;
  char type;
};

/* Map special section names to POSIX/BSD single-character symbol types.
   This table is probably incomplete.  It is sorted for convenience of
   adding entries.  Since it is so short, a linear search is used.  */
static const struct section_to_type stt[] =
{
  {".drectve", 'i'},		/* MSVC's .drective section */
  {".edata", 'e'},		/* MSVC's .edata (export) section */
  {".idata", 'i'},		/* MSVC's .idata (import) section */
  {".pdata", 'p'},		/* MSVC's .pdata (stack unwind) section */
  {0, 0}
};

/* Return the single-character symbol type corresponding to
   section S, or '?' for an unknown COFF section.

   Check for leading strings which match, followed by a number, '.',
   or '$' so .idata5 matches the .idata entry.  */

static char
coff_section_type (const char *s)
{
  const struct section_to_type *t;

  for (t = &stt[0]; t->section; t++)
    {
      size_t len = strlen (t->section);
      if (strncmp (s, t->section, len) == 0
	  && memchr (".$0123456789", s[len], 13) != 0)
	return t->type;
    }

  return '?';
}

/* Return the single-character symbol type corresponding to section
   SECTION, or '?' for an unknown section.  This uses section flags to
   identify sections.

   FIXME These types are unhandled: e, i, p.  If we handled these also,
   we could perhaps obsolete coff_section_type.  */

static char
decode_section_type (const struct bfd_section *section)
{
  if (section->flags & SEC_CODE)
    return 't';
  if (section->flags & SEC_DATA)
    {
      if (section->flags & SEC_READONLY)
	return 'r';
      else if (section->flags & SEC_SMALL_DATA)
	return 'g';
      else
	return 'd';
    }
  if ((section->flags & SEC_HAS_CONTENTS) == 0)
    {
      if (section->flags & SEC_SMALL_DATA)
	return 's';
      else
	return 'b';
    }
  if (section->flags & SEC_DEBUGGING)
    return 'N';
  if ((section->flags & SEC_HAS_CONTENTS) && (section->flags & SEC_READONLY))
    return 'n';

  return '?';
}

/*
FUNCTION
	bfd_decode_symclass

SYNOPSIS
	int bfd_decode_symclass (asymbol *symbol);

DESCRIPTION
	Return a character corresponding to the symbol
	class of @var{symbol}, or '?' for an unknown class.
*/
int
bfd_decode_symclass (asymbol *symbol)
{
  char c;

  /* Paranoia...  */
  if (symbol == NULL || symbol->section == NULL)
    return '?';

  if (symbol->section && bfd_is_com_section (symbol->section))
    {
      if (symbol->section->flags & SEC_SMALL_DATA)
	return 'c';
      else
	return 'C';
    }
  if (bfd_is_und_section (symbol->section))
    {
      if (symbol->flags & BSF_WEAK)
	{
	  /* If weak, determine if it's specifically an object
	     or non-object weak.  */
	  if (symbol->flags & BSF_OBJECT)
	    return 'v';
	  else
	    return 'w';
	}
      else
	return 'U';
    }
  if (bfd_is_ind_section (symbol->section))
    return 'I';
  if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION)
    return 'i';
  if (symbol->flags & BSF_WEAK)
    {
      /* If weak, determine if it's specifically an object
	 or non-object weak.  */
      if (symbol->flags & BSF_OBJECT)
	return 'V';
      else
	return 'W';
    }
  if (symbol->flags & BSF_GNU_UNIQUE)
    return 'u';
  if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
    return '?';

  if (bfd_is_abs_section (symbol->section))
    c = 'a';
  else if (symbol->section)
    {
      c = coff_section_type (symbol->section->name);
      if (c == '?')
	c = decode_section_type (symbol->section);
    }
  else
    return '?';
  if (symbol->flags & BSF_GLOBAL)
    c = TOUPPER (c);
  return c;

  /* We don't have to handle these cases just yet, but we will soon:
     N_SETV: 'v';
     N_SETA: 'l';
     N_SETT: 'x';
     N_SETD: 'z';
     N_SETB: 's';
     N_INDR: 'i';
     */
}

/*
FUNCTION
	bfd_is_undefined_symclass

SYNOPSIS
	bool bfd_is_undefined_symclass (int symclass);

DESCRIPTION
	Returns non-zero if the class symbol returned by
	bfd_decode_symclass represents an undefined symbol.
	Returns zero otherwise.
*/

bool
bfd_is_undefined_symclass (int symclass)
{
  return symclass == 'U' || symclass == 'w' || symclass == 'v';
}

/*
FUNCTION
	bfd_symbol_info

SYNOPSIS
	void bfd_symbol_info (asymbol *symbol, symbol_info *ret);

DESCRIPTION
	Fill in the basic info about symbol that nm needs.
	Additional info may be added by the back-ends after
	calling this function.
*/

void
bfd_symbol_info (asymbol *symbol, symbol_info *ret)
{
  ret->type = bfd_decode_symclass (symbol);

  if (bfd_is_undefined_symclass (ret->type))
    ret->value = 0;
  else
    ret->value = symbol->value + symbol->section->vma;

  ret->name = symbol->name;
}

/*
FUNCTION
	bfd_copy_private_symbol_data

SYNOPSIS
	bool bfd_copy_private_symbol_data
	  (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);

DESCRIPTION
	Copy private symbol information from @var{isym} in the BFD
	@var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}.
	Return <<TRUE>> on success, <<FALSE>> on error.  Possible error
	returns are:

	o <<bfd_error_no_memory>> -
	Not enough memory exists to create private data for @var{osec}.

.#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
.	BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
.		  (ibfd, isymbol, obfd, osymbol))
.
*/

/* The generic version of the function which returns mini symbols.
   This is used when the backend does not provide a more efficient
   version.  It just uses BFD asymbol structures as mini symbols.  */

long
_bfd_generic_read_minisymbols (bfd *abfd,
			       bool dynamic,
			       void **minisymsp,
			       unsigned int *sizep)
{
  long storage;
  asymbol **syms = NULL;
  long symcount;

  if (dynamic)
    storage = bfd_get_dynamic_symtab_upper_bound (abfd);
  else
    storage = bfd_get_symtab_upper_bound (abfd);
  if (storage < 0)
    goto error_return;
  if (storage == 0)
    return 0;

  syms = (asymbol **) bfd_malloc (storage);
  if (syms == NULL)
    goto error_return;

  if (dynamic)
    symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
  else
    symcount = bfd_canonicalize_symtab (abfd, syms);
  if (symcount < 0)
    goto error_return;

  if (symcount == 0)
    /* We return 0 above when storage is 0.  Exit in the same state
       here, so as to not complicate callers with having to deal with
       freeing memory for zero symcount.  */
    free (syms);
  else
    {
      *minisymsp = syms;
      *sizep = sizeof (asymbol *);
    }
  return symcount;

 error_return:
  bfd_set_error (bfd_error_no_symbols);
  free (syms);
  return -1;
}

/* The generic version of the function which converts a minisymbol to
   an asymbol.  We don't worry about the sym argument we are passed;
   we just return the asymbol the minisymbol points to.  */

asymbol *
_bfd_generic_minisymbol_to_symbol (bfd *abfd ATTRIBUTE_UNUSED,
				   bool dynamic ATTRIBUTE_UNUSED,
				   const void *minisym,
				   asymbol *sym ATTRIBUTE_UNUSED)
{
  return *(asymbol **) minisym;
}

/* Look through stabs debugging information in .stab and .stabstr
   sections to find the source file and line closest to a desired
   location.  This is used by COFF and ELF targets.  It sets *pfound
   to TRUE if it finds some information.  The *pinfo field is used to
   pass cached information in and out of this routine; this first time
   the routine is called for a BFD, *pinfo should be NULL.  The value
   placed in *pinfo should be saved with the BFD, and passed back each
   time this function is called.  */

/* We use a cache by default.  */

#define ENABLE_CACHING

/* We keep an array of indexentry structures to record where in the
   stabs section we should look to find line number information for a
   particular address.  */

struct indexentry
{
  bfd_vma val;
  bfd_byte *stab;
  bfd_byte *str;
  char *directory_name;
  char *file_name;
  char *function_name;
  int idx;
};

/* Compare two indexentry structures.  This is called via qsort.  */

static int
cmpindexentry (const void *a, const void *b)
{
  const struct indexentry *contestantA = (const struct indexentry *) a;
  const struct indexentry *contestantB = (const struct indexentry *) b;

  if (contestantA->val < contestantB->val)
    return -1;
  if (contestantA->val > contestantB->val)
    return 1;
  return contestantA->idx - contestantB->idx;
}

/* A pointer to this structure is stored in *pinfo.  */

struct stab_find_info
{
  /* The .stab section.  */
  asection *stabsec;
  /* The .stabstr section.  */
  asection *strsec;
  /* The contents of the .stab section.  */
  bfd_byte *stabs;
  /* The contents of the .stabstr section.  */
  bfd_byte *strs;

  /* A table that indexes stabs by memory address.  */
  struct indexentry *indextable;
  /* The number of entries in indextable.  */
  int indextablesize;

#ifdef ENABLE_CACHING
  /* Cached values to restart quickly.  */
  struct indexentry *cached_indexentry;
  bfd_vma cached_offset;
  bfd_byte *cached_stab;
  char *cached_file_name;
#endif

  /* Saved ptr to malloc'ed filename.  */
  char *filename;
};

bool
_bfd_stab_section_find_nearest_line (bfd *abfd,
				     asymbol **symbols,
				     asection *section,
				     bfd_vma offset,
				     bool *pfound,
				     const char **pfilename,
				     const char **pfnname,
				     unsigned int *pline,
				     void **pinfo)
{
  struct stab_find_info *info;
  bfd_size_type stabsize, strsize;
  bfd_byte *stab, *str;
  bfd_byte *nul_fun, *nul_str;
  bfd_size_type stroff;
  struct indexentry *indexentry;
  char *file_name;
  char *directory_name;
  bool saw_line, saw_func;

  *pfound = false;
  *pfilename = bfd_get_filename (abfd);
  *pfnname = NULL;
  *pline = 0;

  /* Stabs entries use a 12 byte format:
       4 byte string table index
       1 byte stab type
       1 byte stab other field
       2 byte stab desc field
       4 byte stab value
     FIXME: This will have to change for a 64 bit object format.

     The stabs symbols are divided into compilation units.  For the
     first entry in each unit, the type of 0, the value is the length
     of the string table for this unit, and the desc field is the
     number of stabs symbols for this unit.  */

#define STRDXOFF (0)
#define TYPEOFF (4)
#define OTHEROFF (5)
#define DESCOFF (6)
#define VALOFF (8)
#define STABSIZE (12)

  info = (struct stab_find_info *) *pinfo;
  if (info != NULL)
    {
      if (info->stabsec == NULL || info->strsec == NULL)
	{
	  /* No usable stabs debugging information.  */
	  return true;
	}

      stabsize = (info->stabsec->rawsize
		  ? info->stabsec->rawsize
		  : info->stabsec->size);
      strsize = (info->strsec->rawsize
		 ? info->strsec->rawsize
		 : info->strsec->size);
    }
  else
    {
      long reloc_size, reloc_count;
      arelent **reloc_vector;
      int i;
      char *function_name;
      bfd_size_type amt = sizeof *info;

      info = (struct stab_find_info *) bfd_zalloc (abfd, amt);
      if (info == NULL)
	return false;
      *pinfo = info;

      /* FIXME: When using the linker --split-by-file or
	 --split-by-reloc options, it is possible for the .stab and
	 .stabstr sections to be split.  We should handle that.  */

      info->stabsec = bfd_get_section_by_name (abfd, ".stab");
      info->strsec = bfd_get_section_by_name (abfd, ".stabstr");

      if (info->stabsec == NULL || info->strsec == NULL)
	{
	  /* Try SOM section names.  */
	  info->stabsec = bfd_get_section_by_name (abfd, "$GDB_SYMBOLS$");
	  info->strsec  = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");

	  if (info->stabsec == NULL || info->strsec == NULL)
	    return true;
	}

      if ((info->stabsec->flags & SEC_HAS_CONTENTS) == 0
	  || (info->strsec->flags & SEC_HAS_CONTENTS) == 0)
	goto out;

      stabsize = (info->stabsec->rawsize
		  ? info->stabsec->rawsize
		  : info->stabsec->size);
      stabsize = (stabsize / STABSIZE) * STABSIZE;
      strsize = (info->strsec->rawsize
		 ? info->strsec->rawsize
		 : info->strsec->size);

      if (stabsize == 0 || strsize == 0)
	goto out;

      if (!bfd_malloc_and_get_section (abfd, info->stabsec, &info->stabs))
	goto out;
      if (!bfd_malloc_and_get_section (abfd, info->strsec, &info->strs))
	goto out1;

      /* Stab strings ought to be nul terminated.  Ensure the last one
	 is, to prevent running off the end of the buffer.  */
      info->strs[strsize - 1] = 0;

      /* If this is a relocatable object file, we have to relocate
	 the entries in .stab.  This should always be simple 32 bit
	 relocations against symbols defined in this object file, so
	 this should be no big deal.  */
      reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
      if (reloc_size < 0)
	goto out2;
      reloc_vector = (arelent **) bfd_malloc (reloc_size);
      if (reloc_vector == NULL && reloc_size != 0)
	goto out2;
      reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
					    symbols);
      if (reloc_count < 0)
	{
	out3:
	  free (reloc_vector);
	out2:
	  free (info->strs);
	  info->strs = NULL;
	out1:
	  free (info->stabs);
	  info->stabs = NULL;
	out:
	  info->stabsec = NULL;
	  return false;
	}
      if (reloc_count > 0)
	{
	  arelent **pr;

	  for (pr = reloc_vector; *pr != NULL; pr++)
	    {
	      arelent *r;
	      unsigned long val;
	      asymbol *sym;
	      bfd_size_type octets;

	      r = *pr;
	      /* Ignore R_*_NONE relocs.  */
	      if (r->howto->dst_mask == 0)
		continue;

	      octets = r->address * bfd_octets_per_byte (abfd, NULL);
	      if (r->howto->rightshift != 0
		  || bfd_get_reloc_size (r->howto) != 4
		  || r->howto->bitsize != 32
		  || r->howto->pc_relative
		  || r->howto->bitpos != 0
		  || r->howto->dst_mask != 0xffffffff
		  || octets + 4 > stabsize)
		{
		  _bfd_error_handler
		    (_("unsupported .stab relocation"));
		  bfd_set_error (bfd_error_invalid_operation);
		  goto out3;
		}

	      val = bfd_get_32 (abfd, info->stabs + octets);
	      val &= r->howto->src_mask;
	      sym = *r->sym_ptr_ptr;
	      val += sym->value + sym->section->vma + r->addend;
	      bfd_put_32 (abfd, (bfd_vma) val, info->stabs + octets);
	    }
	}

      free (reloc_vector);

      /* First time through this function, build a table matching
	 function VM addresses to stabs, then sort based on starting
	 VM address.  Do this in two passes: once to count how many
	 table entries we'll need, and a second to actually build the
	 table.  */

      info->indextablesize = 0;
      nul_fun = NULL;
      for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
	{
	  if (stab[TYPEOFF] == (bfd_byte) N_SO)
	    {
	      /* if we did not see a function def, leave space for one.  */
	      if (nul_fun != NULL)
		++info->indextablesize;

	      /* N_SO with null name indicates EOF */
	      if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
		nul_fun = NULL;
	      else
		{
		  nul_fun = stab;

		  /* two N_SO's in a row is a filename and directory. Skip */
		  if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
		      && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
		    stab += STABSIZE;
		}
	    }
	  else if (stab[TYPEOFF] == (bfd_byte) N_FUN
		   && bfd_get_32 (abfd, stab + STRDXOFF) != 0)
	    {
	      nul_fun = NULL;
	      ++info->indextablesize;
	    }
	}

      if (nul_fun != NULL)
	++info->indextablesize;

      if (info->indextablesize == 0)
	{
	  free (info->strs);
	  info->strs = NULL;
	  free (info->stabs);
	  info->stabs = NULL;
	  info->stabsec = NULL;
	  return true;
	}
      ++info->indextablesize;

      amt = info->indextablesize;
      amt *= sizeof (struct indexentry);
      info->indextable = (struct indexentry *) bfd_malloc (amt);
      if (info->indextable == NULL)
	goto out3;

      file_name = NULL;
      directory_name = NULL;
      nul_fun = NULL;
      stroff = 0;

      for (i = 0, stab = info->stabs, nul_str = str = info->strs;
	   i < info->indextablesize && stab < info->stabs + stabsize;
	   stab += STABSIZE)
	{
	  switch (stab[TYPEOFF])
	    {
	    case 0:
	      /* This is the first entry in a compilation unit.  */
	      if ((bfd_size_type) ((info->strs + strsize) - str) < stroff)
		break;
	      str += stroff;
	      stroff = bfd_get_32 (abfd, stab + VALOFF);
	      break;

	    case N_SO:
	      /* The main file name.  */

	      /* The following code creates a new indextable entry with
		 a NULL function name if there were no N_FUNs in a file.
		 Note that a N_SO without a file name is an EOF and
		 there could be 2 N_SO following it with the new filename
		 and directory.  */
	      if (nul_fun != NULL)
		{
		  info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
		  info->indextable[i].stab = nul_fun;
		  info->indextable[i].str = nul_str;
		  info->indextable[i].directory_name = directory_name;
		  info->indextable[i].file_name = file_name;
		  info->indextable[i].function_name = NULL;
		  info->indextable[i].idx = i;
		  ++i;
		}

	      directory_name = NULL;
	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
	      if (file_name == (char *) str)
		{
		  file_name = NULL;
		  nul_fun = NULL;
		}
	      else
		{
		  nul_fun = stab;
		  nul_str = str;
		  if (file_name >= (char *) info->strs + strsize
		      || file_name < (char *) str)
		    file_name = NULL;
		  if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
		      && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
		    {
		      /* Two consecutive N_SOs are a directory and a
			 file name.  */
		      stab += STABSIZE;
		      directory_name = file_name;
		      file_name = ((char *) str
				   + bfd_get_32 (abfd, stab + STRDXOFF));
		      if (file_name >= (char *) info->strs + strsize
			  || file_name < (char *) str)
			file_name = NULL;
		    }
		}
	      break;

	    case N_SOL:
	      /* The name of an include file.  */
	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
	      /* PR 17512: file: 0c680a1f.  */
	      /* PR 17512: file: 5da8aec4.  */
	      if (file_name >= (char *) info->strs + strsize
		  || file_name < (char *) str)
		file_name = NULL;
	      break;

	    case N_FUN:
	      /* A function name.  */
	      function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
	      if (function_name == (char *) str)
		continue;
	      if (function_name >= (char *) info->strs + strsize
		  || function_name < (char *) str)
		function_name = NULL;

	      nul_fun = NULL;
	      info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
	      info->indextable[i].stab = stab;
	      info->indextable[i].str = str;
	      info->indextable[i].directory_name = directory_name;
	      info->indextable[i].file_name = file_name;
	      info->indextable[i].function_name = function_name;
	      info->indextable[i].idx = i;
	      ++i;
	      break;
	    }
	}

      if (nul_fun != NULL)
	{
	  info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
	  info->indextable[i].stab = nul_fun;
	  info->indextable[i].str = nul_str;
	  info->indextable[i].directory_name = directory_name;
	  info->indextable[i].file_name = file_name;
	  info->indextable[i].function_name = NULL;
	  info->indextable[i].idx = i;
	  ++i;
	}

      info->indextable[i].val = (bfd_vma) -1;
      info->indextable[i].stab = info->stabs + stabsize;
      info->indextable[i].str = str;
      info->indextable[i].directory_name = NULL;
      info->indextable[i].file_name = NULL;
      info->indextable[i].function_name = NULL;
      info->indextable[i].idx = i;
      ++i;

      info->indextablesize = i;
      qsort (info->indextable, (size_t) i, sizeof (struct indexentry),
	     cmpindexentry);
    }

  /* We are passed a section relative offset.  The offsets in the
     stabs information are absolute.  */
  offset += bfd_section_vma (section);

#ifdef ENABLE_CACHING
  if (info->cached_indexentry != NULL
      && offset >= info->cached_offset
      && offset < (info->cached_indexentry + 1)->val)
    {
      stab = info->cached_stab;
      indexentry = info->cached_indexentry;
      file_name = info->cached_file_name;
    }
  else
#endif
    {
      long low, high;
      long mid = -1;

      /* Cache non-existent or invalid.  Do binary search on
	 indextable.  */
      indexentry = NULL;

      low = 0;
      high = info->indextablesize - 1;
      while (low != high)
	{
	  mid = (high + low) / 2;
	  if (offset >= info->indextable[mid].val
	      && offset < info->indextable[mid + 1].val)
	    {
	      indexentry = &info->indextable[mid];
	      break;
	    }

	  if (info->indextable[mid].val > offset)
	    high = mid;
	  else
	    low = mid + 1;
	}

      if (indexentry == NULL)
	return true;

      stab = indexentry->stab + STABSIZE;
      file_name = indexentry->file_name;
    }

  directory_name = indexentry->directory_name;
  str = indexentry->str;

  saw_line = false;
  saw_func = false;
  for (; stab < (indexentry+1)->stab; stab += STABSIZE)
    {
      bool done;
      bfd_vma val;

      done = false;

      switch (stab[TYPEOFF])
	{
	case N_SOL:
	  /* The name of an include file.  */
	  val = bfd_get_32 (abfd, stab + VALOFF);
	  if (val <= offset)
	    {
	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
	      if (file_name >= (char *) info->strs + strsize
		  || file_name < (char *) str)
		file_name = NULL;
	      *pline = 0;
	    }
	  break;

	case N_SLINE:
	case N_DSLINE:
	case N_BSLINE:
	  /* A line number.  If the function was specified, then the value
	     is relative to the start of the function.  Otherwise, the
	     value is an absolute address.  */
	  val = ((indexentry->function_name ? indexentry->val : 0)
		 + bfd_get_32 (abfd, stab + VALOFF));
	  /* If this line starts before our desired offset, or if it's
	     the first line we've been able to find, use it.  The
	     !saw_line check works around a bug in GCC 2.95.3, which emits
	     the first N_SLINE late.  */
	  if (!saw_line || val <= offset)
	    {
	      *pline = bfd_get_16 (abfd, stab + DESCOFF);

#ifdef ENABLE_CACHING
	      info->cached_stab = stab;
	      info->cached_offset = val;
	      info->cached_file_name = file_name;
	      info->cached_indexentry = indexentry;
#endif
	    }
	  if (val > offset)
	    done = true;
	  saw_line = true;
	  break;

	case N_FUN:
	case N_SO:
	  if (saw_func || saw_line)
	    done = true;
	  saw_func = true;
	  break;
	}

      if (done)
	break;
    }

  *pfound = true;

  if (file_name == NULL || IS_ABSOLUTE_PATH (file_name)
      || directory_name == NULL)
    *pfilename = file_name;
  else
    {
      size_t dirlen;

      dirlen = strlen (directory_name);
      if (info->filename == NULL
	  || filename_ncmp (info->filename, directory_name, dirlen) != 0
	  || filename_cmp (info->filename + dirlen, file_name) != 0)
	{
	  size_t len;

	  /* Don't free info->filename here.  objdump and other
	     apps keep a copy of a previously returned file name
	     pointer.  */
	  len = strlen (file_name) + 1;
	  info->filename = (char *) bfd_alloc (abfd, dirlen + len);
	  if (info->filename == NULL)
	    return false;
	  memcpy (info->filename, directory_name, dirlen);
	  memcpy (info->filename + dirlen, file_name, len);
	}

      *pfilename = info->filename;
    }

  if (indexentry->function_name != NULL)
    {
      char *s;

      /* This will typically be something like main:F(0,1), so we want
	 to clobber the colon.  It's OK to change the name, since the
	 string is in our own local storage anyhow.  */
      s = strchr (indexentry->function_name, ':');
      if (s != NULL)
	*s = '\0';

      *pfnname = indexentry->function_name;
    }

  return true;
}

void
_bfd_stab_cleanup (bfd *abfd ATTRIBUTE_UNUSED, void **pinfo)
{
  struct stab_find_info *info = (struct stab_find_info *) *pinfo;
  if (info == NULL)
    return;

  free (info->indextable);
  free (info->strs);
  free (info->stabs);
}

long
_bfd_nosymbols_canonicalize_symtab (bfd *abfd ATTRIBUTE_UNUSED,
				    asymbol **location ATTRIBUTE_UNUSED)
{
  return 0;
}

void
_bfd_nosymbols_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
			     void *afile ATTRIBUTE_UNUSED,
			     asymbol *symbol ATTRIBUTE_UNUSED,
			     bfd_print_symbol_type how ATTRIBUTE_UNUSED)
{
}

void
_bfd_nosymbols_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
				asymbol *sym ATTRIBUTE_UNUSED,
				symbol_info *ret ATTRIBUTE_UNUSED)
{
}

const char *
_bfd_nosymbols_get_symbol_version_string (bfd *abfd,
					  asymbol *symbol ATTRIBUTE_UNUSED,
					  bool base_p ATTRIBUTE_UNUSED,
					  bool *hidden ATTRIBUTE_UNUSED)
{
  return (const char *) _bfd_ptr_bfd_null_error (abfd);
}

bool
_bfd_nosymbols_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
					const char *name ATTRIBUTE_UNUSED)
{
  return false;
}

alent *
_bfd_nosymbols_get_lineno (bfd *abfd, asymbol *sym ATTRIBUTE_UNUSED)
{
  return (alent *) _bfd_ptr_bfd_null_error (abfd);
}

bool
_bfd_nosymbols_find_nearest_line
    (bfd *abfd,
     asymbol **symbols ATTRIBUTE_UNUSED,
     asection *section ATTRIBUTE_UNUSED,
     bfd_vma offset ATTRIBUTE_UNUSED,
     const char **filename_ptr ATTRIBUTE_UNUSED,
     const char **functionname_ptr ATTRIBUTE_UNUSED,
     unsigned int *line_ptr ATTRIBUTE_UNUSED,
     unsigned int *discriminator_ptr ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

bool
_bfd_nosymbols_find_nearest_line_with_alt
    (bfd *abfd,
     const char *alt_filename ATTRIBUTE_UNUSED,
     asymbol **symbols ATTRIBUTE_UNUSED,
     asection *section ATTRIBUTE_UNUSED,
     bfd_vma offset ATTRIBUTE_UNUSED,
     const char **filename_ptr ATTRIBUTE_UNUSED,
     const char **functionname_ptr ATTRIBUTE_UNUSED,
     unsigned int *line_ptr ATTRIBUTE_UNUSED,
     unsigned int *discriminator_ptr ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

bool
_bfd_nosymbols_find_line (bfd *abfd,
			  asymbol **symbols ATTRIBUTE_UNUSED,
			  asymbol *symbol ATTRIBUTE_UNUSED,
			  const char **filename_ptr ATTRIBUTE_UNUSED,
			  unsigned int *line_ptr ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

bool
_bfd_nosymbols_find_inliner_info
    (bfd *abfd,
     const char **filename_ptr ATTRIBUTE_UNUSED,
     const char **functionname_ptr ATTRIBUTE_UNUSED,
     unsigned int *line_ptr ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

asymbol *
_bfd_nosymbols_bfd_make_debug_symbol (bfd *abfd,
				      void *ptr ATTRIBUTE_UNUSED,
				      unsigned long sz ATTRIBUTE_UNUSED)
{
  return (asymbol *) _bfd_ptr_bfd_null_error (abfd);
}

long
_bfd_nosymbols_read_minisymbols (bfd *abfd,
				 bool dynamic ATTRIBUTE_UNUSED,
				 void **minisymsp ATTRIBUTE_UNUSED,
				 unsigned int *sizep ATTRIBUTE_UNUSED)
{
  return _bfd_long_bfd_n1_error (abfd);
}

asymbol *
_bfd_nosymbols_minisymbol_to_symbol (bfd *abfd,
				     bool dynamic ATTRIBUTE_UNUSED,
				     const void *minisym ATTRIBUTE_UNUSED,
				     asymbol *sym ATTRIBUTE_UNUSED)
{
  return (asymbol *) _bfd_ptr_bfd_null_error (abfd);
}

long
_bfd_nodynamic_get_synthetic_symtab (bfd *abfd,
				     long symcount ATTRIBUTE_UNUSED,
				     asymbol **syms ATTRIBUTE_UNUSED,
				     long dynsymcount ATTRIBUTE_UNUSED,
				     asymbol **dynsyms ATTRIBUTE_UNUSED,
				     asymbol **ret ATTRIBUTE_UNUSED)
{
  return _bfd_long_bfd_n1_error (abfd);
}
