/* BFD back-end data structures for ELF files.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002 Free Software Foundation, Inc.
+ 2002, 2003 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
} elf_symbol_type;
\f
struct elf_strtab_hash;
+struct got_entry;
+struct plt_entry;
/* ELF linker hash table entries. */
/* If this symbol requires an entry in the global offset table, the
processor specific backend uses this field to track usage and
- final offset. We use a union and two names primarily to document
- the intent of any particular piece of code. The field should be
- used as a count until size_dynamic_sections, at which point the
- contents of the .got is fixed. Afterward, if this field is -1,
- then the symbol does not require a global offset table entry. */
- union
+ final offset. Two schemes are supported: The first assumes that
+ a symbol may only have one GOT entry, and uses REFCOUNT until
+ size_dynamic_sections, at which point the contents of the .got is
+ fixed. Afterward, if OFFSET is -1, then the symbol does not
+ require a global offset table entry. The second scheme allows
+ multiple GOT entries per symbol, managed via a linked list
+ pointed to by GLIST. */
+ union gotplt_union
{
bfd_signed_vma refcount;
bfd_vma offset;
+ struct got_entry *glist;
+ struct plt_entry *plist;
} got;
/* Same, but tracks a procedure linkage table entry. */
- union
- {
- bfd_signed_vma refcount;
- bfd_vma offset;
- } plt;
+ union gotplt_union plt;
/* Symbol size. */
bfd_size_type size;
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
not currently set by all the backends. */
#define ELF_LINK_NON_GOT_REF 010000
+ /* Symbol has a definition in a shared object. */
+#define ELF_LINK_DYNAMIC_DEF 020000
+ /* Symbol is weak in all shared objects. */
+#define ELF_LINK_DYNAMIC_WEAK 040000
};
+/* Will references to this symbol always reference the symbol
+ in this object? STV_PROTECTED is excluded from the visibility test
+ here so that function pointer comparisons work properly. Since
+ function symbols not defined in an app are set to their .plt entry,
+ it's necessary for shared libs to also reference the .plt even
+ though the symbol is really local to the shared lib. */
+#define SYMBOL_REFERENCES_LOCAL(INFO, H) \
+ ((! (INFO)->shared \
+ || (INFO)->symbolic \
+ || (H)->dynindx == -1 \
+ || ELF_ST_VISIBILITY ((H)->other) == STV_INTERNAL \
+ || ELF_ST_VISIBILITY ((H)->other) == STV_HIDDEN \
+ || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) \
+ && ((H)->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
+
+/* Will _calls_ to this symbol always call the version in this object? */
+#define SYMBOL_CALLS_LOCAL(INFO, H) \
+ ((! (INFO)->shared \
+ || (INFO)->symbolic \
+ || (H)->dynindx == -1 \
+ || ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \
+ || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) \
+ && ((H)->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
+
/* Records local symbols to be emitted in the dynamic symbol table. */
struct elf_link_local_dynamic_entry
bfd *abfd;
};
-enum elf_link_info_type
-{
- ELF_INFO_TYPE_NONE,
- ELF_INFO_TYPE_STABS,
- ELF_INFO_TYPE_MERGE,
- ELF_INFO_TYPE_EH_FRAME,
- ELF_INFO_TYPE_JUST_SYMS,
- ELF_INFO_TYPE_LAST
-};
-
/* Structures used by the eh_frame optimization code. */
struct cie_header
{
/* The value to use when initialising got.refcount/offset and
plt.refcount/offset in an elf_link_hash_entry. Set to zero when
- the values are refcounts. Set to -1 in size_dynamic_sections
- when the values may be offsets. */
- bfd_signed_vma init_refcount;
+ the values are refcounts. Set to init_offset in
+ size_dynamic_sections when the values may be offsets. */
+ union gotplt_union init_refcount;
+
+ /* The value to use for got.refcount/offset and plt.refcount/offset
+ when the values may be offsets. Normally (bfd_vma) -1. */
+ union gotplt_union init_offset;
/* The number of symbols found in the link which must be put into
the .dynsym section. */
handle all back-ends. */
#define MAX_INT_RELS_PER_EXT_REL 3
- unsigned char arch_size, file_align;
+ unsigned char arch_size, log_file_align;
unsigned char elfclass, ev_current;
int (*write_out_phdrs)
PARAMS ((bfd *, const Elf_Internal_Phdr *, unsigned int));
This function is responsible for adjust the section contents as
necessary, and (if using Rela relocs and generating a
- relocateable output file) adjusting the reloc addend as
+ relocatable output file) adjusting the reloc addend as
necessary.
This function does not have to worry about setting the reloc
The global hash table entry for the global symbols can be found
via elf_sym_hashes (input_bfd).
- When generating relocateable output, this function must handle
+ When generating relocatable output, this function must handle
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
going to be the section symbol corresponding to the output
section, which means that the addend must be adjusted
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
+ /* This function implements `bfd_elf_bfd_from_remote_memory';
+ see elf.c, elfcode.h. */
+ bfd *(*elf_backend_bfd_from_remote_memory)
+ PARAMS ((bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma vma, char *myaddr, int len)));
+
/* Alternate EM_xxxx machine codes for this backend. */
int elf_machine_alt1;
int elf_machine_alt2;
/* The number of relocations currently assigned to REL_HDR2. */
unsigned int rel_count2;
- /* A pointer to a linked list tracking dynamic relocs copied for
- local symbols. */
- PTR local_dynrel;
-
- /* A pointer to the bfd section used for dynamic relocs. */
- asection *sreloc;
-
/* The ELF section number of this section. Only used for an output
file. */
int this_idx;
REL_HDR2 if any. Only used for an output file. */
int rel_idx2;
+ /* Used by the backend linker when generating a shared library to
+ record the dynamic symbol index for a section symbol
+ corresponding to this section. A value of 0 means that there is
+ no dynamic symbol for this section. */
+ int dynindx;
+
/* Used by the backend linker to store the symbol hash table entries
associated with relocs against global symbols. */
struct elf_link_hash_entry **rel_hashes;
pointer may be NULL. It is used by the backend linker. */
Elf_Internal_Rela *relocs;
- /* Used by the backend linker when generating a shared library to
- record the dynamic symbol index for a section symbol
- corresponding to this section. A value of 0 means that there is
- no dynamic symbol for this section. */
- long dynindx;
-
- /* A pointer used for various section optimizations. */
- PTR sec_info;
+ /* A pointer to a linked list tracking dynamic relocs copied for
+ local symbols. */
+ PTR local_dynrel;
- /* Type of that information. */
- enum elf_link_info_type sec_info_type;
+ /* A pointer to the bfd section used for dynamic relocs. */
+ asection *sreloc;
union {
/* Group name, if this section is a member of a group. */
the linker. */
asection *next_in_group;
- /* A pointer available for the processor specific ELF backend. */
- PTR tdata;
-
- /* Nonzero if this section uses RELA relocations, rather than REL. */
- unsigned int use_rela_p:1;
-
- /* Nonzero when a group is COMDAT. */
- unsigned int linkonce_p:1;
+ /* A pointer used for various section optimizations. */
+ PTR sec_info;
};
#define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd)
#define elf_group_name(sec) (elf_section_data(sec)->group.name)
#define elf_group_id(sec) (elf_section_data(sec)->group.id)
#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
-#define elf_linkonce_p(sec) (elf_section_data(sec)->linkonce_p)
/* Return TRUE if section has been discarded. */
-#define elf_discarded_section(sec) \
- (!bfd_is_abs_section(sec) \
- && bfd_is_abs_section((sec)->output_section) \
- && elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \
- && elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
+#define elf_discarded_section(sec) \
+ (!bfd_is_abs_section (sec) \
+ && bfd_is_abs_section ((sec)->output_section) \
+ && sec->sec_info_type != ELF_INFO_TYPE_MERGE \
+ && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
#define get_elf_backend_data(abfd) \
((struct elf_backend_data *) (abfd)->xvec->backend_data)
bfd_boolean written_address_p; /* whether address was written yet */
} elf_linker_section_pointers_t;
+/* This struct is used to pass information to routines called via
+ elf_link_hash_traverse which must return failure. */
+
+struct elf_info_failed
+{
+ bfd_boolean failed;
+ struct bfd_link_info *info;
+ struct bfd_elf_version_tree *verdefs;
+};
+
+/* This structure is used to pass information to
+ _bfd_elf_link_assign_sym_version. */
+
+struct elf_assign_sym_version_info
+{
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Version tree. */
+ struct bfd_elf_version_tree *verdefs;
+ /* Whether we had a failure. */
+ bfd_boolean failed;
+};
+
+/* This structure is used to pass information to
+ _bfd_elf_link_find_version_dependencies. */
+
+struct elf_find_verdep_info
+{
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* The number of dependencies. */
+ unsigned int vers;
+ /* Whether we had a failure. */
+ bfd_boolean failed;
+};
+
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
minus the sh_info field of the symbol table header. */
struct elf_link_hash_entry **sym_hashes;
- /* A mapping from local symbols to offsets into the global offset
- table, used when linking. This is indexed by the symbol index.
- Like for the globals, we use a union and two names primarily to
- document the intent of any particular piece of code. The field
- should be used as a count until size_dynamic_sections, at which
- point the contents of the .got is fixed. Afterward, if an entry
- is -1, then the symbol does not require a global offset table entry. */
+ /* Track usage and final offsets of GOT entries for local symbols.
+ This array is indexed by symbol index. Elements are used
+ identically to "got" in struct elf_link_hash_entry. */
union
{
bfd_signed_vma *refcounts;
bfd_vma *offsets;
+ struct got_entry **ents;
} local_got;
/* A mapping from local symbols to offsets into the various linker
/* Number of symbol version references we are about to emit. */
unsigned int cverrefs;
+ /* Segment flags for the PT_GNU_STACK segment. */
+ unsigned int stack_flags;
+
/* Symbol version definitions in external objects. */
Elf_Internal_Verdef *verdef;
#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes)
#define elf_local_got_refcounts(bfd) (elf_tdata(bfd) -> local_got.refcounts)
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
+#define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents)
#define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers)
#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
#define elf_dt_soname(bfd) (elf_tdata(bfd) -> dt_soname)
extern Elf_Internal_Sym *bfd_elf_get_elf_syms
PARAMS ((bfd *, Elf_Internal_Shdr *, size_t, size_t,
Elf_Internal_Sym *, PTR, Elf_External_Sym_Shndx *));
+extern const char *bfd_elf_local_sym_name
+ PARAMS ((bfd *, Elf_Internal_Sym *));
extern bfd_boolean _bfd_elf_copy_private_bfd_data
PARAMS ((bfd *, bfd *));
PARAMS ((bfd *, struct sym_sec_cache *, asection *, unsigned long));
extern asection *bfd_section_from_elf_index
PARAMS ((bfd *, unsigned int));
-extern bfd_boolean _bfd_elf_create_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
extern struct bfd_strtab_hash *_bfd_elf_stringtab_init
PARAMS ((void));
extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
PARAMS ((struct bfd_link_info *));
+extern bfd_boolean _bfd_elf_merge_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, const char *,
+ Elf_Internal_Sym *, asection **, bfd_vma *,
+ struct elf_link_hash_entry **, bfd_boolean *, bfd_boolean *,
+ bfd_boolean *, bfd_boolean *, bfd_boolean));
+
+extern bfd_boolean _bfd_elf_add_default_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
+ bfd_boolean *, bfd_boolean, bfd_boolean));
+
+extern bfd_boolean _bfd_elf_export_symbol
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+
+extern bfd_boolean _bfd_elf_link_find_version_dependencies
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+
+extern bfd_boolean _bfd_elf_link_assign_sym_version
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+
extern bfd_boolean _bfd_elf_link_record_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
extern long _bfd_elf_link_lookup_local_dynindx
extern bfd_boolean _bfd_elf_validate_reloc
PARAMS ((bfd *, arelent *));
+extern bfd_boolean _bfd_elf_link_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
extern bfd_boolean _bfd_elf_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
extern bfd_boolean _bfd_elf_create_got_section
extern char *_bfd_elfcore_strndup
PARAMS ((bfd *, char *, size_t));
-extern elf_linker_section_t *_bfd_elf_create_linker_section
- PARAMS ((bfd *, struct bfd_link_info *, enum elf_linker_section_enum,
- elf_linker_section_t *));
-
-extern elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section
- PARAMS ((elf_linker_section_pointers_t *, bfd_vma,
- elf_linker_section_enum_t));
+extern Elf_Internal_Rela *_bfd_elf_link_read_relocs
+ PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, bfd_boolean));
-extern bfd_boolean bfd_elf32_create_pointer_linker_section
- PARAMS ((bfd *, struct bfd_link_info *, elf_linker_section_t *,
- struct elf_link_hash_entry *, const Elf_Internal_Rela *));
+extern bfd_boolean _bfd_elf_link_size_reloc_section
+ PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
-extern bfd_vma bfd_elf32_finish_pointer_linker_section
- PARAMS ((bfd *, bfd *, struct bfd_link_info *, elf_linker_section_t *,
- struct elf_link_hash_entry *, bfd_vma,
- const Elf_Internal_Rela *, int));
+extern bfd_boolean _bfd_elf_link_output_relocs
+ PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
-extern bfd_boolean bfd_elf64_create_pointer_linker_section
- PARAMS ((bfd *, struct bfd_link_info *, elf_linker_section_t *,
- struct elf_link_hash_entry *, const Elf_Internal_Rela *));
+extern bfd_boolean _bfd_elf_fix_symbol_flags
+ PARAMS ((struct elf_link_hash_entry *, struct elf_info_failed *));
-extern bfd_vma bfd_elf64_finish_pointer_linker_section
- PARAMS ((bfd *, bfd *, struct bfd_link_info *, elf_linker_section_t *,
- struct elf_link_hash_entry *, bfd_vma,
- const Elf_Internal_Rela *, int));
+extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
+ PARAMS ((struct elf_link_hash_entry *, PTR));
-extern bfd_boolean _bfd_elf_make_linker_section_rela
- PARAMS ((bfd *, elf_linker_section_t *, int));
+extern bfd_boolean _bfd_elf_link_sec_merge_syms
+ PARAMS ((struct elf_link_hash_entry *, PTR));
extern const bfd_target *bfd_elf32_object_p
PARAMS ((bfd *));
PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
extern bfd_boolean bfd_elf32_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
-extern bfd_boolean bfd_elf32_link_create_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
-extern Elf_Internal_Rela *_bfd_elf32_link_read_relocs
- PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, bfd_boolean));
extern const bfd_target *bfd_elf64_object_p
PARAMS ((bfd *));
PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
extern bfd_boolean bfd_elf64_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
-extern bfd_boolean bfd_elf64_link_create_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
-extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
- PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, bfd_boolean));
#define bfd_elf32_link_record_dynamic_symbol \
_bfd_elf_link_record_dynamic_symbol
extern char *elfcore_write_lwpstatus
PARAMS ((bfd *, char *, int *, long, int, const PTR));
+extern bfd *_bfd_elf32_bfd_from_remote_memory
+ PARAMS ((bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma, char *, int)));
+extern bfd *_bfd_elf64_bfd_from_remote_memory
+ PARAMS ((bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma, char *, int)));
+
/* SH ELF specific routine. */
extern bfd_boolean _sh_elf_set_mach_from_flags