Line 1... |
Line 1... |
/* Generic BFD library interface and support routines.
|
/* Generic BFD library interface and support routines.
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
Written by Cygnus Support.
|
Written by Cygnus Support.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
Line 33... |
Line 33... |
contains the major data about the file and pointers
|
contains the major data about the file and pointers
|
to the rest of the data.
|
to the rest of the data.
|
|
|
CODE_FRAGMENT
|
CODE_FRAGMENT
|
.
|
.
|
|
.enum bfd_direction
|
|
. {
|
|
. no_direction = 0,
|
|
. read_direction = 1,
|
|
. write_direction = 2,
|
|
. both_direction = 3
|
|
. };
|
|
.
|
.struct bfd
|
.struct bfd
|
.{
|
.{
|
. {* A unique identifier of the BFD *}
|
. {* A unique identifier of the BFD *}
|
. unsigned int id;
|
. unsigned int id;
|
.
|
.
|
Line 49... |
Line 57... |
. {* The IOSTREAM, and corresponding IO vector that provide access
|
. {* The IOSTREAM, and corresponding IO vector that provide access
|
. to the file backing the BFD. *}
|
. to the file backing the BFD. *}
|
. void *iostream;
|
. void *iostream;
|
. const struct bfd_iovec *iovec;
|
. const struct bfd_iovec *iovec;
|
.
|
.
|
. {* Is the file descriptor being cached? That is, can it be closed as
|
|
. needed, and re-opened when accessed later? *}
|
|
. bfd_boolean cacheable;
|
|
.
|
|
. {* Marks whether there was a default target specified when the
|
|
. BFD was opened. This is used to select which matching algorithm
|
|
. to use to choose the back end. *}
|
|
. bfd_boolean target_defaulted;
|
|
.
|
|
. {* The caching routines use these to maintain a
|
. {* The caching routines use these to maintain a
|
. least-recently-used list of BFDs. *}
|
. least-recently-used list of BFDs. *}
|
. struct bfd *lru_prev, *lru_next;
|
. struct bfd *lru_prev, *lru_next;
|
.
|
.
|
. {* When a file is closed by the caching routines, BFD retains
|
. {* When a file is closed by the caching routines, BFD retains
|
. state information on the file here... *}
|
. state information on the file here... *}
|
. ufile_ptr where;
|
. ufile_ptr where;
|
.
|
.
|
. {* ... and here: (``once'' means at least once). *}
|
|
. bfd_boolean opened_once;
|
|
.
|
|
. {* Set if we have a locally maintained mtime value, rather than
|
|
. getting it from the file each time. *}
|
|
. bfd_boolean mtime_set;
|
|
.
|
|
. {* File modified time, if mtime_set is TRUE. *}
|
. {* File modified time, if mtime_set is TRUE. *}
|
. long mtime;
|
. long mtime;
|
.
|
.
|
. {* Reserved for an unimplemented file locking extension. *}
|
. {* Reserved for an unimplemented file locking extension. *}
|
. int ifd;
|
. int ifd;
|
.
|
.
|
. {* The format which belongs to the BFD. (object, core, etc.) *}
|
. {* The format which belongs to the BFD. (object, core, etc.) *}
|
. bfd_format format;
|
. bfd_format format;
|
.
|
.
|
. {* The direction with which the BFD was opened. *}
|
. {* The direction with which the BFD was opened. *}
|
. enum bfd_direction
|
. enum bfd_direction direction;
|
. {
|
|
. no_direction = 0,
|
|
. read_direction = 1,
|
|
. write_direction = 2,
|
|
. both_direction = 3
|
|
. }
|
|
. direction;
|
|
.
|
.
|
. {* Format_specific flags. *}
|
. {* Format_specific flags. *}
|
. flagword flags;
|
. flagword flags;
|
.
|
.
|
|
. {* Values that may appear in the flags field of a BFD. These also
|
|
. appear in the object_flags field of the bfd_target structure, where
|
|
. they indicate the set of flags used by that backend (not all flags
|
|
. are meaningful for all object file formats) (FIXME: at the moment,
|
|
. the object_flags values have mostly just been copied from backend
|
|
. to another, and are not necessarily correct). *}
|
|
.
|
|
.#define BFD_NO_FLAGS 0x00
|
|
.
|
|
. {* BFD contains relocation entries. *}
|
|
.#define HAS_RELOC 0x01
|
|
.
|
|
. {* BFD is directly executable. *}
|
|
.#define EXEC_P 0x02
|
|
.
|
|
. {* BFD has line number information (basically used for F_LNNO in a
|
|
. COFF header). *}
|
|
.#define HAS_LINENO 0x04
|
|
.
|
|
. {* BFD has debugging information. *}
|
|
.#define HAS_DEBUG 0x08
|
|
.
|
|
. {* BFD has symbols. *}
|
|
.#define HAS_SYMS 0x10
|
|
.
|
|
. {* BFD has local symbols (basically used for F_LSYMS in a COFF
|
|
. header). *}
|
|
.#define HAS_LOCALS 0x20
|
|
.
|
|
. {* BFD is a dynamic object. *}
|
|
.#define DYNAMIC 0x40
|
|
.
|
|
. {* Text section is write protected (if D_PAGED is not set, this is
|
|
. like an a.out NMAGIC file) (the linker sets this by default, but
|
|
. clears it for -r or -N). *}
|
|
.#define WP_TEXT 0x80
|
|
.
|
|
. {* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
|
|
. linker sets this by default, but clears it for -r or -n or -N). *}
|
|
.#define D_PAGED 0x100
|
|
.
|
|
. {* BFD is relaxable (this means that bfd_relax_section may be able to
|
|
. do something) (sometimes bfd_relax_section can do something even if
|
|
. this is not set). *}
|
|
.#define BFD_IS_RELAXABLE 0x200
|
|
.
|
|
. {* This may be set before writing out a BFD to request using a
|
|
. traditional format. For example, this is used to request that when
|
|
. writing out an a.out object the symbols not be hashed to eliminate
|
|
. duplicates. *}
|
|
.#define BFD_TRADITIONAL_FORMAT 0x400
|
|
.
|
|
. {* This flag indicates that the BFD contents are actually cached
|
|
. in memory. If this is set, iostream points to a bfd_in_memory
|
|
. struct. *}
|
|
.#define BFD_IN_MEMORY 0x800
|
|
.
|
|
. {* The sections in this BFD specify a memory page. *}
|
|
.#define HAS_LOAD_PAGE 0x1000
|
|
.
|
|
. {* This BFD has been created by the linker and doesn't correspond
|
|
. to any input file. *}
|
|
.#define BFD_LINKER_CREATED 0x2000
|
|
.
|
|
. {* This may be set before writing out a BFD to request that it
|
|
. be written using values for UIDs, GIDs, timestamps, etc. that
|
|
. will be consistent from run to run. *}
|
|
.#define BFD_DETERMINISTIC_OUTPUT 0x4000
|
|
.
|
. {* Currently my_archive is tested before adding origin to
|
. {* Currently my_archive is tested before adding origin to
|
. anything. I believe that this can become always an add of
|
. anything. I believe that this can become always an add of
|
. origin, with origin set to 0 for non archive files. *}
|
. origin, with origin set to 0 for non archive files. *}
|
. ufile_ptr origin;
|
. ufile_ptr origin;
|
.
|
.
|
. {* Remember when output has begun, to stop strange things
|
. {* The origin in the archive of the proxy entry. This will
|
. from happening. *}
|
. normally be the same as origin, except for thin archives,
|
. bfd_boolean output_has_begun;
|
. when it will contain the current offset of the proxy in the
|
|
. thin archive rather than the offset of the bfd in its actual
|
|
. container. *}
|
|
. ufile_ptr proxy_origin;
|
.
|
.
|
. {* A hash table for section names. *}
|
. {* A hash table for section names. *}
|
. struct bfd_hash_table section_htab;
|
. struct bfd_hash_table section_htab;
|
.
|
.
|
. {* Pointer to linked list of sections. *}
|
. {* Pointer to linked list of sections. *}
|
Line 123... |
Line 180... |
. bfd_vma start_address;
|
. bfd_vma start_address;
|
.
|
.
|
. {* Used for input and output. *}
|
. {* Used for input and output. *}
|
. unsigned int symcount;
|
. unsigned int symcount;
|
.
|
.
|
. {* Symbol table for output BFD (with symcount entries). *}
|
. {* Symbol table for output BFD (with symcount entries).
|
|
. Also used by the linker to cache input BFD symbols. *}
|
. struct bfd_symbol **outsymbols;
|
. struct bfd_symbol **outsymbols;
|
.
|
.
|
. {* Used for slurped dynamic symbol tables. *}
|
. {* Used for slurped dynamic symbol tables. *}
|
. unsigned int dynsymcount;
|
. unsigned int dynsymcount;
|
.
|
.
|
. {* Pointer to structure which contains architecture information. *}
|
. {* Pointer to structure which contains architecture information. *}
|
. const struct bfd_arch_info *arch_info;
|
. const struct bfd_arch_info *arch_info;
|
.
|
.
|
. {* Flag set if symbols from this BFD should not be exported. *}
|
|
. bfd_boolean no_export;
|
|
.
|
|
. {* Stuff only useful for archives. *}
|
. {* Stuff only useful for archives. *}
|
. void *arelt_data;
|
. void *arelt_data;
|
. struct bfd *my_archive; {* The containing archive BFD. *}
|
. struct bfd *my_archive; {* The containing archive BFD. *}
|
. struct bfd *archive_next; {* The next BFD in the archive. *}
|
. struct bfd *archive_next; {* The next BFD in the archive. *}
|
. struct bfd *archive_head; {* The first BFD in the archive. *}
|
. struct bfd *archive_head; {* The first BFD in the archive. *}
|
. bfd_boolean has_armap;
|
. struct bfd *nested_archives; {* List of nested archive in a flattened
|
|
. thin archive. *}
|
.
|
.
|
. {* A chain of BFD structures involved in a link. *}
|
. {* A chain of BFD structures involved in a link. *}
|
. struct bfd *link_next;
|
. struct bfd *link_next;
|
.
|
.
|
. {* A field used by _bfd_generic_link_add_archive_symbols. This will
|
. {* A field used by _bfd_generic_link_add_archive_symbols. This will
|
Line 163... |
Line 219... |
. struct xcoff_tdata *xcoff_obj_data;
|
. struct xcoff_tdata *xcoff_obj_data;
|
. struct ecoff_tdata *ecoff_obj_data;
|
. struct ecoff_tdata *ecoff_obj_data;
|
. struct ieee_data_struct *ieee_data;
|
. struct ieee_data_struct *ieee_data;
|
. struct ieee_ar_data_struct *ieee_ar_data;
|
. struct ieee_ar_data_struct *ieee_ar_data;
|
. struct srec_data_struct *srec_data;
|
. struct srec_data_struct *srec_data;
|
|
. struct verilog_data_struct *verilog_data;
|
. struct ihex_data_struct *ihex_data;
|
. struct ihex_data_struct *ihex_data;
|
. struct tekhex_data_struct *tekhex_data;
|
. struct tekhex_data_struct *tekhex_data;
|
. struct elf_obj_tdata *elf_obj_data;
|
. struct elf_obj_tdata *elf_obj_data;
|
. struct nlm_obj_tdata *nlm_obj_data;
|
. struct nlm_obj_tdata *nlm_obj_data;
|
. struct bout_data_struct *bout_data;
|
. struct bout_data_struct *bout_data;
|
Line 183... |
Line 240... |
. struct cisco_core_struct *cisco_core_data;
|
. struct cisco_core_struct *cisco_core_data;
|
. struct versados_data_struct *versados_data;
|
. struct versados_data_struct *versados_data;
|
. struct netbsd_core_struct *netbsd_core_data;
|
. struct netbsd_core_struct *netbsd_core_data;
|
. struct mach_o_data_struct *mach_o_data;
|
. struct mach_o_data_struct *mach_o_data;
|
. struct mach_o_fat_data_struct *mach_o_fat_data;
|
. struct mach_o_fat_data_struct *mach_o_fat_data;
|
|
. struct plugin_data_struct *plugin_data;
|
. struct bfd_pef_data_struct *pef_data;
|
. struct bfd_pef_data_struct *pef_data;
|
. struct bfd_pef_xlib_data_struct *pef_xlib_data;
|
. struct bfd_pef_xlib_data_struct *pef_xlib_data;
|
. struct bfd_sym_data_struct *sym_data;
|
. struct bfd_sym_data_struct *sym_data;
|
. void *any;
|
. void *any;
|
. }
|
. }
|
Line 197... |
Line 255... |
.
|
.
|
. {* Where all the allocated stuff under this BFD goes. This is a
|
. {* Where all the allocated stuff under this BFD goes. This is a
|
. struct objalloc *, but we use void * to avoid requiring the inclusion
|
. struct objalloc *, but we use void * to avoid requiring the inclusion
|
. of objalloc.h. *}
|
. of objalloc.h. *}
|
. void *memory;
|
. void *memory;
|
|
.
|
|
. {* Is the file descriptor being cached? That is, can it be closed as
|
|
. needed, and re-opened when accessed later? *}
|
|
. unsigned int cacheable : 1;
|
|
.
|
|
. {* Marks whether there was a default target specified when the
|
|
. BFD was opened. This is used to select which matching algorithm
|
|
. to use to choose the back end. *}
|
|
. unsigned int target_defaulted : 1;
|
|
.
|
|
. {* ... and here: (``once'' means at least once). *}
|
|
. unsigned int opened_once : 1;
|
|
.
|
|
. {* Set if we have a locally maintained mtime value, rather than
|
|
. getting it from the file each time. *}
|
|
. unsigned int mtime_set : 1;
|
|
.
|
|
. {* Flag set if symbols from this BFD should not be exported. *}
|
|
. unsigned int no_export : 1;
|
|
.
|
|
. {* Remember when output has begun, to stop strange things
|
|
. from happening. *}
|
|
. unsigned int output_has_begun : 1;
|
|
.
|
|
. {* Have archive map. *}
|
|
. unsigned int has_armap : 1;
|
|
.
|
|
. {* Set if this is a thin archive. *}
|
|
. unsigned int is_thin_archive : 1;
|
.};
|
.};
|
.
|
.
|
*/
|
*/
|
|
|
#include "sysdep.h"
|
#include "sysdep.h"
|
Line 350... |
Line 437... |
writing an archive, but on one of the input files. */
|
writing an archive, but on one of the input files. */
|
va_list ap;
|
va_list ap;
|
|
|
va_start (ap, error_tag);
|
va_start (ap, error_tag);
|
input_bfd = va_arg (ap, bfd *);
|
input_bfd = va_arg (ap, bfd *);
|
input_error = va_arg (ap, int);
|
input_error = (bfd_error_type) va_arg (ap, int);
|
if (input_error >= bfd_error_on_input)
|
if (input_error >= bfd_error_on_input)
|
abort ();
|
abort ();
|
va_end (ap);
|
va_end (ap);
|
}
|
}
|
}
|
}
|
Line 920... |
Line 1007... |
|| strcmp (name, "pei-x86-64") == 0
|
|| strcmp (name, "pei-x86-64") == 0
|
|| strcmp (name, "pe-arm-wince-little") == 0
|
|| strcmp (name, "pe-arm-wince-little") == 0
|
|| strcmp (name, "pei-arm-wince-little") == 0)
|
|| strcmp (name, "pei-arm-wince-little") == 0)
|
return 1;
|
return 1;
|
|
|
|
if (CONST_STRNEQ (name, "mach-o"))
|
|
return 0;
|
|
|
bfd_set_error (bfd_error_wrong_format);
|
bfd_set_error (bfd_error_wrong_format);
|
return -1;
|
return -1;
|
}
|
}
|
|
|
/*
|
/*
|
Line 1357... |
Line 1447... |
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
return TRUE;
|
return TRUE;
|
|
|
amt = sizeof (struct elf_segment_map);
|
amt = sizeof (struct elf_segment_map);
|
amt += ((bfd_size_type) count - 1) * sizeof (asection *);
|
amt += ((bfd_size_type) count - 1) * sizeof (asection *);
|
m = bfd_zalloc (abfd, amt);
|
m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
|
if (m == NULL)
|
if (m == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
m->p_type = type;
|
m->p_type = type;
|
m->p_flags = flags;
|
m->p_flags = flags;
|
Line 1391... |
Line 1481... |
{
|
{
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
return bed->s->elfclass == ELFCLASS32;
|
return bed->s->elfclass == ELFCLASS32;
|
}
|
}
|
|
|
/* For non-ELF, make a guess based on the target name. */
|
/* For non-ELF targets, use architecture information. */
|
return (strstr (bfd_get_target (abfd), "64") == NULL
|
return bfd_arch_bits_per_address (abfd) <= 32;
|
&& strcmp (bfd_get_target (abfd), "mmo") != 0);
|
|
}
|
}
|
#endif
|
#endif
|
|
|
/* bfd_sprintf_vma and bfd_fprintf_vma display an address in the
|
/* bfd_sprintf_vma and bfd_fprintf_vma display an address in the
|
target's address size. */
|
target's address size. */
|
Line 1613... |
Line 1702... |
DESCRIPTION
|
DESCRIPTION
|
Returns the maximum page size, in bytes, as determined by
|
Returns the maximum page size, in bytes, as determined by
|
emulation.
|
emulation.
|
|
|
RETURNS
|
RETURNS
|
Returns the maximum page size in bytes for ELF, abort
|
Returns the maximum page size in bytes for ELF, 0 otherwise.
|
otherwise.
|
|
*/
|
*/
|
|
|
bfd_vma
|
bfd_vma
|
bfd_emul_get_maxpagesize (const char *emul)
|
bfd_emul_get_maxpagesize (const char *emul)
|
{
|
{
|
Line 1627... |
Line 1715... |
target = bfd_find_target (emul, NULL);
|
target = bfd_find_target (emul, NULL);
|
if (target != NULL
|
if (target != NULL
|
&& target->flavour == bfd_target_elf_flavour)
|
&& target->flavour == bfd_target_elf_flavour)
|
return xvec_get_elf_backend_data (target)->maxpagesize;
|
return xvec_get_elf_backend_data (target)->maxpagesize;
|
|
|
abort ();
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static void
|
static void
|
bfd_elf_set_pagesize (const bfd_target *target, bfd_vma size,
|
bfd_elf_set_pagesize (const bfd_target *target, bfd_vma size,
|
Line 1686... |
Line 1773... |
DESCRIPTION
|
DESCRIPTION
|
Returns the common page size, in bytes, as determined by
|
Returns the common page size, in bytes, as determined by
|
emulation.
|
emulation.
|
|
|
RETURNS
|
RETURNS
|
Returns the common page size in bytes for ELF, abort otherwise.
|
Returns the common page size in bytes for ELF, 0 otherwise.
|
*/
|
*/
|
|
|
bfd_vma
|
bfd_vma
|
bfd_emul_get_commonpagesize (const char *emul)
|
bfd_emul_get_commonpagesize (const char *emul)
|
{
|
{
|
Line 1699... |
Line 1786... |
target = bfd_find_target (emul, NULL);
|
target = bfd_find_target (emul, NULL);
|
if (target != NULL
|
if (target != NULL
|
&& target->flavour == bfd_target_elf_flavour)
|
&& target->flavour == bfd_target_elf_flavour)
|
return xvec_get_elf_backend_data (target)->commonpagesize;
|
return xvec_get_elf_backend_data (target)->commonpagesize;
|
|
|
abort ();
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
FUNCTION
|
FUNCTION
|
Line 1749... |
Line 1835... |
bfd_demangle (bfd *abfd, const char *name, int options)
|
bfd_demangle (bfd *abfd, const char *name, int options)
|
{
|
{
|
char *res, *alloc;
|
char *res, *alloc;
|
const char *pre, *suf;
|
const char *pre, *suf;
|
size_t pre_len;
|
size_t pre_len;
|
|
bfd_boolean skip_lead;
|
|
|
if (abfd != NULL
|
skip_lead = (abfd != NULL
|
&& *name != '\0'
|
&& *name != '\0'
|
&& bfd_get_symbol_leading_char (abfd) == *name)
|
&& bfd_get_symbol_leading_char (abfd) == *name);
|
|
if (skip_lead)
|
++name;
|
++name;
|
|
|
/* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
|
/* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
|
or the MS PE format. These formats have a number of leading '.'s
|
or the MS PE format. These formats have a number of leading '.'s
|
on at least some symbols, so we remove all dots to avoid
|
on at least some symbols, so we remove all dots to avoid
|
Line 1769... |
Line 1857... |
/* Strip off @plt and suchlike too. */
|
/* Strip off @plt and suchlike too. */
|
alloc = NULL;
|
alloc = NULL;
|
suf = strchr (name, '@');
|
suf = strchr (name, '@');
|
if (suf != NULL)
|
if (suf != NULL)
|
{
|
{
|
alloc = bfd_malloc (suf - name + 1);
|
alloc = (char *) bfd_malloc (suf - name + 1);
|
if (alloc == NULL)
|
if (alloc == NULL)
|
return NULL;
|
return NULL;
|
memcpy (alloc, name, suf - name);
|
memcpy (alloc, name, suf - name);
|
alloc[suf - name] = '\0';
|
alloc[suf - name] = '\0';
|
name = alloc;
|
name = alloc;
|
Line 1783... |
Line 1871... |
|
|
if (alloc != NULL)
|
if (alloc != NULL)
|
free (alloc);
|
free (alloc);
|
|
|
if (res == NULL)
|
if (res == NULL)
|
|
{
|
|
if (skip_lead)
|
|
{
|
|
size_t len = strlen (pre) + 1;
|
|
alloc = (char *) bfd_malloc (len);
|
|
if (alloc == NULL)
|
return NULL;
|
return NULL;
|
|
memcpy (alloc, pre, len);
|
|
return alloc;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
/* Put back any prefix or suffix. */
|
/* Put back any prefix or suffix. */
|
if (pre_len != 0 || suf != NULL)
|
if (pre_len != 0 || suf != NULL)
|
{
|
{
|
size_t len;
|
size_t len;
|
Line 1796... |
Line 1895... |
|
|
len = strlen (res);
|
len = strlen (res);
|
if (suf == NULL)
|
if (suf == NULL)
|
suf = res + len;
|
suf = res + len;
|
suf_len = strlen (suf) + 1;
|
suf_len = strlen (suf) + 1;
|
final = bfd_malloc (pre_len + len + suf_len);
|
final = (char *) bfd_malloc (pre_len + len + suf_len);
|
if (final != NULL)
|
if (final != NULL)
|
{
|
{
|
memcpy (final, pre, pre_len);
|
memcpy (final, pre, pre_len);
|
memcpy (final + pre_len, res, len);
|
memcpy (final + pre_len, res, len);
|
memcpy (final + pre_len + len, suf, suf_len);
|
memcpy (final + pre_len + len, suf, suf_len);
|