/* 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
};
/* Records local symbols to be emitted in the dynamic symbol table. */
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));
/* 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
#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 bfd_boolean _bfd_elf_make_linker_section_rela
PARAMS ((bfd *, elf_linker_section_t *, int));
+extern Elf_Internal_Rela *_bfd_elf_link_read_relocs
+ PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, bfd_boolean));
+
+extern bfd_boolean _bfd_elf_link_size_reloc_section
+ PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
+
+extern bfd_boolean _bfd_elf_link_output_relocs
+ PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
+
+extern bfd_boolean _bfd_elf_fix_symbol_flags
+ PARAMS ((struct elf_link_hash_entry *, struct elf_info_failed *));
+
+extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+
+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 *));
extern const bfd_target *bfd_elf32_core_file_p
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