133965Sjdp/* Generic BFD library interface and support routines.
278828Sobrien   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3218822Sdim   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
433965Sjdp   Free Software Foundation, Inc.
533965Sjdp   Written by Cygnus Support.
633965Sjdp
7130561Sobrien   This file is part of BFD, the Binary File Descriptor library.
833965Sjdp
9130561Sobrien   This program is free software; you can redistribute it and/or modify
10130561Sobrien   it under the terms of the GNU General Public License as published by
11130561Sobrien   the Free Software Foundation; either version 2 of the License, or
12130561Sobrien   (at your option) any later version.
1333965Sjdp
14130561Sobrien   This program is distributed in the hope that it will be useful,
15130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
16130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17130561Sobrien   GNU General Public License for more details.
1833965Sjdp
19130561Sobrien   You should have received a copy of the GNU General Public License
20130561Sobrien   along with this program; if not, write to the Free Software
21218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2233965Sjdp
2333965Sjdp/*
2433965SjdpSECTION
2533965Sjdp	<<typedef bfd>>
2633965Sjdp
2733965Sjdp	A BFD has type <<bfd>>; objects of this type are the
2833965Sjdp	cornerstone of any application using BFD. Using BFD
2933965Sjdp	consists of making references though the BFD and to data in the BFD.
3033965Sjdp
3133965Sjdp	Here is the structure that defines the type <<bfd>>.  It
3233965Sjdp	contains the major data about the file and pointers
3333965Sjdp	to the rest of the data.
3433965Sjdp
3533965SjdpCODE_FRAGMENT
3633965Sjdp.
37130561Sobrien.struct bfd
3833965Sjdp.{
39130561Sobrien.  {* A unique identifier of the BFD  *}
40130561Sobrien.  unsigned int id;
41130561Sobrien.
4291041Sobrien.  {* The filename the application opened the BFD with.  *}
4391041Sobrien.  const char *filename;
4433965Sjdp.
4591041Sobrien.  {* A pointer to the target jump table.  *}
4691041Sobrien.  const struct bfd_target *xvec;
4733965Sjdp.
48218822Sdim.  {* The IOSTREAM, and corresponding IO vector that provide access
49218822Sdim.     to the file backing the BFD.  *}
50130561Sobrien.  void *iostream;
51218822Sdim.  const struct bfd_iovec *iovec;
5233965Sjdp.
5391041Sobrien.  {* Is the file descriptor being cached?  That is, can it be closed as
5491041Sobrien.     needed, and re-opened when accessed later?  *}
55130561Sobrien.  bfd_boolean cacheable;
5633965Sjdp.
5791041Sobrien.  {* Marks whether there was a default target specified when the
5891041Sobrien.     BFD was opened. This is used to select which matching algorithm
5991041Sobrien.     to use to choose the back end.  *}
60130561Sobrien.  bfd_boolean target_defaulted;
6133965Sjdp.
6291041Sobrien.  {* The caching routines use these to maintain a
6391041Sobrien.     least-recently-used list of BFDs.  *}
64130561Sobrien.  struct bfd *lru_prev, *lru_next;
6533965Sjdp.
6691041Sobrien.  {* When a file is closed by the caching routines, BFD retains
6791041Sobrien.     state information on the file here...  *}
6891041Sobrien.  ufile_ptr where;
6933965Sjdp.
7091041Sobrien.  {* ... and here: (``once'' means at least once).  *}
71130561Sobrien.  bfd_boolean opened_once;
7233965Sjdp.
7391041Sobrien.  {* Set if we have a locally maintained mtime value, rather than
7491041Sobrien.     getting it from the file each time.  *}
75130561Sobrien.  bfd_boolean mtime_set;
7633965Sjdp.
77130561Sobrien.  {* File modified time, if mtime_set is TRUE.  *}
7891041Sobrien.  long mtime;
7933965Sjdp.
8091041Sobrien.  {* Reserved for an unimplemented file locking extension.  *}
8191041Sobrien.  int ifd;
8233965Sjdp.
8391041Sobrien.  {* The format which belongs to the BFD. (object, core, etc.)  *}
8491041Sobrien.  bfd_format format;
8533965Sjdp.
8691041Sobrien.  {* The direction with which the BFD was opened.  *}
8791041Sobrien.  enum bfd_direction
8891041Sobrien.    {
8991041Sobrien.      no_direction = 0,
9091041Sobrien.      read_direction = 1,
9191041Sobrien.      write_direction = 2,
9291041Sobrien.      both_direction = 3
9391041Sobrien.    }
9491041Sobrien.  direction;
9533965Sjdp.
9691041Sobrien.  {* Format_specific flags.  *}
9791041Sobrien.  flagword flags;
9833965Sjdp.
9991041Sobrien.  {* Currently my_archive is tested before adding origin to
10091041Sobrien.     anything. I believe that this can become always an add of
10191041Sobrien.     origin, with origin set to 0 for non archive files.  *}
10291041Sobrien.  ufile_ptr origin;
10333965Sjdp.
10491041Sobrien.  {* Remember when output has begun, to stop strange things
10591041Sobrien.     from happening.  *}
106130561Sobrien.  bfd_boolean output_has_begun;
10733965Sjdp.
10891041Sobrien.  {* A hash table for section names.  *}
10991041Sobrien.  struct bfd_hash_table section_htab;
11033965Sjdp.
11191041Sobrien.  {* Pointer to linked list of sections.  *}
112130561Sobrien.  struct bfd_section *sections;
11333965Sjdp.
114218822Sdim.  {* The last section on the section list.  *}
115218822Sdim.  struct bfd_section *section_last;
11633965Sjdp.
11791041Sobrien.  {* The number of sections.  *}
11891041Sobrien.  unsigned int section_count;
11933965Sjdp.
12091041Sobrien.  {* Stuff only useful for object files:
12191041Sobrien.     The start address.  *}
12291041Sobrien.  bfd_vma start_address;
12333965Sjdp.
12491041Sobrien.  {* Used for input and output.  *}
12591041Sobrien.  unsigned int symcount;
12633965Sjdp.
12791041Sobrien.  {* Symbol table for output BFD (with symcount entries).  *}
128130561Sobrien.  struct bfd_symbol  **outsymbols;
12933965Sjdp.
130104834Sobrien.  {* Used for slurped dynamic symbol tables.  *}
131104834Sobrien.  unsigned int dynsymcount;
132104834Sobrien.
13391041Sobrien.  {* Pointer to structure which contains architecture information.  *}
13491041Sobrien.  const struct bfd_arch_info *arch_info;
13533965Sjdp.
136218822Sdim.  {* Flag set if symbols from this BFD should not be exported.  *}
137218822Sdim.  bfd_boolean no_export;
138218822Sdim.
13991041Sobrien.  {* Stuff only useful for archives.  *}
140130561Sobrien.  void *arelt_data;
141130561Sobrien.  struct bfd *my_archive;      {* The containing archive BFD.  *}
142218822Sdim.  struct bfd *archive_next;    {* The next BFD in the archive.  *}
143130561Sobrien.  struct bfd *archive_head;    {* The first BFD in the archive.  *}
144130561Sobrien.  bfd_boolean has_armap;
14533965Sjdp.
14691041Sobrien.  {* A chain of BFD structures involved in a link.  *}
147130561Sobrien.  struct bfd *link_next;
14833965Sjdp.
14991041Sobrien.  {* A field used by _bfd_generic_link_add_archive_symbols.  This will
15091041Sobrien.     be used only for archive elements.  *}
15191041Sobrien.  int archive_pass;
15233965Sjdp.
15391041Sobrien.  {* Used by the back end to hold private data.  *}
15491041Sobrien.  union
15591041Sobrien.    {
15633965Sjdp.      struct aout_data_struct *aout_data;
15733965Sjdp.      struct artdata *aout_ar_data;
15833965Sjdp.      struct _oasys_data *oasys_obj_data;
15933965Sjdp.      struct _oasys_ar_data *oasys_ar_data;
16033965Sjdp.      struct coff_tdata *coff_obj_data;
16133965Sjdp.      struct pe_tdata *pe_obj_data;
16233965Sjdp.      struct xcoff_tdata *xcoff_obj_data;
16333965Sjdp.      struct ecoff_tdata *ecoff_obj_data;
16433965Sjdp.      struct ieee_data_struct *ieee_data;
16533965Sjdp.      struct ieee_ar_data_struct *ieee_ar_data;
16633965Sjdp.      struct srec_data_struct *srec_data;
16733965Sjdp.      struct ihex_data_struct *ihex_data;
16833965Sjdp.      struct tekhex_data_struct *tekhex_data;
16933965Sjdp.      struct elf_obj_tdata *elf_obj_data;
17033965Sjdp.      struct nlm_obj_tdata *nlm_obj_data;
17133965Sjdp.      struct bout_data_struct *bout_data;
17289857Sobrien.      struct mmo_data_struct *mmo_data;
17333965Sjdp.      struct sun_core_struct *sun_core_data;
17460484Sobrien.      struct sco5_core_struct *sco5_core_data;
17533965Sjdp.      struct trad_core_struct *trad_core_data;
17633965Sjdp.      struct som_data_struct *som_data;
17733965Sjdp.      struct hpux_core_struct *hpux_core_data;
17833965Sjdp.      struct hppabsd_core_struct *hppabsd_core_data;
17933965Sjdp.      struct sgi_core_struct *sgi_core_data;
18033965Sjdp.      struct lynx_core_struct *lynx_core_data;
18133965Sjdp.      struct osf_core_struct *osf_core_data;
18233965Sjdp.      struct cisco_core_struct *cisco_core_data;
18333965Sjdp.      struct versados_data_struct *versados_data;
18433965Sjdp.      struct netbsd_core_struct *netbsd_core_data;
185130561Sobrien.      struct mach_o_data_struct *mach_o_data;
186130561Sobrien.      struct mach_o_fat_data_struct *mach_o_fat_data;
187130561Sobrien.      struct bfd_pef_data_struct *pef_data;
188130561Sobrien.      struct bfd_pef_xlib_data_struct *pef_xlib_data;
189130561Sobrien.      struct bfd_sym_data_struct *sym_data;
190130561Sobrien.      void *any;
19191041Sobrien.    }
19291041Sobrien.  tdata;
19377298Sobrien.
19491041Sobrien.  {* Used by the application to hold private data.  *}
195130561Sobrien.  void *usrdata;
19633965Sjdp.
19733965Sjdp.  {* Where all the allocated stuff under this BFD goes.  This is a
198130561Sobrien.     struct objalloc *, but we use void * to avoid requiring the inclusion
199130561Sobrien.     of objalloc.h.  *}
200130561Sobrien.  void *memory;
20133965Sjdp.};
20233965Sjdp.
20333965Sjdp*/
20433965Sjdp
205218822Sdim#include "sysdep.h"
206218822Sdim#include <stdarg.h>
20733965Sjdp#include "bfd.h"
208130561Sobrien#include "bfdver.h"
20933965Sjdp#include "libiberty.h"
210218822Sdim#include "demangle.h"
21189857Sobrien#include "safe-ctype.h"
21233965Sjdp#include "bfdlink.h"
21333965Sjdp#include "libbfd.h"
21433965Sjdp#include "coff/internal.h"
21533965Sjdp#include "coff/sym.h"
21633965Sjdp#include "libcoff.h"
21733965Sjdp#include "libecoff.h"
21833965Sjdp#undef obj_symbols
21933965Sjdp#include "elf-bfd.h"
220218822Sdim
221218822Sdim#ifndef EXIT_FAILURE
222218822Sdim#define EXIT_FAILURE 1
223218822Sdim#endif
224218822Sdim
22533965Sjdp
22633965Sjdp/* provide storage for subsystem, stack and heap data which may have been
22733965Sjdp   passed in on the command line.  Ld puts this data into a bfd_link_info
22833965Sjdp   struct which ultimately gets passed in to the bfd.  When it arrives, copy
22933965Sjdp   it to the following struct so that the data will be available in coffcode.h
23033965Sjdp   where it is needed.  The typedef's used are defined in bfd.h */
23133965Sjdp
23233965Sjdp/*
23333965SjdpSECTION
23433965Sjdp	Error reporting
23533965Sjdp
23633965Sjdp	Most BFD functions return nonzero on success (check their
23733965Sjdp	individual documentation for precise semantics).  On an error,
23833965Sjdp	they call <<bfd_set_error>> to set an error condition that callers
23933965Sjdp	can check by calling <<bfd_get_error>>.
24033965Sjdp        If that returns <<bfd_error_system_call>>, then check
24133965Sjdp	<<errno>>.
24233965Sjdp
24333965Sjdp	The easiest way to report a BFD error to the user is to
24433965Sjdp	use <<bfd_perror>>.
24533965Sjdp
24633965SjdpSUBSECTION
24733965Sjdp	Type <<bfd_error_type>>
24833965Sjdp
24933965Sjdp	The values returned by <<bfd_get_error>> are defined by the
25033965Sjdp	enumerated type <<bfd_error_type>>.
25133965Sjdp
25233965SjdpCODE_FRAGMENT
25333965Sjdp.
25433965Sjdp.typedef enum bfd_error
25533965Sjdp.{
25633965Sjdp.  bfd_error_no_error = 0,
25733965Sjdp.  bfd_error_system_call,
25833965Sjdp.  bfd_error_invalid_target,
25933965Sjdp.  bfd_error_wrong_format,
26089857Sobrien.  bfd_error_wrong_object_format,
26133965Sjdp.  bfd_error_invalid_operation,
26233965Sjdp.  bfd_error_no_memory,
26333965Sjdp.  bfd_error_no_symbols,
26433965Sjdp.  bfd_error_no_armap,
26533965Sjdp.  bfd_error_no_more_archived_files,
26633965Sjdp.  bfd_error_malformed_archive,
26733965Sjdp.  bfd_error_file_not_recognized,
26833965Sjdp.  bfd_error_file_ambiguously_recognized,
26933965Sjdp.  bfd_error_no_contents,
27033965Sjdp.  bfd_error_nonrepresentable_section,
27133965Sjdp.  bfd_error_no_debug_section,
27233965Sjdp.  bfd_error_bad_value,
27333965Sjdp.  bfd_error_file_truncated,
27433965Sjdp.  bfd_error_file_too_big,
275218822Sdim.  bfd_error_on_input,
27633965Sjdp.  bfd_error_invalid_error_code
27791041Sobrien.}
27891041Sobrien.bfd_error_type;
27933965Sjdp.
28033965Sjdp*/
28133965Sjdp
28233965Sjdpstatic bfd_error_type bfd_error = bfd_error_no_error;
283218822Sdimstatic bfd *input_bfd = NULL;
284218822Sdimstatic bfd_error_type input_error = bfd_error_no_error;
28533965Sjdp
28689857Sobrienconst char *const bfd_errmsgs[] =
28789857Sobrien{
28889857Sobrien  N_("No error"),
28989857Sobrien  N_("System call error"),
29089857Sobrien  N_("Invalid bfd target"),
29189857Sobrien  N_("File in wrong format"),
29289857Sobrien  N_("Archive object file in wrong format"),
29389857Sobrien  N_("Invalid operation"),
29489857Sobrien  N_("Memory exhausted"),
29589857Sobrien  N_("No symbols"),
29689857Sobrien  N_("Archive has no index; run ranlib to add one"),
29789857Sobrien  N_("No more archived files"),
29889857Sobrien  N_("Malformed archive"),
29989857Sobrien  N_("File format not recognized"),
30089857Sobrien  N_("File format is ambiguous"),
30189857Sobrien  N_("Section has no contents"),
30289857Sobrien  N_("Nonrepresentable section on output"),
30389857Sobrien  N_("Symbol needs debug section which does not exist"),
30489857Sobrien  N_("Bad value"),
30589857Sobrien  N_("File truncated"),
30689857Sobrien  N_("File too big"),
307218822Sdim  N_("Error reading %s: %s"),
30889857Sobrien  N_("#<Invalid error code>")
30989857Sobrien};
31033965Sjdp
31133965Sjdp/*
31233965SjdpFUNCTION
31333965Sjdp	bfd_get_error
31433965Sjdp
31533965SjdpSYNOPSIS
31633965Sjdp	bfd_error_type bfd_get_error (void);
31733965Sjdp
31833965SjdpDESCRIPTION
31933965Sjdp	Return the current BFD error condition.
32033965Sjdp*/
32133965Sjdp
32233965Sjdpbfd_error_type
323130561Sobrienbfd_get_error (void)
32433965Sjdp{
32533965Sjdp  return bfd_error;
32633965Sjdp}
32733965Sjdp
32833965Sjdp/*
32933965SjdpFUNCTION
33033965Sjdp	bfd_set_error
33133965Sjdp
33233965SjdpSYNOPSIS
333218822Sdim	void bfd_set_error (bfd_error_type error_tag, ...);
33433965Sjdp
33533965SjdpDESCRIPTION
33633965Sjdp	Set the BFD error condition to be @var{error_tag}.
337218822Sdim	If @var{error_tag} is bfd_error_on_input, then this function
338218822Sdim	takes two more parameters, the input bfd where the error
339218822Sdim	occurred, and the bfd_error_type error.
34033965Sjdp*/
34133965Sjdp
34233965Sjdpvoid
343218822Sdimbfd_set_error (bfd_error_type error_tag, ...)
34433965Sjdp{
34533965Sjdp  bfd_error = error_tag;
346218822Sdim  if (error_tag == bfd_error_on_input)
347218822Sdim    {
348218822Sdim      /* This is an error that occurred during bfd_close when
349218822Sdim	 writing an archive, but on one of the input files.  */
350218822Sdim      va_list ap;
351218822Sdim
352218822Sdim      va_start (ap, error_tag);
353218822Sdim      input_bfd = va_arg (ap, bfd *);
354218822Sdim      input_error = va_arg (ap, int);
355218822Sdim      if (input_error >= bfd_error_on_input)
356218822Sdim	abort ();
357218822Sdim      va_end (ap);
358218822Sdim    }
35933965Sjdp}
36033965Sjdp
36133965Sjdp/*
36233965SjdpFUNCTION
36333965Sjdp	bfd_errmsg
36433965Sjdp
36533965SjdpSYNOPSIS
36689857Sobrien	const char *bfd_errmsg (bfd_error_type error_tag);
36733965Sjdp
36833965SjdpDESCRIPTION
36933965Sjdp	Return a string describing the error @var{error_tag}, or
37033965Sjdp	the system error if @var{error_tag} is <<bfd_error_system_call>>.
37133965Sjdp*/
37233965Sjdp
37389857Sobrienconst char *
374130561Sobrienbfd_errmsg (bfd_error_type error_tag)
37533965Sjdp{
37633965Sjdp#ifndef errno
37733965Sjdp  extern int errno;
37833965Sjdp#endif
379218822Sdim  if (error_tag == bfd_error_on_input)
380218822Sdim    {
381218822Sdim      char *buf;
382218822Sdim      const char *msg = bfd_errmsg (input_error);
383218822Sdim
384218822Sdim      if (asprintf (&buf, _(bfd_errmsgs [error_tag]), input_bfd->filename, msg)
385218822Sdim	  != -1)
386218822Sdim	return buf;
387218822Sdim
388218822Sdim      /* Ick, what to do on out of memory?  */
389218822Sdim      return msg;
390218822Sdim    }
391218822Sdim
39233965Sjdp  if (error_tag == bfd_error_system_call)
39333965Sjdp    return xstrerror (errno);
39433965Sjdp
395130561Sobrien  if (error_tag > bfd_error_invalid_error_code)
396130561Sobrien    error_tag = bfd_error_invalid_error_code;	/* sanity check */
39733965Sjdp
398130561Sobrien  return _(bfd_errmsgs [error_tag]);
39933965Sjdp}
40033965Sjdp
40133965Sjdp/*
40233965SjdpFUNCTION
40333965Sjdp	bfd_perror
40433965Sjdp
40533965SjdpSYNOPSIS
40689857Sobrien	void bfd_perror (const char *message);
40733965Sjdp
40833965SjdpDESCRIPTION
40933965Sjdp	Print to the standard error stream a string describing the
41033965Sjdp	last BFD error that occurred, or the last system error if
41133965Sjdp	the last BFD error was a system call failure.  If @var{message}
41233965Sjdp	is non-NULL and non-empty, the error string printed is preceded
41333965Sjdp	by @var{message}, a colon, and a space.  It is followed by a newline.
41433965Sjdp*/
41533965Sjdp
41633965Sjdpvoid
417130561Sobrienbfd_perror (const char *message)
41833965Sjdp{
419218822Sdim  if (message == NULL || *message == '\0')
420218822Sdim    fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ()));
42189857Sobrien  else
422218822Sdim    fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ()));
42333965Sjdp}
42433965Sjdp
42533965Sjdp/*
42633965SjdpSUBSECTION
42733965Sjdp	BFD error handler
42833965Sjdp
42933965Sjdp	Some BFD functions want to print messages describing the
43033965Sjdp	problem.  They call a BFD error handler function.  This
431130561Sobrien	function may be overridden by the program.
43233965Sjdp
43333965Sjdp	The BFD error handler acts like printf.
43433965Sjdp
43533965SjdpCODE_FRAGMENT
43633965Sjdp.
437130561Sobrien.typedef void (*bfd_error_handler_type) (const char *, ...);
43833965Sjdp.
43933965Sjdp*/
44033965Sjdp
44133965Sjdp/* The program name used when printing BFD error messages.  */
44233965Sjdp
44333965Sjdpstatic const char *_bfd_error_program_name;
44433965Sjdp
445218822Sdim/* This is the default routine to handle BFD error messages.
446218822Sdim   Like fprintf (stderr, ...), but also handles some extra format specifiers.
44733965Sjdp
448218822Sdim   %A section name from section.  For group components, print group name too.
449218822Sdim   %B file name from bfd.  For archive components, prints archive too.
450218822Sdim
451218822Sdim   Note - because these two extra format specifiers require special handling
452218822Sdim   they are scanned for and processed in this function, before calling
453218822Sdim   vfprintf.  This means that the *arguments* for these format specifiers
454218822Sdim   must be the first ones in the variable argument list, regardless of where
455218822Sdim   the specifiers appear in the format string.  Thus for example calling
456218822Sdim   this function with a format string of:
457218822Sdim
458218822Sdim      "blah %s blah %A blah %d blah %B"
459218822Sdim
460218822Sdim   would involve passing the arguments as:
461218822Sdim
462218822Sdim      "blah %s blah %A blah %d blah %B",
463218822Sdim        asection_for_the_%A,
464218822Sdim	bfd_for_the_%B,
465218822Sdim	string_for_the_%s,
466218822Sdim	integer_for_the_%d);
467218822Sdim */
468218822Sdim
469218822Sdimvoid
470218822Sdim_bfd_default_error_handler (const char *fmt, ...)
47133965Sjdp{
472218822Sdim  va_list ap;
473218822Sdim  char *bufp;
474218822Sdim  const char *new_fmt, *p;
475218822Sdim  size_t avail = 1000;
476218822Sdim  char buf[1000];
477130561Sobrien
47833965Sjdp  if (_bfd_error_program_name != NULL)
47933965Sjdp    fprintf (stderr, "%s: ", _bfd_error_program_name);
48033965Sjdp  else
48133965Sjdp    fprintf (stderr, "BFD: ");
48233965Sjdp
483218822Sdim  va_start (ap, fmt);
484218822Sdim  new_fmt = fmt;
485218822Sdim  bufp = buf;
48633965Sjdp
487218822Sdim  /* Reserve enough space for the existing format string.  */
488218822Sdim  avail -= strlen (fmt) + 1;
489218822Sdim  if (avail > 1000)
490218822Sdim    _exit (EXIT_FAILURE);
491218822Sdim
492218822Sdim  p = fmt;
493218822Sdim  while (1)
494218822Sdim    {
495218822Sdim      char *q;
496218822Sdim      size_t len, extra, trim;
497218822Sdim
498218822Sdim      p = strchr (p, '%');
499218822Sdim      if (p == NULL || p[1] == '\0')
500218822Sdim	{
501218822Sdim	  if (new_fmt == buf)
502218822Sdim	    {
503218822Sdim	      len = strlen (fmt);
504218822Sdim	      memcpy (bufp, fmt, len + 1);
505218822Sdim	    }
506218822Sdim	  break;
507218822Sdim	}
508218822Sdim
509218822Sdim      if (p[1] == 'A' || p[1] == 'B')
510218822Sdim	{
511218822Sdim	  len = p - fmt;
512218822Sdim	  memcpy (bufp, fmt, len);
513218822Sdim	  bufp += len;
514218822Sdim	  fmt = p + 2;
515218822Sdim	  new_fmt = buf;
516218822Sdim
517218822Sdim	  /* If we run out of space, tough, you lose your ridiculously
518218822Sdim	     long file or section name.  It's not safe to try to alloc
519218822Sdim	     memory here;  We might be printing an out of memory message.  */
520218822Sdim	  if (avail == 0)
521218822Sdim	    {
522218822Sdim	      *bufp++ = '*';
523218822Sdim	      *bufp++ = '*';
524218822Sdim	      *bufp = '\0';
525218822Sdim	    }
526218822Sdim	  else
527218822Sdim	    {
528218822Sdim	      if (p[1] == 'B')
529218822Sdim		{
530218822Sdim		  bfd *abfd = va_arg (ap, bfd *);
531218822Sdim
532218822Sdim		  if (abfd == NULL)
533218822Sdim		    /* Invoking %B with a null bfd pointer is an internal error.  */
534218822Sdim		    abort ();
535218822Sdim		  else if (abfd->my_archive)
536218822Sdim		    snprintf (bufp, avail, "%s(%s)",
537218822Sdim			      abfd->my_archive->filename, abfd->filename);
538218822Sdim		  else
539218822Sdim		    snprintf (bufp, avail, "%s", abfd->filename);
540218822Sdim		}
541218822Sdim	      else
542218822Sdim		{
543218822Sdim		  asection *sec = va_arg (ap, asection *);
544218822Sdim		  bfd *abfd;
545218822Sdim		  const char *group = NULL;
546218822Sdim		  struct coff_comdat_info *ci;
547218822Sdim
548218822Sdim		  if (sec == NULL)
549218822Sdim		    /* Invoking %A with a null section pointer is an internal error.  */
550218822Sdim		    abort ();
551218822Sdim		  abfd = sec->owner;
552218822Sdim		  if (abfd != NULL
553218822Sdim		      && bfd_get_flavour (abfd) == bfd_target_elf_flavour
554218822Sdim		      && elf_next_in_group (sec) != NULL
555218822Sdim		      && (sec->flags & SEC_GROUP) == 0)
556218822Sdim		    group = elf_group_name (sec);
557218822Sdim		  else if (abfd != NULL
558218822Sdim			   && bfd_get_flavour (abfd) == bfd_target_coff_flavour
559218822Sdim			   && (ci = bfd_coff_get_comdat_section (sec->owner,
560218822Sdim								 sec)) != NULL)
561218822Sdim		    group = ci->name;
562218822Sdim		  if (group != NULL)
563218822Sdim		    snprintf (bufp, avail, "%s[%s]", sec->name, group);
564218822Sdim		  else
565218822Sdim		    snprintf (bufp, avail, "%s", sec->name);
566218822Sdim		}
567218822Sdim	      len = strlen (bufp);
568218822Sdim	      avail = avail - len + 2;
569218822Sdim
570218822Sdim	      /* We need to replace any '%' we printed by "%%".
571218822Sdim		 First count how many.  */
572218822Sdim	      q = bufp;
573218822Sdim	      bufp += len;
574218822Sdim	      extra = 0;
575218822Sdim	      while ((q = strchr (q, '%')) != NULL)
576218822Sdim		{
577218822Sdim		  ++q;
578218822Sdim		  ++extra;
579218822Sdim		}
580218822Sdim
581218822Sdim	      /* If there isn't room, trim off the end of the string.  */
582218822Sdim	      q = bufp;
583218822Sdim	      bufp += extra;
584218822Sdim	      if (extra > avail)
585218822Sdim		{
586218822Sdim		  trim = extra - avail;
587218822Sdim		  bufp -= trim;
588218822Sdim		  do
589218822Sdim		    {
590218822Sdim		      if (*--q == '%')
591218822Sdim			--extra;
592218822Sdim		    }
593218822Sdim		  while (--trim != 0);
594218822Sdim		  *q = '\0';
595218822Sdim		  avail = extra;
596218822Sdim		}
597218822Sdim	      avail -= extra;
598218822Sdim
599218822Sdim	      /* Now double all '%' chars, shuffling the string as we go.  */
600218822Sdim	      while (extra != 0)
601218822Sdim		{
602218822Sdim		  while ((q[extra] = *q) != '%')
603218822Sdim		    --q;
604218822Sdim		  q[--extra] = '%';
605218822Sdim		  --q;
606218822Sdim		}
607218822Sdim	    }
608218822Sdim	}
609218822Sdim      p = p + 2;
610218822Sdim    }
611218822Sdim
612218822Sdim  vfprintf (stderr, new_fmt, ap);
613218822Sdim  va_end (ap);
614218822Sdim
615218822Sdim  putc ('\n', stderr);
61633965Sjdp}
61733965Sjdp
61833965Sjdp/* This is a function pointer to the routine which should handle BFD
61933965Sjdp   error messages.  It is called when a BFD routine encounters an
62033965Sjdp   error for which it wants to print a message.  Going through a
62133965Sjdp   function pointer permits a program linked against BFD to intercept
62233965Sjdp   the messages and deal with them itself.  */
62333965Sjdp
62433965Sjdpbfd_error_handler_type _bfd_error_handler = _bfd_default_error_handler;
62533965Sjdp
62633965Sjdp/*
62733965SjdpFUNCTION
62833965Sjdp	bfd_set_error_handler
62933965Sjdp
63033965SjdpSYNOPSIS
63133965Sjdp	bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);
63233965Sjdp
63333965SjdpDESCRIPTION
63433965Sjdp	Set the BFD error handler function.  Returns the previous
63533965Sjdp	function.
63633965Sjdp*/
63733965Sjdp
63833965Sjdpbfd_error_handler_type
639130561Sobrienbfd_set_error_handler (bfd_error_handler_type pnew)
64033965Sjdp{
64133965Sjdp  bfd_error_handler_type pold;
64233965Sjdp
64333965Sjdp  pold = _bfd_error_handler;
64433965Sjdp  _bfd_error_handler = pnew;
64533965Sjdp  return pold;
64633965Sjdp}
64733965Sjdp
64833965Sjdp/*
64933965SjdpFUNCTION
65033965Sjdp	bfd_set_error_program_name
65133965Sjdp
65233965SjdpSYNOPSIS
65333965Sjdp	void bfd_set_error_program_name (const char *);
65433965Sjdp
65533965SjdpDESCRIPTION
65633965Sjdp	Set the program name to use when printing a BFD error.  This
65733965Sjdp	is printed before the error message followed by a colon and
65833965Sjdp	space.  The string must not be changed after it is passed to
65933965Sjdp	this function.
66033965Sjdp*/
66133965Sjdp
66233965Sjdpvoid
663130561Sobrienbfd_set_error_program_name (const char *name)
66433965Sjdp{
66533965Sjdp  _bfd_error_program_name = name;
66633965Sjdp}
66738889Sjdp
66838889Sjdp/*
66938889SjdpFUNCTION
67038889Sjdp	bfd_get_error_handler
67138889Sjdp
67238889SjdpSYNOPSIS
67338889Sjdp	bfd_error_handler_type bfd_get_error_handler (void);
67438889Sjdp
67538889SjdpDESCRIPTION
67638889Sjdp	Return the BFD error handler function.
67738889Sjdp*/
67838889Sjdp
67938889Sjdpbfd_error_handler_type
680130561Sobrienbfd_get_error_handler (void)
68138889Sjdp{
68238889Sjdp  return _bfd_error_handler;
68338889Sjdp}
68433965Sjdp
68533965Sjdp/*
68633965SjdpSECTION
687218822Sdim	Miscellaneous
688218822Sdim
689218822SdimSUBSECTION
690218822Sdim	Miscellaneous functions
69133965Sjdp*/
69233965Sjdp
69333965Sjdp/*
69433965SjdpFUNCTION
69533965Sjdp	bfd_get_reloc_upper_bound
69633965Sjdp
69733965SjdpSYNOPSIS
698130561Sobrien	long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);
69933965Sjdp
70033965SjdpDESCRIPTION
70133965Sjdp	Return the number of bytes required to store the
70233965Sjdp	relocation information associated with section @var{sect}
70333965Sjdp	attached to bfd @var{abfd}.  If an error occurs, return -1.
70433965Sjdp
70533965Sjdp*/
70633965Sjdp
70733965Sjdplong
708130561Sobrienbfd_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
70933965Sjdp{
71089857Sobrien  if (abfd->format != bfd_object)
71189857Sobrien    {
71289857Sobrien      bfd_set_error (bfd_error_invalid_operation);
71389857Sobrien      return -1;
71489857Sobrien    }
71533965Sjdp
71633965Sjdp  return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
71733965Sjdp}
71833965Sjdp
71933965Sjdp/*
72033965SjdpFUNCTION
72133965Sjdp	bfd_canonicalize_reloc
72233965Sjdp
72333965SjdpSYNOPSIS
72433965Sjdp	long bfd_canonicalize_reloc
725130561Sobrien	  (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);
72633965Sjdp
72733965SjdpDESCRIPTION
72833965Sjdp	Call the back end associated with the open BFD
72933965Sjdp	@var{abfd} and translate the external form of the relocation
73033965Sjdp	information attached to @var{sec} into the internal canonical
73133965Sjdp	form.  Place the table into memory at @var{loc}, which has
73233965Sjdp	been preallocated, usually by a call to
73333965Sjdp	<<bfd_get_reloc_upper_bound>>.  Returns the number of relocs, or
73433965Sjdp	-1 on error.
73533965Sjdp
73633965Sjdp	The @var{syms} table is also needed for horrible internal magic
73733965Sjdp	reasons.
73833965Sjdp
73933965Sjdp*/
74033965Sjdplong
741130561Sobrienbfd_canonicalize_reloc (bfd *abfd,
742130561Sobrien			sec_ptr asect,
743130561Sobrien			arelent **location,
744130561Sobrien			asymbol **symbols)
74533965Sjdp{
74689857Sobrien  if (abfd->format != bfd_object)
74789857Sobrien    {
74889857Sobrien      bfd_set_error (bfd_error_invalid_operation);
74989857Sobrien      return -1;
75089857Sobrien    }
75189857Sobrien
75233965Sjdp  return BFD_SEND (abfd, _bfd_canonicalize_reloc,
75333965Sjdp		   (abfd, asect, location, symbols));
75433965Sjdp}
75533965Sjdp
75633965Sjdp/*
75733965SjdpFUNCTION
75833965Sjdp	bfd_set_reloc
75933965Sjdp
76033965SjdpSYNOPSIS
76133965Sjdp	void bfd_set_reloc
76291041Sobrien	  (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
76333965Sjdp
76433965SjdpDESCRIPTION
76533965Sjdp	Set the relocation pointer and count within
76633965Sjdp	section @var{sec} to the values @var{rel} and @var{count}.
76733965Sjdp	The argument @var{abfd} is ignored.
76833965Sjdp
76933965Sjdp*/
77077298Sobrien
77133965Sjdpvoid
772130561Sobrienbfd_set_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED,
773130561Sobrien	       sec_ptr asect,
774130561Sobrien	       arelent **location,
775130561Sobrien	       unsigned int count)
77633965Sjdp{
77733965Sjdp  asect->orelocation = location;
77833965Sjdp  asect->reloc_count = count;
77933965Sjdp}
78033965Sjdp
78133965Sjdp/*
78233965SjdpFUNCTION
78333965Sjdp	bfd_set_file_flags
78433965Sjdp
78533965SjdpSYNOPSIS
786130561Sobrien	bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags);
78733965Sjdp
78833965SjdpDESCRIPTION
78933965Sjdp	Set the flag word in the BFD @var{abfd} to the value @var{flags}.
79033965Sjdp
79133965Sjdp	Possible errors are:
79233965Sjdp	o <<bfd_error_wrong_format>> - The target bfd was not of object format.
79333965Sjdp	o <<bfd_error_invalid_operation>> - The target bfd was open for reading.
79433965Sjdp	o <<bfd_error_invalid_operation>> -
79533965Sjdp	The flag word contained a bit which was not applicable to the
79633965Sjdp	type of file.  E.g., an attempt was made to set the <<D_PAGED>> bit
79733965Sjdp	on a BFD format which does not support demand paging.
79833965Sjdp
79933965Sjdp*/
80033965Sjdp
801130561Sobrienbfd_boolean
802130561Sobrienbfd_set_file_flags (bfd *abfd, flagword flags)
80333965Sjdp{
80489857Sobrien  if (abfd->format != bfd_object)
80589857Sobrien    {
80689857Sobrien      bfd_set_error (bfd_error_wrong_format);
807130561Sobrien      return FALSE;
80889857Sobrien    }
80933965Sjdp
81089857Sobrien  if (bfd_read_p (abfd))
81189857Sobrien    {
81289857Sobrien      bfd_set_error (bfd_error_invalid_operation);
813130561Sobrien      return FALSE;
81489857Sobrien    }
81533965Sjdp
81633965Sjdp  bfd_get_file_flags (abfd) = flags;
81789857Sobrien  if ((flags & bfd_applicable_file_flags (abfd)) != flags)
81889857Sobrien    {
81989857Sobrien      bfd_set_error (bfd_error_invalid_operation);
820130561Sobrien      return FALSE;
82189857Sobrien    }
82233965Sjdp
823130561Sobrien  return TRUE;
82433965Sjdp}
82533965Sjdp
82633965Sjdpvoid
827130561Sobrienbfd_assert (const char *file, int line)
82833965Sjdp{
82989857Sobrien  (*_bfd_error_handler) (_("BFD %s assertion fail %s:%d"),
83089857Sobrien			 BFD_VERSION_STRING, file, line);
83133965Sjdp}
83233965Sjdp
83360484Sobrien/* A more or less friendly abort message.  In libbfd.h abort is
83460484Sobrien   defined to call this function.  */
83533965Sjdp
83660484Sobrienvoid
837130561Sobrien_bfd_abort (const char *file, int line, const char *fn)
83860484Sobrien{
83960484Sobrien  if (fn != NULL)
84060484Sobrien    (*_bfd_error_handler)
84189857Sobrien      (_("BFD %s internal error, aborting at %s line %d in %s\n"),
84289857Sobrien       BFD_VERSION_STRING, file, line, fn);
84360484Sobrien  else
84460484Sobrien    (*_bfd_error_handler)
84589857Sobrien      (_("BFD %s internal error, aborting at %s line %d\n"),
84689857Sobrien       BFD_VERSION_STRING, file, line);
84760484Sobrien  (*_bfd_error_handler) (_("Please report this bug.\n"));
848218822Sdim  _exit (EXIT_FAILURE);
84960484Sobrien}
85060484Sobrien
85133965Sjdp/*
85233965SjdpFUNCTION
85377298Sobrien	bfd_get_arch_size
85477298Sobrien
85577298SobrienSYNOPSIS
85677298Sobrien 	int bfd_get_arch_size (bfd *abfd);
85777298Sobrien
85877298SobrienDESCRIPTION
85977298Sobrien	Returns the architecture address size, in bits, as determined
86077298Sobrien	by the object file's format.  For ELF, this information is
86177298Sobrien	included in the header.
86277298Sobrien
86377298SobrienRETURNS
86477298Sobrien	Returns the arch size in bits if known, <<-1>> otherwise.
86577298Sobrien*/
86677298Sobrien
86777298Sobrienint
868130561Sobrienbfd_get_arch_size (bfd *abfd)
86977298Sobrien{
87077298Sobrien  if (abfd->xvec->flavour == bfd_target_elf_flavour)
871130561Sobrien    return get_elf_backend_data (abfd)->s->arch_size;
87277298Sobrien
87377298Sobrien  return -1;
87477298Sobrien}
87577298Sobrien
87677298Sobrien/*
87777298SobrienFUNCTION
87877298Sobrien	bfd_get_sign_extend_vma
87977298Sobrien
88077298SobrienSYNOPSIS
88177298Sobrien 	int bfd_get_sign_extend_vma (bfd *abfd);
88277298Sobrien
88377298SobrienDESCRIPTION
88477298Sobrien	Indicates if the target architecture "naturally" sign extends
88577298Sobrien	an address.  Some architectures implicitly sign extend address
88677298Sobrien	values when they are converted to types larger than the size
88777298Sobrien	of an address.  For instance, bfd_get_start_address() will
88877298Sobrien	return an address sign extended to fill a bfd_vma when this is
88977298Sobrien	the case.
89077298Sobrien
89177298SobrienRETURNS
89277298Sobrien	Returns <<1>> if the target architecture is known to sign
89377298Sobrien	extend addresses, <<0>> if the target architecture is known to
89477298Sobrien	not sign extend addresses, and <<-1>> otherwise.
89577298Sobrien*/
89677298Sobrien
89777298Sobrienint
898130561Sobrienbfd_get_sign_extend_vma (bfd *abfd)
89977298Sobrien{
90089857Sobrien  char *name;
90189857Sobrien
90277298Sobrien  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
903130561Sobrien    return get_elf_backend_data (abfd)->sign_extend_vma;
90477298Sobrien
90589857Sobrien  name = bfd_get_target (abfd);
90689857Sobrien
907218822Sdim  /* Return a proper value for DJGPP & PE COFF.
90889857Sobrien     This function is required for DWARF2 support, but there is
90989857Sobrien     no place to store this information in the COFF back end.
91089857Sobrien     Should enough other COFF targets add support for DWARF2,
91189857Sobrien     a place will have to be found.  Until then, this hack will do.  */
912218822Sdim  if (CONST_STRNEQ (name, "coff-go32")
913218822Sdim      || strcmp (name, "pe-i386") == 0
914218822Sdim      || strcmp (name, "pei-i386") == 0
915218822Sdim      || strcmp (name, "pe-arm-wince-little") == 0
916218822Sdim      || strcmp (name, "pei-arm-wince-little") == 0)
91789857Sobrien    return 1;
91889857Sobrien
91977298Sobrien  bfd_set_error (bfd_error_wrong_format);
92077298Sobrien  return -1;
92177298Sobrien}
92277298Sobrien
92377298Sobrien/*
92477298SobrienFUNCTION
92533965Sjdp	bfd_set_start_address
92633965Sjdp
92733965SjdpSYNOPSIS
928130561Sobrien 	bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma);
92933965Sjdp
93033965SjdpDESCRIPTION
93133965Sjdp	Make @var{vma} the entry point of output BFD @var{abfd}.
93233965Sjdp
93333965SjdpRETURNS
934130561Sobrien	Returns <<TRUE>> on success, <<FALSE>> otherwise.
93533965Sjdp*/
93633965Sjdp
937130561Sobrienbfd_boolean
938130561Sobrienbfd_set_start_address (bfd *abfd, bfd_vma vma)
93933965Sjdp{
94033965Sjdp  abfd->start_address = vma;
941130561Sobrien  return TRUE;
94233965Sjdp}
94333965Sjdp
94433965Sjdp/*
94533965SjdpFUNCTION
94633965Sjdp	bfd_get_gp_size
94733965Sjdp
94833965SjdpSYNOPSIS
949130561Sobrien	unsigned int bfd_get_gp_size (bfd *abfd);
95033965Sjdp
95133965SjdpDESCRIPTION
95233965Sjdp	Return the maximum size of objects to be optimized using the GP
95333965Sjdp	register under MIPS ECOFF.  This is typically set by the <<-G>>
95433965Sjdp	argument to the compiler, assembler or linker.
95533965Sjdp*/
95633965Sjdp
95789857Sobrienunsigned int
958130561Sobrienbfd_get_gp_size (bfd *abfd)
95933965Sjdp{
96033965Sjdp  if (abfd->format == bfd_object)
96133965Sjdp    {
96233965Sjdp      if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
96333965Sjdp	return ecoff_data (abfd)->gp_size;
96433965Sjdp      else if (abfd->xvec->flavour == bfd_target_elf_flavour)
96533965Sjdp	return elf_gp_size (abfd);
96633965Sjdp    }
96733965Sjdp  return 0;
96833965Sjdp}
96933965Sjdp
97033965Sjdp/*
97133965SjdpFUNCTION
97233965Sjdp	bfd_set_gp_size
97333965Sjdp
97433965SjdpSYNOPSIS
975130561Sobrien	void bfd_set_gp_size (bfd *abfd, unsigned int i);
97633965Sjdp
97733965SjdpDESCRIPTION
97833965Sjdp	Set the maximum size of objects to be optimized using the GP
97933965Sjdp	register under ECOFF or MIPS ELF.  This is typically set by
98033965Sjdp	the <<-G>> argument to the compiler, assembler or linker.
98133965Sjdp*/
98233965Sjdp
98333965Sjdpvoid
984130561Sobrienbfd_set_gp_size (bfd *abfd, unsigned int i)
98533965Sjdp{
98689857Sobrien  /* Don't try to set GP size on an archive or core file!  */
98733965Sjdp  if (abfd->format != bfd_object)
98833965Sjdp    return;
98989857Sobrien
99033965Sjdp  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
99133965Sjdp    ecoff_data (abfd)->gp_size = i;
99233965Sjdp  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
99333965Sjdp    elf_gp_size (abfd) = i;
99433965Sjdp}
99533965Sjdp
99633965Sjdp/* Get the GP value.  This is an internal function used by some of the
99733965Sjdp   relocation special_function routines on targets which support a GP
99833965Sjdp   register.  */
99933965Sjdp
100033965Sjdpbfd_vma
1001130561Sobrien_bfd_get_gp_value (bfd *abfd)
100233965Sjdp{
1003130561Sobrien  if (! abfd)
1004130561Sobrien    return 0;
100589857Sobrien  if (abfd->format != bfd_object)
100689857Sobrien    return 0;
100789857Sobrien
100889857Sobrien  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
100989857Sobrien    return ecoff_data (abfd)->gp;
101089857Sobrien  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
101189857Sobrien    return elf_gp (abfd);
101289857Sobrien
101333965Sjdp  return 0;
101433965Sjdp}
101533965Sjdp
101633965Sjdp/* Set the GP value.  */
101733965Sjdp
101833965Sjdpvoid
1019130561Sobrien_bfd_set_gp_value (bfd *abfd, bfd_vma v)
102033965Sjdp{
1021130561Sobrien  if (! abfd)
1022130561Sobrien    BFD_FAIL ();
102333965Sjdp  if (abfd->format != bfd_object)
102433965Sjdp    return;
102589857Sobrien
102633965Sjdp  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
102733965Sjdp    ecoff_data (abfd)->gp = v;
102833965Sjdp  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
102933965Sjdp    elf_gp (abfd) = v;
103033965Sjdp}
103133965Sjdp
103233965Sjdp/*
103333965SjdpFUNCTION
103433965Sjdp	bfd_scan_vma
103533965Sjdp
103633965SjdpSYNOPSIS
1037130561Sobrien	bfd_vma bfd_scan_vma (const char *string, const char **end, int base);
103833965Sjdp
103933965SjdpDESCRIPTION
104033965Sjdp	Convert, like <<strtoul>>, a numerical expression
104133965Sjdp	@var{string} into a <<bfd_vma>> integer, and return that integer.
104233965Sjdp	(Though without as many bells and whistles as <<strtoul>>.)
104333965Sjdp	The expression is assumed to be unsigned (i.e., positive).
104433965Sjdp	If given a @var{base}, it is used as the base for conversion.
104533965Sjdp	A base of 0 causes the function to interpret the string
104633965Sjdp	in hex if a leading "0x" or "0X" is found, otherwise
104733965Sjdp	in octal if a leading zero is found, otherwise in decimal.
104833965Sjdp
1049104834Sobrien	If the value would overflow, the maximum <<bfd_vma>> value is
1050104834Sobrien	returned.
105133965Sjdp*/
105233965Sjdp
105333965Sjdpbfd_vma
1054130561Sobrienbfd_scan_vma (const char *string, const char **end, int base)
105533965Sjdp{
105633965Sjdp  bfd_vma value;
1057104834Sobrien  bfd_vma cutoff;
1058104834Sobrien  unsigned int cutlim;
1059104834Sobrien  int overflow;
106033965Sjdp
106133965Sjdp  /* Let the host do it if possible.  */
106277298Sobrien  if (sizeof (bfd_vma) <= sizeof (unsigned long))
1063130561Sobrien    return strtoul (string, (char **) end, base);
106433965Sjdp
1065130561Sobrien#ifdef HAVE_STRTOULL
1066130561Sobrien  if (sizeof (bfd_vma) <= sizeof (unsigned long long))
1067130561Sobrien    return strtoull (string, (char **) end, base);
1068130561Sobrien#endif
1069130561Sobrien
107033965Sjdp  if (base == 0)
107133965Sjdp    {
107233965Sjdp      if (string[0] == '0')
107333965Sjdp	{
107433965Sjdp	  if ((string[1] == 'x') || (string[1] == 'X'))
107533965Sjdp	    base = 16;
107633965Sjdp	  else
107733965Sjdp	    base = 8;
107833965Sjdp	}
107933965Sjdp    }
108089857Sobrien
1081104834Sobrien  if ((base < 2) || (base > 36))
1082104834Sobrien    base = 10;
108377298Sobrien
1084104834Sobrien  if (base == 16
1085104834Sobrien      && string[0] == '0'
1086104834Sobrien      && (string[1] == 'x' || string[1] == 'X')
1087104834Sobrien      && ISXDIGIT (string[2]))
1088104834Sobrien    {
1089104834Sobrien      string += 2;
1090104834Sobrien    }
109133965Sjdp
1092104834Sobrien  cutoff = (~ (bfd_vma) 0) / (bfd_vma) base;
1093104834Sobrien  cutlim = (~ (bfd_vma) 0) % (bfd_vma) base;
1094104834Sobrien  value = 0;
1095104834Sobrien  overflow = 0;
1096104834Sobrien  while (1)
1097104834Sobrien    {
1098104834Sobrien      unsigned int digit;
109933965Sjdp
1100104834Sobrien      digit = *string;
1101104834Sobrien      if (ISDIGIT (digit))
1102104834Sobrien	digit = digit - '0';
1103104834Sobrien      else if (ISALPHA (digit))
1104104834Sobrien	digit = TOUPPER (digit) - 'A' + 10;
1105104834Sobrien      else
1106104834Sobrien	break;
1107104834Sobrien      if (digit >= (unsigned int) base)
1108104834Sobrien	break;
1109104834Sobrien      if (value > cutoff || (value == cutoff && digit > cutlim))
1110104834Sobrien	overflow = 1;
1111104834Sobrien      value = value * base + digit;
1112104834Sobrien      ++string;
1113104834Sobrien    }
111433965Sjdp
1115104834Sobrien  if (overflow)
1116104834Sobrien    value = ~ (bfd_vma) 0;
1117104834Sobrien
1118104834Sobrien  if (end != NULL)
1119104834Sobrien    *end = string;
1120104834Sobrien
112133965Sjdp  return value;
112233965Sjdp}
112333965Sjdp
112433965Sjdp/*
112533965SjdpFUNCTION
1126218822Sdim	bfd_copy_private_header_data
1127218822Sdim
1128218822SdimSYNOPSIS
1129218822Sdim	bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);
1130218822Sdim
1131218822SdimDESCRIPTION
1132218822Sdim	Copy private BFD header information from the BFD @var{ibfd} to the
1133218822Sdim	the BFD @var{obfd}.  This copies information that may require
1134218822Sdim	sections to exist, but does not require symbol tables.  Return
1135218822Sdim	<<true>> on success, <<false>> on error.
1136218822Sdim	Possible error returns are:
1137218822Sdim
1138218822Sdim	o <<bfd_error_no_memory>> -
1139218822Sdim	Not enough memory exists to create private data for @var{obfd}.
1140218822Sdim
1141218822Sdim.#define bfd_copy_private_header_data(ibfd, obfd) \
1142218822Sdim.     BFD_SEND (obfd, _bfd_copy_private_header_data, \
1143218822Sdim.		(ibfd, obfd))
1144218822Sdim
1145218822Sdim*/
1146218822Sdim
1147218822Sdim/*
1148218822SdimFUNCTION
114933965Sjdp	bfd_copy_private_bfd_data
115033965Sjdp
115133965SjdpSYNOPSIS
1152130561Sobrien	bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd);
115333965Sjdp
115433965SjdpDESCRIPTION
115577298Sobrien	Copy private BFD information from the BFD @var{ibfd} to the
1156130561Sobrien	the BFD @var{obfd}.  Return <<TRUE>> on success, <<FALSE>> on error.
115733965Sjdp	Possible error returns are:
115833965Sjdp
115933965Sjdp	o <<bfd_error_no_memory>> -
116033965Sjdp	Not enough memory exists to create private data for @var{obfd}.
116133965Sjdp
116233965Sjdp.#define bfd_copy_private_bfd_data(ibfd, obfd) \
116333965Sjdp.     BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
116433965Sjdp.		(ibfd, obfd))
116533965Sjdp
116633965Sjdp*/
116733965Sjdp
116833965Sjdp/*
116933965SjdpFUNCTION
117033965Sjdp	bfd_merge_private_bfd_data
117133965Sjdp
117233965SjdpSYNOPSIS
1173130561Sobrien	bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd);
117433965Sjdp
117533965SjdpDESCRIPTION
117677298Sobrien	Merge private BFD information from the BFD @var{ibfd} to the
1177130561Sobrien	the output file BFD @var{obfd} when linking.  Return <<TRUE>>
1178130561Sobrien	on success, <<FALSE>> on error.  Possible error returns are:
117933965Sjdp
118033965Sjdp	o <<bfd_error_no_memory>> -
118133965Sjdp	Not enough memory exists to create private data for @var{obfd}.
118233965Sjdp
118333965Sjdp.#define bfd_merge_private_bfd_data(ibfd, obfd) \
118433965Sjdp.     BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
118533965Sjdp.		(ibfd, obfd))
118633965Sjdp
118733965Sjdp*/
118833965Sjdp
118933965Sjdp/*
119033965SjdpFUNCTION
119133965Sjdp	bfd_set_private_flags
119233965Sjdp
119333965SjdpSYNOPSIS
1194130561Sobrien	bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
119533965Sjdp
119633965SjdpDESCRIPTION
119733965Sjdp	Set private BFD flag information in the BFD @var{abfd}.
1198130561Sobrien	Return <<TRUE>> on success, <<FALSE>> on error.  Possible error
119933965Sjdp	returns are:
120033965Sjdp
120133965Sjdp	o <<bfd_error_no_memory>> -
120233965Sjdp	Not enough memory exists to create private data for @var{obfd}.
120333965Sjdp
120433965Sjdp.#define bfd_set_private_flags(abfd, flags) \
1205130561Sobrien.     BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags))
120633965Sjdp
120733965Sjdp*/
120833965Sjdp
120933965Sjdp/*
121033965SjdpFUNCTION
1211130561Sobrien	Other functions
121233965Sjdp
121333965SjdpDESCRIPTION
1214130561Sobrien	The following functions exist but have not yet been documented.
121533965Sjdp
1216218822Sdim.#define bfd_sizeof_headers(abfd, info) \
1217218822Sdim.       BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info))
121833965Sjdp.
121933965Sjdp.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
1220130561Sobrien.       BFD_SEND (abfd, _bfd_find_nearest_line, \
1221130561Sobrien.                 (abfd, sec, syms, off, file, func, line))
122233965Sjdp.
1223218822Sdim.#define bfd_find_line(abfd, syms, sym, file, line) \
1224218822Sdim.       BFD_SEND (abfd, _bfd_find_line, \
1225218822Sdim.                 (abfd, syms, sym, file, line))
1226218822Sdim.
1227218822Sdim.#define bfd_find_inliner_info(abfd, file, func, line) \
1228218822Sdim.       BFD_SEND (abfd, _bfd_find_inliner_info, \
1229218822Sdim.                 (abfd, file, func, line))
1230218822Sdim.
123133965Sjdp.#define bfd_debug_info_start(abfd) \
1232130561Sobrien.       BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
123333965Sjdp.
123433965Sjdp.#define bfd_debug_info_end(abfd) \
1235130561Sobrien.       BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
123633965Sjdp.
123733965Sjdp.#define bfd_debug_info_accumulate(abfd, section) \
1238130561Sobrien.       BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
123933965Sjdp.
124033965Sjdp.#define bfd_stat_arch_elt(abfd, stat) \
1241130561Sobrien.       BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
124233965Sjdp.
124333965Sjdp.#define bfd_update_armap_timestamp(abfd) \
1244130561Sobrien.       BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))
124533965Sjdp.
124633965Sjdp.#define bfd_set_arch_mach(abfd, arch, mach)\
1247130561Sobrien.       BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
124833965Sjdp.
124933965Sjdp.#define bfd_relax_section(abfd, section, link_info, again) \
125033965Sjdp.       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
125133965Sjdp.
125260484Sobrien.#define bfd_gc_sections(abfd, link_info) \
125360484Sobrien.	BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))
125460484Sobrien.
125589857Sobrien.#define bfd_merge_sections(abfd, link_info) \
125689857Sobrien.	BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
125789857Sobrien.
1258218822Sdim.#define bfd_is_group_section(abfd, sec) \
1259218822Sdim.	BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
1260218822Sdim.
1261104834Sobrien.#define bfd_discard_group(abfd, sec) \
1262104834Sobrien.	BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
1263104834Sobrien.
126433965Sjdp.#define bfd_link_hash_table_create(abfd) \
126533965Sjdp.	BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
126633965Sjdp.
1267104834Sobrien.#define bfd_link_hash_table_free(abfd, hash) \
1268104834Sobrien.	BFD_SEND (abfd, _bfd_link_hash_table_free, (hash))
1269104834Sobrien.
127033965Sjdp.#define bfd_link_add_symbols(abfd, info) \
127133965Sjdp.	BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
127233965Sjdp.
1273218822Sdim.#define bfd_link_just_syms(abfd, sec, info) \
1274104834Sobrien.	BFD_SEND (abfd, _bfd_link_just_syms, (sec, info))
1275104834Sobrien.
127633965Sjdp.#define bfd_final_link(abfd, info) \
127733965Sjdp.	BFD_SEND (abfd, _bfd_final_link, (abfd, info))
127833965Sjdp.
127933965Sjdp.#define bfd_free_cached_info(abfd) \
128033965Sjdp.       BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
128133965Sjdp.
128233965Sjdp.#define bfd_get_dynamic_symtab_upper_bound(abfd) \
128333965Sjdp.	BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
128433965Sjdp.
128533965Sjdp.#define bfd_print_private_bfd_data(abfd, file)\
128633965Sjdp.	BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))
128733965Sjdp.
128833965Sjdp.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
128933965Sjdp.	BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
129033965Sjdp.
1291218822Sdim.#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
1292218822Sdim.	BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
1293218822Sdim.						    dyncount, dynsyms, ret))
1294218822Sdim.
129533965Sjdp.#define bfd_get_dynamic_reloc_upper_bound(abfd) \
129633965Sjdp.	BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
129733965Sjdp.
129833965Sjdp.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
129933965Sjdp.	BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
130033965Sjdp.
130133965Sjdp.extern bfd_byte *bfd_get_relocated_section_contents
1302130561Sobrien.  (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
1303130561Sobrien.   bfd_boolean, asymbol **);
130433965Sjdp.
130533965Sjdp
130633965Sjdp*/
130733965Sjdp
130833965Sjdpbfd_byte *
1309130561Sobrienbfd_get_relocated_section_contents (bfd *abfd,
1310130561Sobrien				    struct bfd_link_info *link_info,
1311130561Sobrien				    struct bfd_link_order *link_order,
1312130561Sobrien				    bfd_byte *data,
1313130561Sobrien				    bfd_boolean relocatable,
1314130561Sobrien				    asymbol **symbols)
131533965Sjdp{
131633965Sjdp  bfd *abfd2;
1317130561Sobrien  bfd_byte *(*fn) (bfd *, struct bfd_link_info *, struct bfd_link_order *,
1318130561Sobrien		   bfd_byte *, bfd_boolean, asymbol **);
131933965Sjdp
132033965Sjdp  if (link_order->type == bfd_indirect_link_order)
132133965Sjdp    {
132233965Sjdp      abfd2 = link_order->u.indirect.section->owner;
132389857Sobrien      if (abfd2 == NULL)
132433965Sjdp	abfd2 = abfd;
132533965Sjdp    }
132633965Sjdp  else
132733965Sjdp    abfd2 = abfd;
132889857Sobrien
132933965Sjdp  fn = abfd2->xvec->_bfd_get_relocated_section_contents;
133033965Sjdp
1331130561Sobrien  return (*fn) (abfd, link_info, link_order, data, relocatable, symbols);
133233965Sjdp}
133333965Sjdp
133433965Sjdp/* Record information about an ELF program header.  */
133533965Sjdp
1336130561Sobrienbfd_boolean
1337130561Sobrienbfd_record_phdr (bfd *abfd,
1338130561Sobrien		 unsigned long type,
1339130561Sobrien		 bfd_boolean flags_valid,
1340130561Sobrien		 flagword flags,
1341130561Sobrien		 bfd_boolean at_valid,
1342130561Sobrien		 bfd_vma at,
1343130561Sobrien		 bfd_boolean includes_filehdr,
1344130561Sobrien		 bfd_boolean includes_phdrs,
1345130561Sobrien		 unsigned int count,
1346130561Sobrien		 asection **secs)
134733965Sjdp{
134833965Sjdp  struct elf_segment_map *m, **pm;
134989857Sobrien  bfd_size_type amt;
135033965Sjdp
135133965Sjdp  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
1352130561Sobrien    return TRUE;
135333965Sjdp
135489857Sobrien  amt = sizeof (struct elf_segment_map);
135589857Sobrien  amt += ((bfd_size_type) count - 1) * sizeof (asection *);
1356218822Sdim  m = bfd_zalloc (abfd, amt);
135733965Sjdp  if (m == NULL)
1358130561Sobrien    return FALSE;
135933965Sjdp
136033965Sjdp  m->p_type = type;
136133965Sjdp  m->p_flags = flags;
136233965Sjdp  m->p_paddr = at;
1363130561Sobrien  m->p_flags_valid = flags_valid;
1364130561Sobrien  m->p_paddr_valid = at_valid;
1365130561Sobrien  m->includes_filehdr = includes_filehdr;
1366130561Sobrien  m->includes_phdrs = includes_phdrs;
136733965Sjdp  m->count = count;
136833965Sjdp  if (count > 0)
136933965Sjdp    memcpy (m->sections, secs, count * sizeof (asection *));
137033965Sjdp
137133965Sjdp  for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
137233965Sjdp    ;
137333965Sjdp  *pm = m;
137433965Sjdp
1375130561Sobrien  return TRUE;
137633965Sjdp}
137789857Sobrien
137889857Sobrienvoid
1379130561Sobrienbfd_sprintf_vma (bfd *abfd, char *buf, bfd_vma value)
138089857Sobrien{
138189857Sobrien  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
138289857Sobrien    get_elf_backend_data (abfd)->elf_backend_sprintf_vma (abfd, buf, value);
138389857Sobrien  else
138489857Sobrien    sprintf_vma (buf, value);
138589857Sobrien}
138689857Sobrien
138789857Sobrienvoid
1388130561Sobrienbfd_fprintf_vma (bfd *abfd, void *stream, bfd_vma value)
138989857Sobrien{
139089857Sobrien  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
139189857Sobrien    get_elf_backend_data (abfd)->elf_backend_fprintf_vma (abfd, stream, value);
1392218822Sdim#ifdef BFD64
1393218822Sdim  /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit
1394218822Sdim     value, but really we want to display the address in the target's
1395218822Sdim     address size.  Since we do not have a field in the bfd structure
1396218822Sdim     to tell us this, we take a guess, based on the target's name.  */
1397218822Sdim  else if (strstr (bfd_get_target (abfd), "64") == NULL
1398218822Sdim	   && strcmp (bfd_get_target (abfd), "mmo") != 0)
1399218822Sdim    fprintf ((FILE *) stream, "%08lx", (unsigned long) (value & 0xffffffff));
1400218822Sdim#endif
140189857Sobrien  else
140289857Sobrien    fprintf_vma ((FILE *) stream, value);
140389857Sobrien}
140489857Sobrien
140589857Sobrien/*
140689857SobrienFUNCTION
140789857Sobrien	bfd_alt_mach_code
140889857Sobrien
140989857SobrienSYNOPSIS
1410130561Sobrien	bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative);
141189857Sobrien
141289857SobrienDESCRIPTION
141389857Sobrien
141489857Sobrien	When more than one machine code number is available for the
141589857Sobrien	same machine type, this function can be used to switch between
1416104834Sobrien	the preferred one (alternative == 0) and any others.  Currently,
141789857Sobrien	only ELF supports this feature, with up to two alternate
141889857Sobrien	machine codes.
141989857Sobrien*/
142089857Sobrien
1421130561Sobrienbfd_boolean
1422130561Sobrienbfd_alt_mach_code (bfd *abfd, int alternative)
142389857Sobrien{
142489857Sobrien  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
142589857Sobrien    {
142689857Sobrien      int code;
142789857Sobrien
1428104834Sobrien      switch (alternative)
142989857Sobrien	{
143089857Sobrien	case 0:
143189857Sobrien	  code = get_elf_backend_data (abfd)->elf_machine_code;
143289857Sobrien	  break;
143389857Sobrien
143489857Sobrien	case 1:
143589857Sobrien	  code = get_elf_backend_data (abfd)->elf_machine_alt1;
143689857Sobrien	  if (code == 0)
1437130561Sobrien	    return FALSE;
143889857Sobrien	  break;
143989857Sobrien
144089857Sobrien	case 2:
144189857Sobrien	  code = get_elf_backend_data (abfd)->elf_machine_alt2;
144289857Sobrien	  if (code == 0)
1443130561Sobrien	    return FALSE;
144489857Sobrien	  break;
144589857Sobrien
144689857Sobrien	default:
1447130561Sobrien	  return FALSE;
144889857Sobrien	}
144989857Sobrien
145089857Sobrien      elf_elfheader (abfd)->e_machine = code;
145189857Sobrien
1452130561Sobrien      return TRUE;
145389857Sobrien    }
145489857Sobrien
1455130561Sobrien  return FALSE;
145689857Sobrien}
1457130561Sobrien
1458130561Sobrien/*
1459130561SobrienCODE_FRAGMENT
1460130561Sobrien
1461130561Sobrien.struct bfd_preserve
1462130561Sobrien.{
1463130561Sobrien.  void *marker;
1464130561Sobrien.  void *tdata;
1465130561Sobrien.  flagword flags;
1466130561Sobrien.  const struct bfd_arch_info *arch_info;
1467130561Sobrien.  struct bfd_section *sections;
1468218822Sdim.  struct bfd_section *section_last;
1469130561Sobrien.  unsigned int section_count;
1470130561Sobrien.  struct bfd_hash_table section_htab;
1471130561Sobrien.};
1472130561Sobrien.
1473130561Sobrien*/
1474130561Sobrien
1475130561Sobrien/*
1476130561SobrienFUNCTION
1477130561Sobrien	bfd_preserve_save
1478130561Sobrien
1479130561SobrienSYNOPSIS
1480130561Sobrien	bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *);
1481130561Sobrien
1482130561SobrienDESCRIPTION
1483130561Sobrien	When testing an object for compatibility with a particular
1484130561Sobrien	target back-end, the back-end object_p function needs to set
1485130561Sobrien	up certain fields in the bfd on successfully recognizing the
1486130561Sobrien	object.  This typically happens in a piecemeal fashion, with
1487130561Sobrien	failures possible at many points.  On failure, the bfd is
1488130561Sobrien	supposed to be restored to its initial state, which is
1489130561Sobrien	virtually impossible.  However, restoring a subset of the bfd
1490130561Sobrien	state works in practice.  This function stores the subset and
1491130561Sobrien	reinitializes the bfd.
1492130561Sobrien
1493130561Sobrien*/
1494130561Sobrien
1495130561Sobrienbfd_boolean
1496130561Sobrienbfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
1497130561Sobrien{
1498130561Sobrien  preserve->tdata = abfd->tdata.any;
1499130561Sobrien  preserve->arch_info = abfd->arch_info;
1500130561Sobrien  preserve->flags = abfd->flags;
1501130561Sobrien  preserve->sections = abfd->sections;
1502218822Sdim  preserve->section_last = abfd->section_last;
1503130561Sobrien  preserve->section_count = abfd->section_count;
1504130561Sobrien  preserve->section_htab = abfd->section_htab;
1505130561Sobrien
1506218822Sdim  if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
1507218822Sdim			     sizeof (struct section_hash_entry)))
1508130561Sobrien    return FALSE;
1509130561Sobrien
1510130561Sobrien  abfd->tdata.any = NULL;
1511130561Sobrien  abfd->arch_info = &bfd_default_arch_struct;
1512130561Sobrien  abfd->flags &= BFD_IN_MEMORY;
1513130561Sobrien  abfd->sections = NULL;
1514218822Sdim  abfd->section_last = NULL;
1515130561Sobrien  abfd->section_count = 0;
1516130561Sobrien
1517130561Sobrien  return TRUE;
1518130561Sobrien}
1519130561Sobrien
1520130561Sobrien/*
1521130561SobrienFUNCTION
1522130561Sobrien	bfd_preserve_restore
1523130561Sobrien
1524130561SobrienSYNOPSIS
1525130561Sobrien	void bfd_preserve_restore (bfd *, struct bfd_preserve *);
1526130561Sobrien
1527130561SobrienDESCRIPTION
1528130561Sobrien	This function restores bfd state saved by bfd_preserve_save.
1529130561Sobrien	If MARKER is non-NULL in struct bfd_preserve then that block
1530130561Sobrien	and all subsequently bfd_alloc'd memory is freed.
1531130561Sobrien
1532130561Sobrien*/
1533130561Sobrien
1534130561Sobrienvoid
1535130561Sobrienbfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
1536130561Sobrien{
1537130561Sobrien  bfd_hash_table_free (&abfd->section_htab);
1538130561Sobrien
1539130561Sobrien  abfd->tdata.any = preserve->tdata;
1540130561Sobrien  abfd->arch_info = preserve->arch_info;
1541130561Sobrien  abfd->flags = preserve->flags;
1542130561Sobrien  abfd->section_htab = preserve->section_htab;
1543130561Sobrien  abfd->sections = preserve->sections;
1544218822Sdim  abfd->section_last = preserve->section_last;
1545130561Sobrien  abfd->section_count = preserve->section_count;
1546130561Sobrien
1547130561Sobrien  /* bfd_release frees all memory more recently bfd_alloc'd than
1548130561Sobrien     its arg, as well as its arg.  */
1549130561Sobrien  if (preserve->marker != NULL)
1550130561Sobrien    {
1551130561Sobrien      bfd_release (abfd, preserve->marker);
1552130561Sobrien      preserve->marker = NULL;
1553130561Sobrien    }
1554130561Sobrien}
1555130561Sobrien
1556130561Sobrien/*
1557130561SobrienFUNCTION
1558130561Sobrien	bfd_preserve_finish
1559130561Sobrien
1560130561SobrienSYNOPSIS
1561130561Sobrien	void bfd_preserve_finish (bfd *, struct bfd_preserve *);
1562130561Sobrien
1563130561SobrienDESCRIPTION
1564130561Sobrien	This function should be called when the bfd state saved by
1565130561Sobrien	bfd_preserve_save is no longer needed.  ie. when the back-end
1566130561Sobrien	object_p function returns with success.
1567130561Sobrien
1568130561Sobrien*/
1569130561Sobrien
1570130561Sobrienvoid
1571130561Sobrienbfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
1572130561Sobrien{
1573130561Sobrien  /* It would be nice to be able to free more memory here, eg. old
1574130561Sobrien     tdata, but that's not possible since these blocks are sitting
1575130561Sobrien     inside bfd_alloc'd memory.  The section hash is on a separate
1576130561Sobrien     objalloc.  */
1577130561Sobrien  bfd_hash_table_free (&preserve->section_htab);
1578130561Sobrien}
1579218822Sdim
1580218822Sdim/*
1581218822SdimFUNCTION
1582218822Sdim	bfd_emul_get_maxpagesize
1583218822Sdim
1584218822SdimSYNOPSIS
1585218822Sdim 	bfd_vma bfd_emul_get_maxpagesize (const char *);
1586218822Sdim
1587218822SdimDESCRIPTION
1588218822Sdim	Returns the maximum page size, in bytes, as determined by
1589218822Sdim	emulation.
1590218822Sdim
1591218822SdimRETURNS
1592218822Sdim	Returns the maximum page size in bytes for ELF, abort
1593218822Sdim	otherwise.
1594218822Sdim*/
1595218822Sdim
1596218822Sdimbfd_vma
1597218822Sdimbfd_emul_get_maxpagesize (const char *emul)
1598218822Sdim{
1599218822Sdim  const bfd_target *target;
1600218822Sdim
1601218822Sdim  target = bfd_find_target (emul, NULL);
1602218822Sdim  if (target != NULL
1603218822Sdim      && target->flavour == bfd_target_elf_flavour)
1604218822Sdim    return xvec_get_elf_backend_data (target)->maxpagesize;
1605218822Sdim
1606218822Sdim  abort ();
1607218822Sdim  return 0;
1608218822Sdim}
1609218822Sdim
1610218822Sdimstatic void
1611218822Sdimbfd_elf_set_pagesize (const bfd_target *target, bfd_vma size,
1612218822Sdim		      int offset, const bfd_target *orig_target)
1613218822Sdim{
1614218822Sdim  if (target->flavour == bfd_target_elf_flavour)
1615218822Sdim    {
1616218822Sdim      const struct elf_backend_data *bed;
1617218822Sdim
1618218822Sdim      bed = xvec_get_elf_backend_data (target);
1619218822Sdim      *((bfd_vma *) ((char *) bed + offset)) = size;
1620218822Sdim    }
1621218822Sdim
1622218822Sdim  if (target->alternative_target
1623218822Sdim      && target->alternative_target != orig_target)
1624218822Sdim    bfd_elf_set_pagesize (target->alternative_target, size, offset,
1625218822Sdim			  orig_target);
1626218822Sdim}
1627218822Sdim
1628218822Sdim/*
1629218822SdimFUNCTION
1630218822Sdim	bfd_emul_set_maxpagesize
1631218822Sdim
1632218822SdimSYNOPSIS
1633218822Sdim 	void bfd_emul_set_maxpagesize (const char *, bfd_vma);
1634218822Sdim
1635218822SdimDESCRIPTION
1636218822Sdim	For ELF, set the maximum page size for the emulation.  It is
1637218822Sdim	a no-op for other formats.
1638218822Sdim
1639218822Sdim*/
1640218822Sdim
1641218822Sdimvoid
1642218822Sdimbfd_emul_set_maxpagesize (const char *emul, bfd_vma size)
1643218822Sdim{
1644218822Sdim  const bfd_target *target;
1645218822Sdim
1646218822Sdim  target = bfd_find_target (emul, NULL);
1647218822Sdim  if (target)
1648218822Sdim    bfd_elf_set_pagesize (target, size,
1649218822Sdim			  offsetof (struct elf_backend_data,
1650218822Sdim				    maxpagesize), target);
1651218822Sdim}
1652218822Sdim
1653218822Sdim/*
1654218822SdimFUNCTION
1655218822Sdim	bfd_emul_get_commonpagesize
1656218822Sdim
1657218822SdimSYNOPSIS
1658218822Sdim 	bfd_vma bfd_emul_get_commonpagesize (const char *);
1659218822Sdim
1660218822SdimDESCRIPTION
1661218822Sdim	Returns the common page size, in bytes, as determined by
1662218822Sdim	emulation.
1663218822Sdim
1664218822SdimRETURNS
1665218822Sdim	Returns the common page size in bytes for ELF, abort otherwise.
1666218822Sdim*/
1667218822Sdim
1668218822Sdimbfd_vma
1669218822Sdimbfd_emul_get_commonpagesize (const char *emul)
1670218822Sdim{
1671218822Sdim  const bfd_target *target;
1672218822Sdim
1673218822Sdim  target = bfd_find_target (emul, NULL);
1674218822Sdim  if (target != NULL
1675218822Sdim      && target->flavour == bfd_target_elf_flavour)
1676218822Sdim    return xvec_get_elf_backend_data (target)->commonpagesize;
1677218822Sdim
1678218822Sdim  abort ();
1679218822Sdim  return 0;
1680218822Sdim}
1681218822Sdim
1682218822Sdim/*
1683218822SdimFUNCTION
1684218822Sdim	bfd_emul_set_commonpagesize
1685218822Sdim
1686218822SdimSYNOPSIS
1687218822Sdim 	void bfd_emul_set_commonpagesize (const char *, bfd_vma);
1688218822Sdim
1689218822SdimDESCRIPTION
1690218822Sdim	For ELF, set the common page size for the emulation.  It is
1691218822Sdim	a no-op for other formats.
1692218822Sdim
1693218822Sdim*/
1694218822Sdim
1695218822Sdimvoid
1696218822Sdimbfd_emul_set_commonpagesize (const char *emul, bfd_vma size)
1697218822Sdim{
1698218822Sdim  const bfd_target *target;
1699218822Sdim
1700218822Sdim  target = bfd_find_target (emul, NULL);
1701218822Sdim  if (target)
1702218822Sdim    bfd_elf_set_pagesize (target, size,
1703218822Sdim			  offsetof (struct elf_backend_data,
1704218822Sdim				    commonpagesize), target);
1705218822Sdim}
1706218822Sdim
1707218822Sdim/*
1708218822SdimFUNCTION
1709218822Sdim	bfd_demangle
1710218822Sdim
1711218822SdimSYNOPSIS
1712218822Sdim	char *bfd_demangle (bfd *, const char *, int);
1713218822Sdim
1714218822SdimDESCRIPTION
1715218822Sdim	Wrapper around cplus_demangle.  Strips leading underscores and
1716218822Sdim	other such chars that would otherwise confuse the demangler.
1717218822Sdim	If passed a g++ v3 ABI mangled name, returns a buffer allocated
1718218822Sdim	with malloc holding the demangled name.  Returns NULL otherwise
1719218822Sdim	and on memory alloc failure.
1720218822Sdim*/
1721218822Sdim
1722218822Sdimchar *
1723218822Sdimbfd_demangle (bfd *abfd, const char *name, int options)
1724218822Sdim{
1725218822Sdim  char *res, *alloc;
1726218822Sdim  const char *pre, *suf;
1727218822Sdim  size_t pre_len;
1728218822Sdim
1729218822Sdim  if (abfd != NULL
1730218822Sdim      && *name != '\0'
1731218822Sdim      && bfd_get_symbol_leading_char (abfd) == *name)
1732218822Sdim    ++name;
1733218822Sdim
1734218822Sdim  /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
1735218822Sdim     or the MS PE format.  These formats have a number of leading '.'s
1736218822Sdim     on at least some symbols, so we remove all dots to avoid
1737218822Sdim     confusing the demangler.  */
1738218822Sdim  pre = name;
1739218822Sdim  while (*name == '.' || *name == '$')
1740218822Sdim    ++name;
1741218822Sdim  pre_len = name - pre;
1742218822Sdim
1743218822Sdim  /* Strip off @plt and suchlike too.  */
1744218822Sdim  alloc = NULL;
1745218822Sdim  suf = strchr (name, '@');
1746218822Sdim  if (suf != NULL)
1747218822Sdim    {
1748218822Sdim      alloc = bfd_malloc (suf - name + 1);
1749218822Sdim      if (alloc == NULL)
1750218822Sdim	return NULL;
1751218822Sdim      memcpy (alloc, name, suf - name);
1752218822Sdim      alloc[suf - name] = '\0';
1753218822Sdim      name = alloc;
1754218822Sdim    }
1755218822Sdim
1756218822Sdim  res = cplus_demangle (name, options);
1757218822Sdim
1758218822Sdim  if (alloc != NULL)
1759218822Sdim    free (alloc);
1760218822Sdim
1761218822Sdim  if (res == NULL)
1762218822Sdim    return NULL;
1763218822Sdim
1764218822Sdim  /* Put back any prefix or suffix.  */
1765218822Sdim  if (pre_len != 0 || suf != NULL)
1766218822Sdim    {
1767218822Sdim      size_t len;
1768218822Sdim      size_t suf_len;
1769218822Sdim      char *final;
1770218822Sdim
1771218822Sdim      len = strlen (res);
1772218822Sdim      if (suf == NULL)
1773218822Sdim	suf = res + len;
1774218822Sdim      suf_len = strlen (suf) + 1;
1775218822Sdim      final = bfd_malloc (pre_len + len + suf_len);
1776218822Sdim      if (final != NULL)
1777218822Sdim	{
1778218822Sdim	  memcpy (final, pre, pre_len);
1779218822Sdim	  memcpy (final + pre_len, res, len);
1780218822Sdim	  memcpy (final + pre_len + len, suf, suf_len);
1781218822Sdim	}
1782218822Sdim      free (res);
1783218822Sdim      res = final;
1784218822Sdim    }
1785218822Sdim
1786218822Sdim  return res;
1787218822Sdim}
1788