/* BFD back-end data structures for ELF files.
- Copyright (C) 1992-2015 Free Software Foundation, Inc.
+ Copyright (C) 1992-2016 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
struct bfd_link_hash_entry root;
/* Symbol index in output file. This is initialized to -1. It is
- set to -2 if the symbol is used by a reloc. */
+ set to -2 if the symbol is used by a reloc. It is set to -3 if
+ this symbol is defined in a discarded section. */
long indx;
/* Symbol index as a dynamic symbol. Initialized to -1, and remains
union gotplt_union init_got_offset;
union gotplt_union init_plt_offset;
- /* The number of symbols found in the link which must be put into
- the .dynsym section. */
+ /* The number of symbols found in the link which is intended for the
+ mandatory DT_SYMTAB tag (.dynsym section) in .dynamic section. */
bfd_size_type dynsymcount;
/* The string table of dynamic symbols, which becomes the .dynstr
asection *iplt;
asection *irelplt;
asection *irelifunc;
+ asection *dynsym;
};
/* Look up an entry in an ELF linker hash table. */
enum elf_reloc_type_class {
reloc_class_normal,
reloc_class_relative,
- reloc_class_plt,
reloc_class_copy,
- reloc_class_ifunc
+ reloc_class_ifunc,
+ reloc_class_plt
};
struct elf_reloc_cookie
struct bfd_elf_special_section
{
const char *prefix;
- int prefix_length;
+ unsigned int prefix_length;
/* 0 means name must match PREFIX exactly.
-1 means name must start with PREFIX followed by an arbitrary string.
-2 means name must match PREFIX exactly or consist of PREFIX followed
by a dot then anything.
> 0 means name must start with the first PREFIX_LENGTH chars of
PREFIX and finish with the last SUFFIX_LENGTH chars of PREFIX. */
- int suffix_length;
- int type;
+ signed int suffix_length;
+ unsigned int type;
bfd_vma attr;
};
(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;
+ const char *filename;
+} 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
{
/* The architecture for this backend. */
unsigned int (*elf_backend_count_relocs)
(struct bfd_link_info *, asection *);
+ /* Count additionals relocations. Called for relocatable links if
+ additional relocations needs to be created. */
+ unsigned int (*elf_backend_count_additional_relocs)
+ (asection *);
+
/* Say whether to sort relocs output by ld -r and ld --emit-relocs,
by r_offset. If NULL, default to true. */
bfd_boolean (*sort_relocs_p)
/* Return the section which RELOC_SEC applies to. */
asection *(*get_reloc_section) (asection *reloc_sec);
+ /* 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,
+ FALSE otherwise. Can be called multiple times for a given section,
+ until it returns TRUE. Most of the times it is called ISECTION will be
+ set to an input section that might be associated with the output section.
+ The last time that it is called, ISECTION will be set to NULL. */
+ 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. */
bfd_error_handler_type link_order_error_handler;
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) (bfd *, elf_property *,
+ elf_property *);
+
+ /* Set up GNU properties. */
+ void (*setup_gnu_properties) (struct bfd_link_info *);
+
/* Encoding used for compact EH tables. */
int (*compact_eh_encoding) (struct bfd_link_info *);
/* Alignment for the PT_GNU_STACK segment. */
unsigned stack_align;
+ /* Flag bits to assign to a section of type SHT_STRTAB. */
+ unsigned long elf_strtab_flags;
+
/* 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
elf_gnu_symbol_all = (elf_gnu_symbol_ifunc | elf_gnu_symbol_unique)
};
+typedef struct elf_section_list
+{
+ Elf_Internal_Shdr hdr;
+ unsigned int ndx;
+ struct elf_section_list * next;
+} elf_section_list;
+
+
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
Elf_Internal_Shdr dynversym_hdr;
Elf_Internal_Shdr dynverref_hdr;
Elf_Internal_Shdr dynverdef_hdr;
- Elf_Internal_Shdr symtab_shndx_hdr;
+ elf_section_list * symtab_shndx_list;
bfd_vma gp; /* The gp value */
unsigned int gp_size; /* The gp size */
unsigned int num_elf_sections; /* elf_sect_ptr size */
/* 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;
- unsigned int symtab_section, symtab_shndx_section, dynsymtab_section;
+ unsigned int symtab_section, dynsymtab_section;
unsigned int dynversym_section, dynverdef_section, dynverref_section;
/* An identifier used to distinguish different target
#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)
-#define elf_symtab_shndx(bfd) (elf_tdata(bfd) -> symtab_shndx_section)
+#define elf_symtab_shndx_list(bfd) (elf_tdata(bfd) -> symtab_shndx_list)
#define elf_strtab_sec(bfd) (elf_tdata(bfd) -> o->strtab_section)
#define elf_shstrtab_sec(bfd) (elf_tdata(bfd) -> o->shstrtab_section)
#define elf_symtab_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr)
(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)
\f
extern void _bfd_elf_swap_verdef_in
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
extern bfd_boolean _bfd_elf_find_inliner_info
(bfd *, const char **, const char **, unsigned int *);
-extern bfd_boolean _bfd_elf_find_function
+extern asymbol *_bfd_elf_find_function
(bfd *, asymbol **, asection *, bfd_vma, const char **, const char **);
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
(void);
extern void _bfd_elf_strtab_free
(struct elf_strtab_hash *);
-extern bfd_size_type _bfd_elf_strtab_add
+extern size_t _bfd_elf_strtab_add
(struct elf_strtab_hash *, const char *, bfd_boolean);
extern void _bfd_elf_strtab_addref
- (struct elf_strtab_hash *, bfd_size_type);
+ (struct elf_strtab_hash *, size_t);
extern void _bfd_elf_strtab_delref
- (struct elf_strtab_hash *, bfd_size_type);
+ (struct elf_strtab_hash *, size_t);
extern unsigned int _bfd_elf_strtab_refcount
- (struct elf_strtab_hash *, bfd_size_type);
+ (struct elf_strtab_hash *, size_t);
extern void _bfd_elf_strtab_clear_all_refs
- (struct elf_strtab_hash *tab);
-extern void _bfd_elf_strtab_restore_size
- (struct elf_strtab_hash *, bfd_size_type);
+ (struct elf_strtab_hash *);
+extern void *_bfd_elf_strtab_save
+ (struct elf_strtab_hash *);
+extern void _bfd_elf_strtab_restore
+ (struct elf_strtab_hash *, void *);
extern bfd_size_type _bfd_elf_strtab_size
(struct elf_strtab_hash *);
extern bfd_size_type _bfd_elf_strtab_offset
- (struct elf_strtab_hash *, bfd_size_type);
+ (struct elf_strtab_hash *, size_t);
extern bfd_boolean _bfd_elf_strtab_emit
(bfd *, struct elf_strtab_hash *);
extern void _bfd_elf_strtab_finalize
(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_link_check_relocs
+ (bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_link_record_dynamic_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *);
extern asection *_bfd_elf_gc_mark_rsec
(struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
- struct elf_reloc_cookie *);
+ struct elf_reloc_cookie *, bfd_boolean *);
extern bfd_boolean _bfd_elf_gc_mark_reloc
(struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
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 Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
(bfd * abfd, asection * section);
+/* PowerPC @tls opcode transform/validate. */
+extern unsigned int _bfd_elf_ppc_at_tls_transform
+ (unsigned int, unsigned int);
+/* PowerPC @tprel opcode transform/validate. */
+extern unsigned int _bfd_elf_ppc_at_tprel_transform
+ (unsigned int, unsigned int);
+/* PowerPC elf_object_p tweak. */
+extern bfd_boolean _bfd_elf_ppc_set_arch (bfd *);
+
/* Exported interface for writing elf corefile notes. */
extern char *elfcore_write_note
(bfd *, char *, int *, const char *, int, const void *, 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 _bfd_elf_parse_gnu_properties
+ (bfd *, Elf_Internal_Note *);
+extern elf_property * _bfd_elf_get_property
+ (bfd *, unsigned int, unsigned int);
+extern void _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
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
(struct bfd_link_info *, struct elf_link_hash_entry *,
- struct elf_dyn_relocs **, unsigned int, unsigned int, unsigned int);
+ 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 *));
else if (info->unresolved_syms_in_objects == RM_IGNORE \
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \
ignored = TRUE; \
- else if (!info->relocatable) \
+ 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); \
- if (!info->callbacks->undefined_symbol (info, \
- h->root.root.string, \
- input_bfd, \
- input_section, \
- rel->r_offset, err)) \
- return FALSE; \
+ (*info->callbacks->undefined_symbol) (info, \
+ h->root.root.string, \
+ input_bfd, \
+ input_section, \
+ rel->r_offset, err); \
warned = TRUE; \
} \
(void) unresolved_reloc; \
_bfd_clear_contents (howto, input_bfd, input_section, \
contents + rel[index].r_offset); \
\
- if (info->relocatable \
+ if (bfd_link_relocatable (info) \
&& (input_section->flags & SEC_DEBUGGING)) \
{ \
/* Only remove relocations in debug sections since other \