/* BFD back-end data structures for ELF files.
- Copyright (C) 1992-2016 Free Software Foundation, Inc.
+ Copyright (C) 1992-2018 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
/* Symbol is defined by a shared library with non-default visibility
in a read/write section. */
unsigned int protected_def : 1;
+ /* Symbol is __start_SECNAME or __stop_SECNAME to mark section
+ SECNAME. */
+ unsigned int start_stop : 1;
+ /* Symbol is or was a weak defined symbol from a dynamic object with
+ a strong defined symbol alias. U.ALIAS points to a list of aliases,
+ the definition having is_weakalias clear. */
+ unsigned int is_weakalias : 1;
/* String table index in .dynstr if this is a dynamic symbol. */
unsigned long dynstr_index;
union
{
- /* If this is a weak defined symbol from a dynamic object, this
- field points to a defined symbol with the same value, if there is
- one. Otherwise it is NULL. */
- struct elf_link_hash_entry *weakdef;
+ /* Points to a circular list of non-function symbol aliases. */
+ struct elf_link_hash_entry *alias;
/* Hash value of the name computed using the ELF hash function.
Used part way through size_dynamic_sections, after we've finished
- with weakdefs. */
+ with aliases. */
unsigned long elf_hash_value;
} u;
struct bfd_elf_version_tree *vertree;
} verinfo;
- struct elf_link_virtual_table_entry *vtable;
+ union
+ {
+ /* For __start_SECNAME and __stop_SECNAME symbols, record the first
+ input section whose section name is SECNAME. */
+ asection *start_stop_section;
+
+ /* Vtable information. */
+ struct elf_link_virtual_table_entry *vtable;
+ } u2;
};
+/* Return the strong definition for a weak symbol with aliases. */
+
+static inline struct elf_link_hash_entry *
+weakdef (struct elf_link_hash_entry *h)
+{
+ while (h->is_weakalias)
+ h = h->u.alias;
+ return h;
+}
+
/* Will references to this symbol always reference the symbol
in this object? */
#define SYMBOL_REFERENCES_LOCAL(INFO, H) \
#define SYMBOL_CALLS_LOCAL(INFO, H) \
_bfd_elf_symbol_refs_local_p (H, INFO, 1)
+/* Whether an undefined weak symbol should resolve to its link-time
+ value, even in PIC or PIE objects. */
+#define UNDEFWEAK_NO_DYNAMIC_RELOC(INFO, H) \
+ ((H)->root.type == bfd_link_hash_undefweak \
+ && (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \
+ || (INFO)->dynamic_undefined_weak == 0))
+
/* Common symbols that are turned into definitions don't have the
DEF_REGULAR flag set, so they might appear to be undefined.
Symbols defined in linker scripts also don't have DEF_REGULAR set. */
.eh_frame input section that contains the CIE. */
union {
struct cie *full_cie;
- struct eh_cie_fde *merged_with;
- asection *sec;
+ struct eh_cie_fde *merged_with;
+ asection *sec;
} u;
/* The offset of the personality data from the start of the CIE,
or 0 if the CIE doesn't have any. */
unsigned int personality_offset : 8;
+ /* Length of augmentation. aug_str_len is the length of the
+ string including null terminator. aug_data_len is the length
+ of the rest up to the initial insns. */
+ unsigned int aug_str_len : 3;
+ unsigned int aug_data_len : 5;
+
/* True if we have marked relocations associated with this CIE. */
unsigned int gc_mark : 1;
make_per_encoding_relative is. */
unsigned int per_encoding_relative : 1;
+ /* True if the CIE contains personality data aligned to a
+ multiple of eight bytes. */
+ unsigned int per_encoding_aligned8 : 1;
+
/* True if we need to add an 'R' (FDE encoding) entry to the
CIE's augmentation data. */
unsigned int add_fde_encoding : 1;
unsigned int merged : 1;
/* Unused bits. */
- unsigned int pad1 : 18;
+ unsigned int pad1 : 9;
} cie;
} u;
unsigned int reloc_index;
OR1K_ELF_DATA,
PPC32_ELF_DATA,
PPC64_ELF_DATA,
+ PRU_ELF_DATA,
S390_ELF_DATA,
SH_ELF_DATA,
SPARC_ELF_DATA,
asection *srelplt;
asection *sdynbss;
asection *srelbss;
+ asection *sdynrelro;
+ asection *sreldynrelro;
asection *igotplt;
asection *iplt;
asection *irelplt;
#define elf_hash_table_id(table) ((table) -> hash_table_id)
/* Returns TRUE if the hash table is a struct elf_link_hash_table. */
-#define is_elf_hash_table(htab) \
+#define is_elf_hash_table(htab) \
(((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table)
/* Used by bfd_sym_from_r_symndx to cache a small number of local
};
#define elf_symbol_from(ABFD,S) \
- (((S)->the_bfd->xvec->flavour == bfd_target_elf_flavour \
- && (S)->the_bfd->tdata.elf_obj_data != 0) \
- ? (elf_symbol_type *) (S) \
- : 0)
+ (((S)->the_bfd != NULL \
+ && (S)->the_bfd->xvec->flavour == bfd_target_elf_flavour \
+ && (S)->the_bfd->tdata.elf_obj_data != 0) \
+ ? (elf_symbol_type *) (S) \
+ : 0)
enum elf_reloc_type_class {
reloc_class_normal,
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *, Elf_Internal_Sym *);
+enum elf_property_kind
+ {
+ /* A new property. */
+ property_unknown = 0,
+ /* A property ignored by backend. */
+ property_ignored,
+ /* A corrupt property reported by backend. */
+ property_corrupt,
+ /* A property should be removed due to property merge. */
+ property_remove,
+ /* A property which is a number. */
+ property_number
+ };
+
+typedef struct elf_property
+{
+ unsigned int pr_type;
+ unsigned int pr_datasz;
+ union
+ {
+ /* For property_number, this is a number. */
+ bfd_vma number;
+ /* Add a new one if elf_property_kind is updated. */
+ } u;
+ enum elf_property_kind pr_kind;
+} elf_property;
+
+typedef struct elf_property_list
+{
+ struct elf_property_list *next;
+ struct elf_property property;
+} elf_property_list;
+
struct bfd_elf_section_reloc_data;
struct elf_backend_data
const void *arch_data;
/* A function to translate an ELF RELA relocation to a BFD arelent
- structure. */
- void (*elf_info_to_howto)
+ structure. Returns TRUE upon success, FALSE otherwise. */
+ bfd_boolean (*elf_info_to_howto)
(bfd *, arelent *, Elf_Internal_Rela *);
/* A function to translate an ELF REL relocation to a BFD arelent
- structure. */
- void (*elf_info_to_howto_rel)
+ structure. Returns TRUE upon success, FALSE otherwise. */
+ bfd_boolean (*elf_info_to_howto_rel)
(bfd *, arelent *, Elf_Internal_Rela *);
/* A function to determine whether a symbol is global when
bfd_boolean (*gc_mark_extra_sections)
(struct bfd_link_info *, elf_gc_mark_hook_fn);
- /* This function, if defined, is called during the sweep phase of gc
- in order that a backend might update any data structures it might
- be maintaining. */
- bfd_boolean (*gc_sweep_hook)
- (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
-
/* 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. */
bfd_boolean (*elf_backend_grok_psinfo)
(bfd *, Elf_Internal_Note *);
+ /* This function, if defined, is called when a "FreeBSD" NT_PRSTATUS
+ note is found in a core file. */
+ bfd_boolean (*elf_backend_grok_freebsd_prstatus)
+ (bfd *, Elf_Internal_Note *);
+
/* This function, if defined, is called to write a note to a corefile. */
char *(*elf_backend_write_core_note)
(bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
that can't be determined for some reason. The default definition
goes by the bfd's EI_CLASS. */
unsigned int (*elf_backend_eh_frame_address_size)
- (bfd *, asection *);
+ (bfd *, const asection *);
/* These functions tell elf-eh-frame whether to attempt to turn
absolute or lsda encodings into pc-relative ones. The default
(bfd *);
reloc_howto_type *(*elf_backend_mips_rtype_to_howto)
- (unsigned int, bfd_boolean);
+ (bfd *, unsigned int, bfd_boolean);
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec,
bfd_vma *code_off);
- /* Return the section which RELOC_SEC applies to. */
- asection *(*get_reloc_section) (asection *reloc_sec);
+ /* Given NAME, the name of a relocation section stripped of its
+ .rel/.rela prefix, return the section in ABFD to which the
+ relocations apply. */
+ asection *(*get_reloc_section) (bfd *abfd, const char *name);
/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
has a type >= SHT_LOOS. Returns TRUE if the fields were initialised,
bfd_boolean (*elf_backend_copy_special_section_fields)
(const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection,
Elf_Internal_Shdr *osection);
-
+
/* Used to handle bad SHF_LINK_ORDER input. */
void (*link_order_error_handler) (const char *, ...);
or give an error and return FALSE. */
bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
+ /* Parse GNU properties. Return the property kind. If the property
+ is corrupt, issue an error message and return property_corrupt. */
+ enum elf_property_kind (*parse_gnu_properties) (bfd *, unsigned int,
+ bfd_byte *,
+ unsigned int);
+
+ /* Merge GNU properties. Return TRUE if property is updated. */
+ bfd_boolean (*merge_gnu_properties) (struct bfd_link_info *, bfd *,
+ elf_property *, elf_property *);
+
+ /* Set up GNU properties. */
+ bfd *(*setup_gnu_properties) (struct bfd_link_info *);
+
/* Encoding used for compact EH tables. */
int (*compact_eh_encoding) (struct bfd_link_info *);
unsigned can_refcount : 1;
unsigned want_got_sym : 1;
unsigned want_dynbss : 1;
+ unsigned want_dynrelro : 1;
/* Targets which do not support physical addressing often require
that the p_paddr field in the section header to be set to zero.
This field indicates whether this behavior is required. */
unsigned want_p_paddr_set_to_zero : 1;
+ /* Target has broken hardware and/or kernel that requires pages not
+ to be mapped twice with different permissions. */
+ unsigned no_page_alias : 1;
+
/* True if an object file lacking a .note.GNU-stack section
should be assumed to be requesting exec stack. At least one
other file in the link needs to have a .note.GNU-stack section
/* Address of protected data defined in the shared library may be
external, i.e., due to copy relocation. */
unsigned extern_protected_data : 1;
+
+ /* True if `_bfd_elf_link_renumber_dynsyms' must be called even for
+ static binaries. */
+ unsigned always_renumber_dynsyms : 1;
+
+ /* True if the 32-bit Linux PRPSINFO structure's `pr_uid' and `pr_gid'
+ members use a 16-bit data type. */
+ unsigned linux_prpsinfo32_ugid16 : 1;
+
+ /* True if the 64-bit Linux PRPSINFO structure's `pr_uid' and `pr_gid'
+ members use a 16-bit data type. */
+ unsigned linux_prpsinfo64_ugid16 : 1;
};
/* Information about reloc sections associated with a bfd_elf_section_data
typedef struct elf_section_list
{
- Elf_Internal_Shdr hdr;
- unsigned int ndx;
+ Elf_Internal_Shdr hdr;
+ unsigned int ndx;
struct elf_section_list * next;
} elf_section_list;
/* Symbol buffer. */
void *symbuf;
+ /* List of GNU properties. Will be updated by setup_gnu_properties
+ after all input GNU properties are merged for output. */
+ elf_property_list *properties;
+
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
obj_attribute_list *other_obj_attributes[2];
Elf_Internal_Shdr **group_sect_ptr;
int num_group;
+ /* Index into group_sect_ptr, updated by setup_group when finding a
+ section's group. Used to optimize subsequent group searches. */
+ unsigned int group_search_offset;
+
unsigned int symtab_section, dynsymtab_section;
unsigned int dynversym_section, dynverdef_section, dynverref_section;
/* An identifier used to distinguish different target
specific extensions to this structure. */
- enum elf_target_id object_id;
+ ENUM_BITFIELD (elf_target_id) object_id : 6;
/* Whether a dyanmic object was specified normally on the linker
command line, or was specified when --as-needed was in effect,
or was found via a DT_NEEDED entry. */
- enum dynamic_lib_link_class dyn_lib_class;
+ 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 if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED
+ property. */
+ unsigned int has_no_copy_on_protected : 1;
/* 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
sh_info field in the symbol table header, and always read all the
symbols. */
- bfd_boolean bad_symtab;
-
- enum elf_gnu_symbols has_gnu_symbols;
+ unsigned int bad_symtab : 1;
/* Information grabbed from an elf core file. */
struct core_elf_obj_tdata *core;
(elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
#define elf_other_obj_attributes_proc(bfd) \
(elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
+#define elf_has_no_copy_on_protected(bfd) \
+ (elf_tdata(bfd) -> has_no_copy_on_protected)
\f
extern void _bfd_elf_swap_verdef_in
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
(bfd *, void *, asymbol *, bfd_print_symbol_type);
extern unsigned int _bfd_elf_eh_frame_address_size
- (bfd *, asection *);
+ (bfd *, const asection *);
extern bfd_byte _bfd_elf_encode_eh_address
(bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset,
asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded);
(bfd *, asection *);
/* If the target doesn't have reloc handling written yet: */
-extern void _bfd_elf_no_info_to_howto
+extern bfd_boolean _bfd_elf_no_info_to_howto
(bfd *, arelent *, Elf_Internal_Rela *);
extern bfd_boolean bfd_section_from_shdr
extern bfd_boolean _bfd_elf_discard_section_eh_frame
(bfd *, struct bfd_link_info *, asection *,
bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *);
+extern bfd_boolean _bfd_elf_adjust_eh_frame_global_symbol
+ (struct elf_link_hash_entry *, void *);
extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr
(bfd *, struct bfd_link_info *);
extern bfd_vma _bfd_elf_eh_frame_section_offset
extern bfd_boolean _bfd_elf_link_create_dynamic_sections
(bfd *, struct bfd_link_info *);
-extern bfd_boolean _bfd_elf_link_omit_section_dynsym
+extern bfd_boolean _bfd_elf_omit_section_dynsym_default
+ (bfd *, struct bfd_link_info *, asection *);
+extern bfd_boolean _bfd_elf_omit_section_dynsym_all
(bfd *, struct bfd_link_info *, asection *);
extern bfd_boolean _bfd_elf_create_dynamic_sections
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_setup_sections
(bfd *);
+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 const bfd_target *bfd_elf32_object_p
extern bfd_boolean bfd_elf_gc_common_final_link
(bfd *, struct bfd_link_info *);
-extern asection *_bfd_elf_is_start_stop
- (const struct bfd_link_info *, struct elf_link_hash_entry *);
-
extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
(bfd_vma, void *);
extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *,
bfd_vma *);
-extern asection *_bfd_elf_get_reloc_section (asection *);
+extern asection *_bfd_elf_plt_get_reloc_section (bfd *, const char *);
extern int bfd_elf_get_default_section_type (flagword);
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_s390_vxrs_high
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_gs_cb
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_gs_bc
+ (bfd *, char *, int *, const void *, int);
extern char *elfcore_write_arm_vfp
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_aarch_tls
extern char *elfcore_write_linux_prpsinfo64
(bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
-/* Linux/PPC32 uses different layout compared to most archs. */
-extern char *elfcore_write_ppc_linux_prpsinfo32
- (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
-
extern bfd *_bfd_elf32_bfd_from_remote_memory
(bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
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 _bfd_elf_parse_gnu_properties
+ (bfd *, Elf_Internal_Note *);
+extern elf_property * _bfd_elf_get_property
+ (bfd *, unsigned int, unsigned int);
+extern bfd *_bfd_elf_link_setup_gnu_properties
+ (struct bfd_link_info *);
+
/* The linker may need to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
(struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_dyn_relocs **, bfd_boolean *, unsigned int,
unsigned int, unsigned int, bfd_boolean);
-extern long _bfd_elf_ifunc_get_synthetic_symtab
- (bfd *, long, asymbol **, long, asymbol **, asymbol **, asection *,
- bfd_vma *(*) (bfd *, asymbol **, asection *, asection *));
extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
memmove (rel, rel + count, \
(relend - rel - count) * sizeof (*rel)); \
\
- input_section->reloc_count--; \
+ input_section->reloc_count -= count; \
relend -= count; \
rel--; \
continue; \
library, if any. A unique symbol can never be bound locally. */
#define SYMBOLIC_BIND(INFO, H) \
(!(H)->unique_global \
- && ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)))
+ && ((INFO)->symbolic \
+ || (H)->start_stop \
+ || ((INFO)->dynamic && !(H)->dynamic)))
#ifdef __cplusplus
}