/* BFD back-end data structures for ELF files.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
Free Software Foundation, Inc.
Written by Cygnus Support.
/* Symbol st_other value, symbol visibility. */
unsigned int other : 8;
+ /* The symbol's st_target_internal value (see Elf_Internal_Sym). */
+ unsigned int target_internal : 8;
+
/* Symbol is referenced by a non-shared object (other than the object
in which it is defined). */
unsigned int ref_regular : 1;
FIXME: There is no real need for this field if def_dynamic is never
cleared and all places that test def_dynamic also test def_regular. */
unsigned int dynamic_def : 1;
- /* Symbol is weak in all shared objects. */
- unsigned int dynamic_weak : 1;
+ /* Symbol has a non-weak reference from a shared object. */
+ unsigned int ref_dynamic_nonweak : 1;
/* Symbol is referenced with a relocation where C/C++ pointer equality
matters. */
unsigned int pointer_equality_needed : 1;
};
/* Will references to this symbol always reference the symbol
- in this object? STV_PROTECTED is excluded from the visibility test
- here so that function pointer comparisons work properly. Since
- function symbols not defined in an app are set to their .plt entry,
- it's necessary for shared libs to also reference the .plt even
- though the symbol is really local to the shared lib. */
+ in this object? */
#define SYMBOL_REFERENCES_LOCAL(INFO, H) \
_bfd_elf_symbol_refs_local_p (H, INFO, 0)
one line. */
enum elf_target_id
{
- ALPHA_ELF_DATA = 1,
+ AARCH64_ELF_DATA = 1,
+ ALPHA_ELF_DATA,
ARM_ELF_DATA,
AVR_ELF_DATA,
BFIN_ELF_DATA,
M32R_ELF_DATA,
M68HC11_ELF_DATA,
M68K_ELF_DATA,
+ METAG_ELF_DATA,
MICROBLAZE_ELF_DATA,
MIPS_ELF_DATA,
MN10300_ELF_DATA,
+ NIOS2_ELF_DATA,
PPC32_ELF_DATA,
PPC64_ELF_DATA,
S390_ELF_DATA,
TIC6X_ELF_DATA,
X86_64_ELF_DATA,
XTENSA_ELF_DATA,
+ XGATE_ELF_DATA,
+ TILEGX_ELF_DATA,
+ TILEPRO_ELF_DATA,
GENERIC_ELF_DATA
};
/* The _PROCEDURE_LINKAGE_TABLE_ symbol. */
struct elf_link_hash_entry *hplt;
+ /* The _DYNAMIC symbol. */
+ struct elf_link_hash_entry *hdynamic;
+
/* A pointer to information used to merge SEC_MERGE sections. */
void *merge_info;
/* The architecture for this backend. */
enum bfd_architecture arch;
+ /* An identifier used to distinguish different target specific
+ extensions to elf_obj_tdata and elf_link_hash_table structures. */
+ enum elf_target_id target_id;
+
/* The ELF machine code (EM_xxxx) for this backend. */
int elf_machine_code;
/* The BFD flags applied to sections created for dynamic linking. */
flagword dynamic_sec_flags;
+ /* Architecture-specific data for this backend.
+ This is actually a pointer to some type like struct elf_ARCH_data. */
+ const void *arch_data;
+
/* A function to translate an ELF RELA relocation to a BFD arelent
structure. */
void (*elf_info_to_howto)
char *(*elf_backend_write_core_note)
(bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
+ /* This function, if defined, is called to convert target-specific
+ section flag names into hex values. */
+ flagword (*elf_backend_lookup_section_flags_hook)
+ (char *);
+
/* This function returns class of a reloc type. */
enum elf_reloc_type_class (*elf_backend_reloc_type_class)
(const Elf_Internal_Rela *);
see elf.c, elfcode.h. */
bfd *(*elf_backend_bfd_from_remote_memory)
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
- int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len));
+ int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
+ bfd_size_type len));
/* This function is used by `_bfd_elf_get_synthetic_symtab';
see elf.c. */
/* Return TRUE if type is a function symbol type. */
bfd_boolean (*is_function_type) (unsigned int type);
+ /* If the ELF symbol SYM might be a function in SEC, return the
+ function size and set *CODE_OFF to the function's entry point,
+ otherwise return zero. */
+ bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec,
+ bfd_vma *code_off);
+
/* Used to handle bad SHF_LINK_ORDER input. */
bfd_error_handler_type link_order_error_handler;
actual tag number to place in the input position. */
int (*obj_attrs_order) (int);
+ /* Handle merging unknown attributes; either warn and return TRUE,
+ or give an error and return FALSE. */
+ bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
+
+ /* This is non-zero if static TLS segments require a special alignment. */
+ unsigned static_tls_alignment;
+
+ /* Alignment for the PT_GNU_STACK segment. */
+ unsigned stack_align;
+
/* 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
unsigned default_execstack : 1;
};
+/* Information about reloc sections associated with a bfd_elf_section_data
+ structure. */
+struct bfd_elf_section_reloc_data
+{
+ /* The ELF header for the reloc section associated with this
+ section, if any. */
+ Elf_Internal_Shdr *hdr;
+ /* The number of relocations currently assigned to HDR. */
+ unsigned int count;
+ /* The ELF section number of the reloc section. Only used for an
+ output file. */
+ int idx;
+ /* Used by the backend linker to store the symbol hash table entries
+ associated with relocs against global symbols. */
+ struct elf_link_hash_entry **hashes;
+};
+
/* Information stored for each BFD section in an ELF file. This
structure is allocated by elf_new_section_hook. */
/* The ELF header for this section. */
Elf_Internal_Shdr this_hdr;
- /* The ELF header for the reloc section associated with this
- section, if any. */
- Elf_Internal_Shdr rel_hdr;
-
- /* If there is a second reloc section associated with this section,
- as can happen on Irix 6, this field points to the header. */
- Elf_Internal_Shdr *rel_hdr2;
+ /* INPUT_SECTION_FLAGS if specified in the linker script. */
+ struct flag_info *section_flag_info;
- /* The number of relocations currently assigned to REL_HDR. */
- unsigned int rel_count;
-
- /* The number of relocations currently assigned to REL_HDR2. */
- unsigned int rel_count2;
+ /* Information about the REL and RELA reloc sections associated
+ with this section, if any. */
+ struct bfd_elf_section_reloc_data rel, rela;
/* The ELF section number of this section. */
int this_idx;
- /* The ELF section number of the reloc section indicated by
- REL_HDR if any. Only used for an output file. */
- int rel_idx;
-
- /* The ELF section number of the reloc section indicated by
- 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
/* A pointer to the linked-to section for SHF_LINK_ORDER. */
asection *linked_to;
- /* 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;
-
/* A pointer to the swapped relocs. If the section uses REL relocs,
rather than RELA, all the r_addend fields will be zero. This
pointer may be NULL. It is used by the backend linker. */
void *sec_info;
};
-#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd)
+#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd)
#define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to)
-#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type)
-#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags)
-#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_fde_list(sec) (elf_section_data(sec)->fde_list)
+#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type)
+#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags)
+#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_fde_list(sec) (elf_section_data(sec)->fde_list)
#define elf_sec_group(sec) (elf_section_data(sec)->sec_group)
#define xvec_get_elf_backend_data(xvec) \
Tag_compatibility = 32
};
+/* The following struct stores information about every SystemTap section
+ found in the object file. */
+struct sdt_note
+{
+ struct sdt_note *next;
+ bfd_size_type size;
+ bfd_byte data[1];
+};
+
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
const char *dt_name;
/* The linker emulation needs to know what audit libs
- are used by a dynamic object. */
+ are used by a dynamic object. */
const char *dt_audit;
/* Records the result of `get_program_header_size'. */
bfd_size_type build_id_size;
bfd_byte *build_id;
+ /* Linked-list containing information about every Systemtap section
+ found in the object file. Each section corresponds to one entry
+ in the list. */
+ struct sdt_note *sdt_note_head;
+
/* True if the bfd contains symbols that have the STT_GNU_IFUNC
- symbol type. Used to set the osabi field in the ELF header
- structure. */
- bfd_boolean has_ifunc_symbols;
+ symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
+ field in the ELF header structure. */
+ bfd_boolean has_gnu_symbols;
/* An identifier used to distinguish different target
specific extensions to this structure. */
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
extern bfd_boolean bfd_elf_allocate_object
(bfd *, size_t, enum elf_target_id);
-extern bfd_boolean bfd_elf_make_generic_object
+extern bfd_boolean bfd_elf_make_object
(bfd *);
extern bfd_boolean bfd_elf_mkcorefile
(bfd *);
(bfd *, const asection *, bfd *, const asection *);
extern bfd_boolean bfd_elf_is_group_section
(bfd *, const struct bfd_section *);
-extern void _bfd_elf_section_already_linked
- (bfd *, struct bfd_section *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_section_already_linked
+ (bfd *, asection *, struct bfd_link_info *);
extern void bfd_elf_set_group_contents
(bfd *, asection *, void *);
extern asection *_bfd_elf_check_kept_section
(asection *, struct bfd_link_info *);
-extern void _bfd_elf_link_just_syms
- (asection *, struct bfd_link_info *);
+#define _bfd_elf_link_just_syms _bfd_generic_link_just_syms
extern void _bfd_elf_copy_link_hash_symbol_type
(bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
extern bfd_boolean _bfd_elf_size_group_sections
extern bfd_boolean _bfd_elf_find_nearest_line
(bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
unsigned int *);
+extern bfd_boolean _bfd_elf_find_nearest_line_discriminator
+ (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
+ unsigned int *, unsigned int *);
extern bfd_boolean _bfd_elf_find_line
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
+extern bfd_boolean _bfd_elf_find_line_discriminator
+ (bfd *, asymbol **, asymbol *, const char **, unsigned int *, unsigned int *);
#define _bfd_generic_find_line _bfd_elf_find_line
+#define _bfd_generic_find_nearest_line_discriminator \
+ _bfd_elf_find_nearest_line_discriminator
extern bfd_boolean _bfd_elf_find_inliner_info
(bfd *, const char **, const char **, unsigned int *);
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
extern bfd_boolean _bfd_elf_new_section_hook
(bfd *, asection *);
extern bfd_boolean _bfd_elf_init_reloc_shdr
- (bfd *, Elf_Internal_Shdr *, asection *, bfd_boolean);
+ (bfd *, struct bfd_elf_section_reloc_data *, asection *, bfd_boolean);
extern const struct bfd_elf_special_section *_bfd_elf_get_special_section
(const char *, const struct bfd_elf_special_section *, unsigned int);
extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr
extern int _bfd_elf_symbol_from_bfd_symbol
(bfd *, asymbol **);
-extern Elf_Internal_Sym *bfd_sym_from_r_symndx
+extern Elf_Internal_Sym *bfd_sym_from_r_symndx
(struct sym_cache *, bfd *, unsigned long);
extern asection *bfd_section_from_elf_index
(bfd *, unsigned int);
(struct elf_strtab_hash *, bfd_size_type);
extern void _bfd_elf_strtab_delref
(struct elf_strtab_hash *, bfd_size_type);
-extern void _bfd_elf_strtab_clear_all_refs
- (struct elf_strtab_hash *);
+extern unsigned int _bfd_elf_strtab_refcount
+ (struct elf_strtab_hash *, bfd_size_type);
+extern void _bfd_elf_strtab_clear_refs
+ (struct elf_strtab_hash *, bfd_size_type);
+#define _bfd_elf_strtab_clear_all_refs(tab) \
+ do { _bfd_elf_strtab_clear_refs (tab, 1); } while (0)
extern bfd_size_type _bfd_elf_strtab_size
(struct elf_strtab_hash *);
extern bfd_size_type _bfd_elf_strtab_offset
(bfd *, struct bfd_link_info *, asection *, bfd_byte *);
extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr
(bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_eh_frame_present
+ (struct bfd_link_info *);
extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
(struct bfd_link_info *);
extern bfd_boolean _bfd_elf_merge_symbol
(bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
- asection **, bfd_vma *, unsigned int *,
+ asection **, bfd_vma *, bfd_boolean *, unsigned int *,
struct elf_link_hash_entry **, bfd_boolean *,
bfd_boolean *, bfd_boolean *, bfd_boolean *);
extern asection *_bfd_elf_common_section
(asection *);
-extern void _bfd_dwarf2_cleanup_debug_info
- (bfd *);
-
extern bfd_vma _bfd_elf_default_got_elt_size
(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, bfd *,
unsigned long);
extern bfd_boolean _bfd_elf_gc_mark
(struct bfd_link_info *, asection *, elf_gc_mark_hook_fn);
+extern bfd_boolean _bfd_elf_gc_mark_extra_sections
+ (struct bfd_link_info *, elf_gc_mark_hook_fn);
+
extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_is_function_type (unsigned int);
+extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *,
+ bfd_vma *);
+
extern int bfd_elf_get_default_section_type (flagword);
+extern bfd_boolean bfd_elf_lookup_section_flags
+ (struct bfd_link_info *, struct flag_info *, asection *);
+
extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
(bfd * abfd, asection * section);
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_s390_prefix
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_last_break
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_system_call
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_arm_vfp
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_tls
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_hw_break
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_hw_watch
+ (bfd *, char *, int *, const void *, int);
extern char *elfcore_write_lwpstatus
(bfd *, char *, int *, long, int, const void *);
extern char *elfcore_write_register_note
(bfd *, char *, int *, const char *, const void *, int);
+/* Internal structure which holds information to be included in the
+ PRPSINFO section of Linux core files.
+
+ This is an "internal" structure in the sense that it should be used
+ to pass information to BFD (via the `elfcore_write_linux_prpsinfo'
+ function), so things like endianess shouldn't be an issue. This
+ structure will eventually be converted in one of the
+ `elf_external_linux_*' structures and written out to an output bfd
+ by one of the functions declared below. */
+
+struct elf_internal_linux_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long pr_flag; /* Flags. */
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ char pr_fname[16 + 1]; /* Filename of executable. */
+ char pr_psargs[80 + 1]; /* Initial part of arg list. */
+ };
+
+/* Linux/most 32-bit archs. */
+extern char *elfcore_write_linux_prpsinfo32
+ (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/most 64-bit archs. */
+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_vma *loadbasep,
- int (*target_read_memory) (bfd_vma, bfd_byte *, int));
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
extern bfd *_bfd_elf64_bfd_from_remote_memory
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
- int (*target_read_memory) (bfd_vma, bfd_byte *, int));
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
extern bfd_vma bfd_elf_obj_attr_size (bfd *);
extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma);
extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int);
extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *);
extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *);
+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);
-/* The linker may needs to keep track of the number of relocs that it
+/* 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
unnecessary. We can store the information in a field extending the
(struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_dyn_relocs **, unsigned int, unsigned int);
+extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
+extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
+
+extern bfd_vma elf64_r_info (bfd_vma, bfd_vma);
+extern bfd_vma elf64_r_sym (bfd_vma);
+extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
+extern bfd_vma elf32_r_sym (bfd_vma);
+
/* Large common section. */
extern asection _bfd_elf_large_com_section;
/* This macro is to avoid lots of duplicated code in the body of the
loop over relocations in xxx_relocate_section() in the various
elfxx-xxxx.c files.
-
+
Handle relocations against symbols from removed linkonce sections,
or sections discarded by a linker script. When doing a relocatable
link, we remove such relocations. Otherwise, we just want the
section contents zeroed and avoid any special processing. */
#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section, \
- rel, relend, howto, contents) \
+ rel, count, relend, \
+ howto, index, contents) \
{ \
+ int i_; \
+ _bfd_clear_contents (howto, input_bfd, input_section, \
+ contents + rel[index].r_offset); \
+ \
if (info->relocatable \
&& (input_section->flags & SEC_DEBUGGING)) \
{ \
sections may require relocations. */ \
Elf_Internal_Shdr *rel_hdr; \
\
- rel_hdr = &elf_section_data (input_section->output_section)->rel_hdr; \
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
\
/* Avoid empty output section. */ \
- if (rel_hdr->sh_size > rel_hdr->sh_entsize) \
+ if (rel_hdr->sh_size > count * rel_hdr->sh_entsize) \
{ \
- rel_hdr->sh_size -= rel_hdr->sh_entsize; \
- rel_hdr = &elf_section_data (input_section)->rel_hdr; \
- rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ rel_hdr->sh_size -= count * rel_hdr->sh_entsize; \
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section); \
+ rel_hdr->sh_size -= count * rel_hdr->sh_entsize; \
\
- memmove (rel, rel + 1, (relend - rel) * sizeof (*rel)); \
+ memmove (rel, rel + count, \
+ (relend - rel - count) * sizeof (*rel)); \
\
- input_section->reloc_count--; \
- relend--; \
+ input_section->reloc_count -= count; \
+ relend -= count; \
rel--; \
continue; \
} \
} \
\
- _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); \
- rel->r_info = 0; \
- rel->r_addend = 0; \
+ for (i_ = 0; i_ < count; i_++) \
+ { \
+ rel[i_].r_info = 0; \
+ rel[i_].r_addend = 0; \
+ } \
+ rel += count - 1; \
continue; \
}
-/* Will a symbol be bound to the the definition within the shared
+/* Will a symbol be bound to the definition within the shared
library, if any. A unique symbol can never be bound locally. */
#define SYMBOLIC_BIND(INFO, H) \
(!(H)->unique_global \