/* BFD back-end data structures for ELF files.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 Free Software
- Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "elf/external.h"
#include "bfdlink.h"
+/* The number of entries in a section is its size divided by the size
+ of a single entry. This is normally only applicaable to reloc and
+ symbol table sections. */
+#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_size / (shdr)->sh_entsize)
+
/* If size isn't specified as 64 or 32, NAME macro should fail. */
#ifndef NAME
#if ARCH_SIZE==64
/* Symbol index as a dynamic symbol. Initialized to -1, and remains
-1 if this is not a dynamic symbol. */
+ /* ??? Note that this is consistently used as a synonym for tests
+ against whether we can perform various simplifying transformations
+ to the code. (E.g. changing a pc-relative jump to a PLT entry
+ into a pc-relative jump to the target function.) That test, which
+ is often relatively complex, and someplaces wrong or incomplete,
+ should really be replaced by a predicate in elflink.c.
+
+ End result: this field -1 does not indicate that the symbol is
+ not in the dynamic symbol table, but rather that the symbol is
+ not visible outside this DSO. */
long dynindx;
/* String table index in .dynstr if this is a dynamic symbol. */
/* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
char type;
- /* Symbol st_other value. */
+ /* Symbol st_other value, symbol visibility. */
unsigned char other;
/* Hash value of the name computed using the ELF hash function. */
#define ELF_LINK_FORCED_LOCAL 02000
/* Symbol was marked during garbage collection. */
#define ELF_LINK_HASH_MARK 04000
+ /* 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
+};
+
+/* Records local symbols to be emitted in the dynamic symbol table. */
+
+struct elf_link_local_dynamic_entry
+{
+ struct elf_link_local_dynamic_entry *next;
+
+ /* The input bfd this symbol came from. */
+ bfd *input_bfd;
+
+ /* The index of the local symbol being copied. */
+ long input_indx;
+
+ /* The index in the outgoing dynamic symbol table. */
+ long dynindx;
+
+ /* A copy of the input symbol. */
+ Elf_Internal_Sym isym;
};
/* ELF linker hash table. */
struct elf_link_hash_entry *hgot;
/* A pointer to information used to link stabs in sections. */
PTR stab_info;
+ /* A pointer to information used to merge SEC_MERGE sections. */
+ PTR merge_info;
+ /* A linked list of local symbols to be added to .dynsym. */
+ struct elf_link_local_dynamic_entry *dynlocal;
+ /* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic
+ objects included in the link. */
+ struct bfd_link_needed_list *runpath;
};
/* Look up an entry in an ELF linker hash table. */
/* The maximum page size for this backend. */
bfd_vma maxpagesize;
- /* This is true if the linker should act like collect and gather
- global constructors and destructors by name. This is true for
- MIPS ELF because the Irix 5 tools can not handle the .init
- section. */
- boolean collect;
-
- /* This is true if the linker should ignore changes to the type of a
- symbol. This is true for MIPS ELF because some Irix 5 objects
- record undefined functions as STT_OBJECT although the definitions
- are STT_FUNC. */
- boolean type_change_ok;
-
/* A function to translate an ELF RELA relocation to a BFD arelent
structure. */
void (*elf_info_to_howto) PARAMS ((bfd *, arelent *,
unsigned int));
/* A function to set the type of the info field. Processor-specific
- types should be handled here. */
- int (*elf_backend_get_symbol_type) PARAMS (( Elf_Internal_Sym *, int));
-
+ types should be handled here. */
+ int (*elf_backend_get_symbol_type) PARAMS (( Elf_Internal_Sym *, int));
+
/* A function to do additional processing on the ELF section header
just before writing it out. This is used to set the flags and
type fields for some sections, or to actually write out data for
Elf32_Internal_Shdr *,
char *));
+ /* A function to convert machine dependent section header flags to
+ BFD internal section header flags. */
+ boolean (*elf_backend_section_flags) PARAMS ((flagword *,
+ Elf32_Internal_Shdr *));
+
+ /* A function to handle unusual program segment types when creating BFD
+ sections from ELF program segments. */
+ boolean (*elf_backend_section_from_phdr) PARAMS ((bfd *,
+ Elf32_Internal_Phdr *,
+ int));
+
/* A function to set up the ELF section header for a BFD section in
preparation for writing it out. This is where the flags and type
fields are set for unusual sections. */
void (*elf_backend_post_process_headers)
PARAMS ((bfd *, struct bfd_link_info *));
+ /* This function, if defined, prints a symbol to file and returns the
+ name of the symbol to be printed. It should return NULL to fall
+ back to default symbol printing. */
+ const char *(*elf_backend_print_symbol_all)
+ PARAMS ((bfd *, PTR, asymbol *));
+
+ /* This function, if defined, is called after all local symbols and
+ global symbols converted to locals are emited into the symtab
+ section. It allows the backend to emit special global symbols
+ not handled in the hash table. */
+ boolean (*elf_backend_output_arch_syms)
+ PARAMS ((bfd *, struct bfd_link_info *, PTR,
+ boolean (*) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *))));
+
+ /* Copy any information related to dynamic linking from a pre-existing
+ symbol IND to a newly created symbol DIR. */
+ void (*elf_backend_copy_indirect_symbol)
+ PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
+
+ /* Modify any information related to dynamic linking such that the
+ symbol is not exported. */
+ void (*elf_backend_hide_symbol)
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
bfd_vma got_header_size;
bfd_vma plt_header_size;
+ /* This is true if the linker should act like collect and gather
+ global constructors and destructors by name. This is true for
+ MIPS ELF because the Irix 5 tools can not handle the .init
+ section. */
+ unsigned collect : 1;
+
+ /* This is true if the linker should ignore changes to the type of a
+ symbol. This is true for MIPS ELF because some Irix 5 objects
+ record undefined functions as STT_OBJECT although the definitions
+ are STT_FUNC. */
+ unsigned type_change_ok : 1;
+
/* Whether the backend may use REL relocations. (Some backends use
both REL and RELA relocations, and this flag is set for those
backends.) */
unsigned may_use_rel_p : 1;
-
+
/* Whether the backend may use RELA relocations. (Some backends use
both REL and RELA relocations, and this flag is set for those
backends.) */
/* Whether the default relocation type is RELA. If a backend with
this flag set wants REL relocations for a particular section,
it must note that explicitly. Similarly, if this flag is clear,
- and the backend wants RELA relocations for a particular
- section. */
+ and the backend wants RELA relocations for a particular
+ section. */
unsigned default_use_rela_p : 1;
+ /* True if addresses "naturally" sign extend. This is used when
+ swapping in from Elf32 when BFD64. */
+ unsigned sign_extend_vma : 1;
+
unsigned want_got_plt : 1;
unsigned plt_readonly : 1;
unsigned want_plt_sym : 1;
unsigned plt_not_loaded : 1;
unsigned plt_alignment : 4;
unsigned can_gc_sections : 1;
+ unsigned want_dynbss : 1;
};
/* Information stored for each BFD section in an ELF file. This
long dynindx;
/* A pointer used for .stab linking optimizations. */
PTR stab_info;
+ /* A pointer used for SEC_MERGE optimizations. */
+ PTR merge_info;
/* A pointer available for the processor specific ELF backend. */
PTR tdata;
/* Nonzero if this section uses RELA relocations, rather than REL. */
file_ptr next_file_pos;
#if 0
/* we don't need these inside bfd anymore, and I think
- these weren't used outside bfd. */
+ these weren't used outside bfd. */
void *prstatus; /* The raw /proc prstatus structure */
void *prpsinfo; /* The raw /proc prpsinfo structure */
#endif
bfd_vma gp; /* The gp value (MIPS only, for now) */
unsigned int gp_size; /* The gp size (MIPS only, for now) */
- /* Information grabbed from an elf core file. */
+ /* Information grabbed from an elf core file. */
int core_signal;
int core_pid;
int core_lwpid;
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. */
+ is -1, then the symbol does not require a global offset table entry. */
union
{
bfd_signed_vma *refcounts;
one. */
const char *dt_name;
+ /* When a reference in a regular object is resolved by a shared
+ object is loaded into via the DT_NEEDED entries by the linker
+ ELF emulation code, we need to add the shared object to the
+ DT_NEEDED list of the resulting binary to indicate the dependency
+ as if the -l option is passed to the linker. This field holds the
+ name of the loaded shared object. */
+ const char *dt_soname;
+
/* Irix 5 often screws up the symbol table, sorting local symbols
after global symbols. This flag is set if the symbol table in
this BFD appears to be screwed up. If it is, we ignore the
find_nearest_line. */
struct mips_elf_find_line *find_line_info;
- /* A place to stash dwarf1 info for this bfd. */
+ /* A place to stash dwarf1 info for this bfd. */
struct dwarf1_debug *dwarf1_find_line_info;
- /* A place to stash dwarf2 info for this bfd. */
- struct dwarf2_debug *dwarf2_find_line_info;
+ /* A place to stash dwarf2 info for this bfd. */
+ PTR dwarf2_find_line_info;
/* An array of stub sections indexed by symbol number, used by the
MIPS ELF linker. FIXME: We should figure out some way to only
/* Linker sections that we are interested in. */
struct elf_linker_section *linker_section[ (int)LINKER_SECTION_MAX ];
+
+ /* The Irix 5 support uses two virtual sections, which represent
+ text/data symbols defined in dynamic objects. */
+ asymbol *elf_data_symbol;
+ asymbol *elf_text_symbol;
+ asection *elf_data_section;
+ asection *elf_text_section;
};
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
#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)
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
#define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n])
#define bfd_elf32_print_symbol bfd_elf_print_symbol
#define bfd_elf64_print_symbol bfd_elf_print_symbol
-extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *));
+extern unsigned long bfd_elf_hash PARAMS ((const char *));
extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
arelent *,
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
extern boolean _bfd_elf_make_section_from_shdr
PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, const char *name));
+extern boolean _bfd_elf_make_section_from_phdr
+ PARAMS ((bfd *abfd, Elf_Internal_Phdr *hdr, int index, const char *typename));
extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
PARAMS ((bfd *));
+extern void _bfd_elf_link_hash_copy_indirect
+ PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
+extern void _bfd_elf_link_hash_hide_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
extern boolean _bfd_elf_link_hash_table_init
PARAMS ((struct elf_link_hash_table *, bfd *,
struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
const char *)));
extern boolean _bfd_elf_slurp_version_tables PARAMS ((bfd *));
+extern boolean _bfd_elf_merge_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
extern boolean _bfd_elf_copy_private_symbol_data
PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
extern boolean _bfd_elf_copy_private_section_data
unsigned long));
extern boolean _bfd_elf_find_nearest_line PARAMS ((bfd *, asection *,
asymbol **,
- bfd_vma, CONST char **,
- CONST char **,
+ bfd_vma, const char **,
+ const char **,
unsigned int *));
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
extern int _bfd_elf_sizeof_headers PARAMS ((bfd *, boolean));
extern boolean _bfd_elf_new_section_hook PARAMS ((bfd *, asection *));
-extern boolean _bfd_elf_init_reloc_shdr
+extern boolean _bfd_elf_init_reloc_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *, boolean));
/* If the target doesn't have reloc handling written yet: */
boolean
_bfd_elf_link_record_dynamic_symbol PARAMS ((struct bfd_link_info *,
struct elf_link_hash_entry *));
+long
+_bfd_elf_link_lookup_local_dynindx PARAMS ((struct bfd_link_info *,
+ bfd *, long));
boolean
_bfd_elf_compute_section_file_positions PARAMS ((bfd *,
struct bfd_link_info *));
struct bfd_link_info *));
boolean _bfd_elf_create_got_section PARAMS ((bfd *,
struct bfd_link_info *));
-boolean _bfd_elf_link_adjust_dynindx PARAMS ((struct elf_link_hash_entry *,
- PTR));
+unsigned long _bfd_elf_link_renumber_dynsyms PARAMS ((bfd *,
+ struct bfd_link_info *));
elf_linker_section_t *_bfd_elf_create_linker_section
PARAMS ((bfd *abfd,
extern boolean bfd_elf32_write_shdrs_and_ehdr PARAMS ((bfd *));
extern int bfd_elf32_write_out_phdrs
PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
+extern void bfd_elf32_write_relocs
+ PARAMS ((bfd *, asection *, PTR));
+extern boolean bfd_elf32_slurp_reloc_table
+ PARAMS ((bfd *, asection *, asymbol **, boolean));
extern boolean bfd_elf32_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
extern boolean bfd_elf32_link_create_dynamic_sections
extern boolean bfd_elf64_write_shdrs_and_ehdr PARAMS ((bfd *));
extern int bfd_elf64_write_out_phdrs
PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
+extern void bfd_elf64_write_relocs
+ PARAMS ((bfd *, asection *, PTR));
+extern boolean bfd_elf64_slurp_reloc_table
+ PARAMS ((bfd *, asection *, asymbol **, boolean));
extern boolean bfd_elf64_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
extern boolean bfd_elf64_link_create_dynamic_sections
extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
-#define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
-#define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
+#define bfd_elf32_link_record_dynamic_symbol \
+ _bfd_elf_link_record_dynamic_symbol
+#define bfd_elf64_link_record_dynamic_symbol \
+ _bfd_elf_link_record_dynamic_symbol
+
+boolean _bfd_elf32_link_record_local_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, long));
+boolean _bfd_elf64_link_record_local_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, long));
extern boolean _bfd_elf_close_and_cleanup PARAMS ((bfd *));
extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
extern boolean _bfd_mips_elf_object_p PARAMS ((bfd *));
extern boolean _bfd_mips_elf_section_from_shdr
- PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
+ PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
extern boolean _bfd_mips_elf_fake_sections
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
extern boolean _bfd_mips_elf_section_from_bfd_section
const char **, unsigned int *));
extern boolean _bfd_mips_elf_set_section_contents
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+extern boolean _bfd_mips_elf_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_mips_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+extern boolean _bfd_mips_elf_adjust_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+extern boolean _bfd_mips_elf_finish_dynamic_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+extern boolean _bfd_mips_elf_finish_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern asection * _bfd_mips_elf_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *));
+extern boolean _bfd_mips_elf_gc_sweep_hook
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+extern boolean _bfd_mips_elf_always_size_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_mips_elf_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_mips_elf_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+extern struct bfd_link_hash_table *_bfd_mips_elf_link_hash_table_create
+ PARAMS ((bfd *));
+extern boolean _bfd_mips_elf_print_private_bfd_data
+ PARAMS ((bfd *, PTR));
+extern boolean _bfd_mips_elf_link_output_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+ asection *));
+extern boolean _bfd_mips_elf_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern int _bfd_mips_elf_additional_program_headers PARAMS ((bfd *));
+extern boolean _bfd_mips_elf_modify_segment_map PARAMS ((bfd *));
+extern boolean _bfd_mips_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+
+/* SH ELF specific routine. */
+
+extern boolean _sh_elf_set_mach_from_flags PARAMS ((bfd *));
#endif /* _LIBELF_H_ */