/* BFD back-end data structures for ELF files.
- Copyright (C) 1992-2019 Free Software Foundation, Inc.
+ Copyright (C) 1992-2020 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
unsigned long destshndx_index;
};
+struct bfd_link_needed_list
+{
+ struct bfd_link_needed_list *next;
+ bfd *by;
+ const char *name;
+};
+
/* ELF linker hash table. */
struct elf_link_hash_table
/* Cached first output tls section and size of PT_TLS segment. */
asection *tls_sec;
- bfd_size_type tls_size;
+ bfd_size_type tls_size; /* Bytes. */
- /* A linked list of BFD's loaded in the link. */
- struct elf_link_loaded_list *loaded;
+ /* A linked list of dynamic BFD's loaded in the link. */
+ struct elf_link_loaded_list *dyn_loaded;
/* Short-cuts to get to dynamic linker sections. */
asection *sgot;
/* A function to convert machine dependent ELF section header flags to
BFD internal section header flags. */
bfd_boolean (*elf_backend_section_flags)
- (flagword *, const Elf_Internal_Shdr *);
+ (const Elf_Internal_Shdr *);
/* A function that returns a struct containing ELF section flags and
type for the given BFD section. */
bfd_boolean (*elf_backend_size_dynamic_sections)
(bfd *output_bfd, struct bfd_link_info *info);
+ /* The STRIP_ZERO_SIZED_DYNAMIC_SECTIONS function is called by the
+ ELF backend linker to strip zero-sized dynamic sections after
+ the section sizes have been set. */
+ bfd_boolean (*elf_backend_strip_zero_sized_dynamic_sections)
+ (struct bfd_link_info *info);
+
/* Set TEXT_INDEX_SECTION and DATA_INDEX_SECTION, the output sections
we keep to use as a base for relocs and symbols. */
void (*elf_backend_init_index_section)
(bfd *, struct bfd_link_info *);
/* A function to do any final processing needed for the ELF file
- before writing it out. The LINKER argument is TRUE if this BFD
- was created by the ELF backend linker. */
- void (*elf_backend_final_write_processing)
- (bfd *, bfd_boolean linker);
+ before writing it out. */
+ bfd_boolean (*elf_backend_final_write_processing)
+ (bfd *);
/* This function is called by get_program_header_size. It should
return the number of additional program segments which this BFD
/* This function is called to modify program headers just before
they are written. */
- bfd_boolean (*elf_backend_modify_program_headers)
+ bfd_boolean (*elf_backend_modify_headers)
(bfd *, struct bfd_link_info *);
/* This function is called to see if the PHDR header should be
bfd_boolean (*gc_mark_extra_sections)
(struct bfd_link_info *, elf_gc_mark_hook_fn);
- /* This function, if defined, is called after the ELF headers have
- been created. This allows for things like the OS and ABI versions
- to be changed. */
- void (*elf_backend_post_process_headers)
+ /* This function is called to initialise ELF file header info.
+ Customised versions can modify things like the OS and ABI version. */
+ bfd_boolean (*elf_backend_init_file_header)
(bfd *, struct bfd_link_info *);
/* This function, if defined, prints a symbol to file and returns the
int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
bfd_size_type len));
+ bfd_boolean (*elf_backend_core_find_build_id) (bfd *, bfd_vma);
+
/* This function is used by `_bfd_elf_get_synthetic_symtab';
see elf.c. */
bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *);
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
+ /* If non-NULL, called to register the location of XLAT_LOC within
+ .MIPS.xhash at which real final dynindx for H will be written.
+ If XLAT_LOC is zero, the symbol is not included in
+ .MIPS.xhash and no dynindx will be written. */
+ void (*record_xhash_symbol)
+ (struct elf_link_hash_entry *h, bfd_vma xlat_loc);
+
/* Return TRUE if type is a function symbol type. */
bfd_boolean (*is_function_type) (unsigned int type);
/* Opcode representing no unwind. */
int (*cant_unwind_opcode) (struct bfd_link_info *);
+ /* Called when emitting an ELF symbol whoes input version had an
+ ST_SHNDX field set to a value in the range SHN_LOPROC..SHN_HIOS.
+ Returns the value to be installed in the ST_SHNDX field of the
+ emitted symbol. If not defined, the value is left unchanged. */
+ unsigned int (*symbol_section_index) (bfd *, elf_symbol_type *);
+
+ /* Called when a section has extra reloc sections. */
+ bfd_boolean (*init_secondary_reloc_section) (bfd *, Elf_Internal_Shdr *,
+ const char *, unsigned int);
+
+ /* Called when after loading the normal relocs for a section. */
+ bfd_boolean (*slurp_secondary_relocs) (bfd *, asection *, asymbol **);
+
+ /* Called after writing the normal relocs for a section. */
+ bfd_boolean (*write_secondary_relocs) (bfd *, asection *);
+
/* This is non-zero if static TLS segments require a special alignment. */
unsigned static_tls_alignment;
/* Segment flags for the PT_GNU_STACK segment. */
unsigned int stack_flags;
- /* This is set to TRUE if the object was created by the backend
- linker. */
- bfd_boolean linker;
-
/* Used to determine if the e_flags field has been initialized */
bfd_boolean flags_init;
};
-/* Indicate if the bfd contains symbols that have the STT_GNU_IFUNC
- symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
- field in the ELF header structure. */
-enum elf_gnu_symbols
+/* Indicate if the bfd contains SHF_GNU_MBIND sections or symbols that
+ have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE binding. Used
+ to set the osabi field in the ELF header structure. */
+enum elf_gnu_osabi
{
- elf_gnu_symbol_none = 0,
- elf_gnu_symbol_any = 1 << 0,
- elf_gnu_symbol_ifunc = (elf_gnu_symbol_any | 1 << 1),
- elf_gnu_symbol_unique = (elf_gnu_symbol_any | 1 << 2),
- elf_gnu_symbol_all = (elf_gnu_symbol_ifunc | elf_gnu_symbol_unique)
+ elf_gnu_osabi_mbind = 1 << 0,
+ elf_gnu_osabi_ifunc = 1 << 1,
+ elf_gnu_osabi_unique = 1 << 2,
};
typedef struct elf_section_list
struct elf_section_list * next;
} elf_section_list;
+enum dynamic_lib_link_class {
+ DYN_NORMAL = 0,
+ DYN_AS_NEEDED = 1,
+ DYN_DT_NEEDED = 2,
+ DYN_NO_ADD_NEEDED = 4,
+ DYN_NO_NEEDED = 8
+};
+
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
struct sdt_note *sdt_note_head;
Elf_Internal_Shdr **group_sect_ptr;
- int num_group;
+ unsigned int num_group;
/* Index into group_sect_ptr, updated by setup_group when finding a
section's group. Used to optimize subsequent group searches. */
or was found via a DT_NEEDED entry. */
ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4;
- /* Whether if the bfd contains symbols that have the STT_GNU_IFUNC
- symbol type or STB_GNU_UNIQUE binding. */
- ENUM_BITFIELD (elf_gnu_symbols) has_gnu_symbols : 3;
+ /* Whether the bfd uses OS specific bits that require ELFOSABI_GNU. */
+ ENUM_BITFIELD (elf_gnu_osabi) has_gnu_osabi : 3;
/* Whether if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED
property. */
#define elf_seg_map(bfd) (elf_tdata(bfd) -> o->seg_map)
#define elf_next_file_pos(bfd) (elf_tdata(bfd) -> o->next_file_pos)
#define elf_eh_frame_hdr(bfd) (elf_tdata(bfd) -> o->eh_frame_hdr)
-#define elf_linker(bfd) (elf_tdata(bfd) -> o->linker)
#define elf_stack_flags(bfd) (elf_tdata(bfd) -> o->stack_flags)
#define elf_shstrtab(bfd) (elf_tdata(bfd) -> o->strtab_ptr)
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
extern Elf_Internal_Sym *bfd_elf_get_elf_syms
(bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *,
Elf_External_Sym_Shndx *);
+extern char * bfd_elf_get_str_section (bfd *, unsigned int);
extern const char *bfd_elf_sym_name
(bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *, asection *);
extern bfd_boolean _bfd_elf_print_private_bfd_data
(bfd *, void *);
const char * _bfd_elf_get_symbol_version_string
- (bfd *, asymbol *, bfd_boolean *);
+ (bfd *, asymbol *, bfd_boolean, bfd_boolean *);
extern void bfd_elf_print_symbol
(bfd *, void *, asymbol *, bfd_print_symbol_type);
(bfd *, const asection *, bfd *, const asection *);
extern bfd_boolean bfd_elf_is_group_section
(bfd *, const struct bfd_section *);
+extern const char *bfd_elf_group_name
+ (bfd *, const struct bfd_section *);
extern bfd_boolean _bfd_elf_section_already_linked
(bfd *, asection *, struct bfd_link_info *);
extern void bfd_elf_set_group_contents
(struct elf_strtab_hash *, void *);
extern bfd_size_type _bfd_elf_strtab_size
(struct elf_strtab_hash *);
+extern bfd_size_type _bfd_elf_strtab_len
+ (struct elf_strtab_hash *);
extern bfd_size_type _bfd_elf_strtab_offset
(struct elf_strtab_hash *, size_t);
+extern const char * _bfd_elf_strtab_str
+ (struct elf_strtab_hash *, size_t idx, bfd_size_type *offset);
extern bfd_boolean _bfd_elf_strtab_emit
(bfd *, struct elf_strtab_hash *);
extern void _bfd_elf_strtab_finalize
(bfd *, struct bfd_link_info *);
extern file_ptr _bfd_elf_assign_file_position_for_section
(Elf_Internal_Shdr *, file_ptr, bfd_boolean);
+extern bfd_boolean _bfd_elf_modify_headers
+ (bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_validate_reloc
(bfd *, arelent *);
+extern bfd_boolean bfd_elf_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *, bfd_boolean,
+ bfd_boolean);
+extern bfd_boolean bfd_elf_stack_segment_size (bfd *, struct bfd_link_info *,
+ const char *, bfd_vma);
+extern bfd_boolean bfd_elf_size_dynamic_sections
+ (bfd *, const char *, const char *, const char *, const char *, const char *,
+ const char * const *, struct bfd_link_info *, struct bfd_section **);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_elf_get_bfd_needed_list
+ (bfd *, struct bfd_link_needed_list **);
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern void bfd_elf_set_dt_needed_name
+ (bfd *, const char *);
+extern const char *bfd_elf_get_dt_soname
+ (bfd *);
+extern void bfd_elf_set_dyn_lib_class
+ (bfd *, enum dynamic_lib_link_class);
+extern int bfd_elf_get_dyn_lib_class
+ (bfd *);
+extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
+ (bfd *, struct bfd_link_info *);
+extern int bfd_elf_discard_info
+ (bfd *, struct bfd_link_info *);
+extern unsigned int _bfd_elf_default_action_discarded
+ (struct bfd_section *);
+extern struct bfd_section *_bfd_elf_tls_setup
+ (bfd *, struct bfd_link_info *);
+
extern bfd_boolean _bfd_elf_link_create_dynamic_sections
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_omit_section_dynsym_default
extern struct bfd_link_hash_entry *bfd_elf_define_start_stop
(struct bfd_link_info *, const char *, asection *);
-extern void _bfd_elf_post_process_headers (bfd * , struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_init_file_header (bfd *, struct bfd_link_info *);
-extern const bfd_target *bfd_elf32_object_p
+extern bfd_boolean _bfd_elf_final_write_processing (bfd *);
+
+extern bfd_cleanup bfd_elf32_object_p
(bfd *);
-extern const bfd_target *bfd_elf32_core_file_p
+extern bfd_cleanup bfd_elf32_core_file_p
(bfd *);
extern char *bfd_elf32_core_file_failing_command
(bfd *);
(bfd *, bfd *);
extern int bfd_elf32_core_file_pid
(bfd *);
+extern bfd_boolean _bfd_elf32_core_find_build_id
+ (bfd *, bfd_vma);
extern bfd_boolean bfd_elf32_swap_symbol_in
(bfd *, const void *, const void *, Elf_Internal_Sym *);
extern bfd_boolean bfd_elf32_slurp_reloc_table
(bfd *, asection *, asymbol **, bfd_boolean);
-extern const bfd_target *bfd_elf64_object_p
+extern bfd_cleanup bfd_elf64_object_p
(bfd *);
-extern const bfd_target *bfd_elf64_core_file_p
+extern bfd_cleanup bfd_elf64_core_file_p
(bfd *);
extern char *bfd_elf64_core_file_failing_command
(bfd *);
(bfd *, bfd *);
extern int bfd_elf64_core_file_pid
(bfd *);
+extern bfd_boolean _bfd_elf64_core_find_build_id
+ (bfd *, bfd_vma);
extern bfd_boolean bfd_elf64_swap_symbol_in
(bfd *, const void *, const void *, Elf_Internal_Sym *);
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_add_dynamic_entry
(struct bfd_link_info *, bfd_vma, bfd_vma);
+extern bfd_boolean _bfd_elf_strip_zero_sized_dynamic_sections
+ (struct bfd_link_info *);
+extern int bfd_elf_add_dt_needed_tag
+ (bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_link_check_relocs
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_ppc_merge_fp_attributes
(bfd *, struct bfd_link_info *);
+/* Return an upper bound on the number of bytes required to store a
+ copy of ABFD's program header table entries. Return -1 if an error
+ occurs; bfd_get_error will return an appropriate code. */
+extern long bfd_get_elf_phdr_upper_bound
+ (bfd *abfd);
+
+/* Copy ABFD's program header table entries to *PHDRS. The entries
+ will be stored as an array of Elf_Internal_Phdr structures, as
+ defined in include/elf/internal.h. To find out how large the
+ buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+ Return the number of program header table entries read, or -1 if an
+ error occurs; bfd_get_error will return an appropriate code. */
+extern int bfd_get_elf_phdrs
+ (bfd *abfd, void *phdrs);
+
/* Exported interface for writing elf corefile notes. */
extern char *elfcore_write_note
(bfd *, char *, int *, const char *, int, const void *, int);
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_aarch_pauth
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_arc_v2
+ (bfd *, char *, int *, const void *, int);
extern char *elfcore_write_lwpstatus
(bfd *, char *, int *, long, int, const void *);
extern char *elfcore_write_register_note
extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int);
extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *);
extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
+extern bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type, size_t);
extern bfd_boolean _bfd_elf_parse_gnu_properties
(bfd *, Elf_Internal_Note *);
extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
extern bfd_vma elf32_r_sym (bfd_vma);
+extern bfd_boolean is_debuginfo_file (bfd *);
+
+
+extern bfd_boolean _bfd_elf_init_secondary_reloc_section
+ (bfd *, Elf_Internal_Shdr *, const char *, unsigned int);
+extern bfd_boolean _bfd_elf_slurp_secondary_reloc_section
+ (bfd *, asection *, asymbol **);
+extern bfd_boolean _bfd_elf_copy_special_section_fields
+ (const bfd *, bfd *, const Elf_Internal_Shdr *, Elf_Internal_Shdr *);
+extern bfd_boolean _bfd_elf_write_secondary_reloc_section
+ (bfd *, asection *);
+extern unsigned int _bfd_elf_symbol_section_index
+ (bfd *, elf_symbol_type *);
+
+
/* Large common section. */
extern asection _bfd_elf_large_com_section;
/* Hash for local symbol with the first section id, ID, in the input
file and the local symbol index, SYM. */
#define ELF_LOCAL_SYMBOL_HASH(ID, SYM) \
- (((((ID) & 0xff) << 24) | (((ID) & 0xff00) << 8)) \
- ^ (SYM) ^ ((ID) >> 16))
+ (((((ID) & 0xffU) << 24) | (((ID) & 0xff00) << 8)) \
+ ^ (SYM) ^ (((ID) & 0xffff0000U) >> 16))
/* This is the condition under which finish_dynamic_symbol will be called.
If our finish_dynamic_symbol isn't called, we'll need to do something
else if (!bfd_link_relocatable (info)) \
{ \
bfd_boolean err; \
- err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR \
- || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); \
+ err = (info->unresolved_syms_in_objects == RM_DIAGNOSE && \
+ !info->warn_unresolved_syms) \
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT; \
(*info->callbacks->undefined_symbol) (info, \
h->root.root.string, \
input_bfd, \
|| (H)->start_stop \
|| ((INFO)->dynamic && !(H)->dynamic)))
+/* Determine if a section contains CTF data, using its name. */
+static inline bfd_boolean
+bfd_section_is_ctf (const asection *sec)
+{
+ const char *name = bfd_section_name (sec);
+ return strncmp (name, ".ctf", 4) == 0 && (name[4] == 0 || name[4] == '.');
+}
+
#ifdef __cplusplus
}
#endif