/* BFD back-end data structures for ELF files.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
#ifndef _LIBELF_H_
#define _LIBELF_H_ 1
#include "elf/common.h"
-#include "elf/internal.h"
#include "elf/external.h"
+#include "elf/internal.h"
#include "bfdlink.h"
/* The number of entries in a section is its size divided by the size
unsigned int hidden : 1;
/* Symbol was forced to local scope due to a version script file. */
unsigned int forced_local : 1;
+ /* Symbol was forced to be dynamic due to a version script file. */
+ unsigned int dynamic : 1;
/* Symbol was marked during garbage collection. */
unsigned int mark : 1;
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
};
/* Structures used by the eh_frame optimization code. */
-struct cie_header
-{
- unsigned int length;
- unsigned int id;
-};
-
-struct cie
-{
- struct cie_header hdr;
- unsigned char version;
- char augmentation[20];
- bfd_vma code_align;
- bfd_signed_vma data_align;
- bfd_vma ra_column;
- bfd_vma augmentation_size;
- struct elf_link_hash_entry *personality;
- unsigned char per_encoding;
- unsigned char lsda_encoding;
- unsigned char fde_encoding;
- unsigned char initial_insn_length;
- unsigned char make_relative;
- unsigned char make_lsda_relative;
- unsigned char initial_instructions[50];
-};
-
struct eh_cie_fde
{
- /* For FDEs, this points to the CIE used. */
- struct eh_cie_fde *cie_inf;
+ union {
+ struct {
+ /* If REMOVED == 1, this is the CIE that the FDE originally used.
+ The CIE belongs to the same .eh_frame input section as the FDE.
+
+ If REMOVED == 0, this is the CIE that we have chosen to use for
+ the output FDE. The CIE's REMOVED field is also 0, but the CIE
+ might belong to a different .eh_frame input section from the FDE. */
+ struct eh_cie_fde *cie_inf;
+ struct eh_cie_fde *next_for_section;
+ } fde;
+ struct {
+ /* CIEs have three states:
+
+ - REMOVED && !MERGED: Slated for removal because we haven't yet
+ proven that an FDE needs it. FULL_CIE, if nonnull, points to
+ more detailed information about the CIE.
+
+ - REMOVED && MERGED: We have merged this CIE with MERGED_WITH,
+ which may not belong to the same input section.
+
+ - !REMOVED: We have decided to keep this CIE. SEC is the
+ .eh_frame input section that contains the CIE. */
+ union {
+ struct cie *full_cie;
+ struct eh_cie_fde *merged_with;
+ asection *sec;
+ } u;
+
+ /* True if we have marked relocations associated with this CIE. */
+ unsigned int gc_mark : 1;
+
+ /* True if we have decided to turn an absolute LSDA encoding into
+ a PC-relative one. */
+ unsigned int make_lsda_relative : 1;
+
+ /* True if the CIE contains personality data and if that data
+ uses a PC-relative encoding. */
+ unsigned int per_encoding_relative : 1;
+
+ /* True if we need to add an 'R' (FDE encoding) entry to the
+ CIE's augmentation data. */
+ unsigned int add_fde_encoding : 1;
+
+ /* True if we have merged this CIE with another. */
+ unsigned int merged : 1;
+ } cie;
+ } u;
+ unsigned int reloc_index;
unsigned int size;
unsigned int offset;
unsigned int new_offset;
- unsigned char fde_encoding;
- unsigned char lsda_encoding;
- unsigned char lsda_offset;
+ unsigned int fde_encoding : 8;
+ unsigned int lsda_encoding : 8;
+ unsigned int lsda_offset : 8;
+
+ /* True if this entry represents a CIE, false if it represents an FDE. */
unsigned int cie : 1;
+
+ /* True if this entry is currently marked for removal. */
unsigned int removed : 1;
+
+ /* True if we need to add a 'z' (augmentation size) entry to the CIE's
+ augmentation data, and an associated byte to each of the CIE's FDEs. */
unsigned int add_augmentation_size : 1;
- unsigned int add_fde_encoding : 1;
+
+ /* True if we have decided to convert absolute FDE relocations into
+ relative ones. This applies to the first relocation in the FDE,
+ which is against the code that the FDE describes. */
unsigned int make_relative : 1;
- unsigned int make_lsda_relative : 1;
- unsigned int need_lsda_relative : 1;
- unsigned int per_encoding_relative : 1;
+
+ /* Unused bits. */
+ unsigned int pad1 : 4;
+
+ unsigned int *set_loc;
};
struct eh_frame_sec_info
{
unsigned int count;
- unsigned int alloced;
+ struct cie *cies;
struct eh_cie_fde entry[1];
};
bfd_vma fde;
};
+struct htab;
+
struct eh_frame_hdr_info
{
- struct cie last_cie;
- asection *last_cie_sec;
- struct eh_cie_fde *last_cie_inf;
+ struct htab *cies;
asection *hdr_sec;
unsigned int fde_count, array_count;
struct eh_frame_array_ent *array;
+ /* TRUE if we should try to merge CIEs between input sections. */
+ bfd_boolean merge_cies;
+ /* TRUE if all .eh_frames have been parsd. */
+ bfd_boolean parsed_eh_frames;
/* TRUE if .eh_frame_hdr should contain the sorted search table.
We build it if we successfully read all .eh_frame input sections
and recognize them. */
bfd_boolean table;
- bfd_boolean offsets_adjusted;
};
/* ELF linker hash table. */
when linking against or generating a shared object. */
bfd_boolean dynamic_sections_created;
+ /* True if this target has relocatable executables, so needs dynamic
+ section symbols. */
+ bfd_boolean is_relocatable_executable;
+
/* The BFD used to hold special sections created by the linker.
This will be the first BFD found which requires these sections to
be created. */
/* The value to use when initialising got.refcount/offset and
plt.refcount/offset in an elf_link_hash_entry. Set to zero when
- the values are refcounts. Set to init_offset in
- size_dynamic_sections when the values may be offsets. */
- union gotplt_union init_refcount;
+ the values are refcounts. Set to init_got_offset/init_plt_offset
+ in size_dynamic_sections when the values may be offsets. */
+ union gotplt_union init_got_refcount;
+ union gotplt_union init_plt_refcount;
/* The value to use for got.refcount/offset and plt.refcount/offset
when the values may be offsets. Normally (bfd_vma) -1. */
- union gotplt_union init_offset;
+ 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. */
included in the link. */
struct bfd_link_needed_list *needed;
+ /* Sections in the output bfd that provides a section symbol
+ to be used by relocations emitted against local symbols.
+ Most targets will not use data_index_section. */
+ asection *text_index_section;
+ asection *data_index_section;
+
/* The _GLOBAL_OFFSET_TABLE_ symbol. */
struct elf_link_hash_entry *hgot;
+ /* The _PROCEDURE_LINKAGE_TABLE_ symbol. */
+ struct elf_link_hash_entry *hplt;
+
/* A pointer to information used to merge SEC_MERGE sections. */
void *merge_info;
/* A linked list of BFD's loaded in the link. */
struct elf_link_loaded_list *loaded;
-
- /* True if this target has relocatable executables, so needs dynamic
- section symbols. */
- bfd_boolean is_relocatable_executable;
};
/* Look up an entry in an ELF linker hash table. */
{
bfd *abfd;
unsigned long indx[LOCAL_SYM_CACHE_SIZE];
- asection *sec[LOCAL_SYM_CACHE_SIZE];
+ unsigned int shndx[LOCAL_SYM_CACHE_SIZE];
};
\f
/* Constant information held for an ELF backend. */
(bfd *, const Elf_Internal_Phdr *, unsigned int);
bfd_boolean
(*write_shdrs_and_ehdr) (bfd *);
+ bfd_boolean (*checksum_contents)
+ (bfd * , void (*) (const void *, size_t, void *), void *);
void (*write_relocs)
(bfd *, asection *, void *);
- void (*swap_symbol_in)
+ bfd_boolean (*swap_symbol_in)
(bfd *, const void *, const void *, Elf_Internal_Sym *);
void (*swap_symbol_out)
(bfd *, const Elf_Internal_Sym *, void *, void *);
int attr;
};
+enum action_discarded
+ {
+ COMPLAIN = 1,
+ PRETEND = 2
+ };
+
+typedef asection * (*elf_gc_mark_hook_fn)
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
struct elf_backend_data
{
/* The architecture for this backend. */
/* The ELF machine code (EM_xxxx) for this backend. */
int elf_machine_code;
+ /* EI_OSABI. */
+ int elf_osabi;
+
/* The maximum page size for this backend. */
bfd_vma maxpagesize;
pages at least this large. May be smaller than maxpagesize. */
bfd_vma minpagesize;
+ /* The common page size for this backend. */
+ bfd_vma commonpagesize;
+
/* The BFD flags applied to sections created for dynamic linking. */
flagword dynamic_sec_flags;
bfd_boolean (*elf_backend_section_from_shdr)
(bfd *, Elf_Internal_Shdr *, const char *, int);
- /* A function to convert machine dependent section header flags to
+ /* 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 *);
+ /* A function that returns a struct containing ELF section flags and
+ type for the given BFD section. */
+ const struct bfd_elf_special_section * (*get_sec_type_attr)
+ (bfd *, asection *);
+
/* A function to handle unusual program segment types when creating BFD
sections from ELF program segments. */
bfd_boolean (*elf_backend_section_from_phdr)
bfd_boolean (*elf_backend_omit_section_dynsym)
(bfd *output_bfd, struct bfd_link_info *info, asection *osec);
+ /* Return TRUE if relocations of targets are compatible to the extent
+ that CHECK_RELOCS will properly process them. PR 4424. */
+ bfd_boolean (*relocs_compatible) (const bfd_target *, const bfd_target *);
+
/* The CHECK_RELOCS function is called by the add_symbols phase of
the ELF backend linker. It is called once for each section with
relocs of an object file, just after the symbols for the object
bfd_boolean (*check_directives)
(bfd *abfd, struct bfd_link_info *info);
+ /* The AS_NEEDED_CLEANUP function is called once per --as-needed
+ input file that was not needed by the add_symbols phase of the
+ ELF backend linker. The function must undo any target specific
+ changes in the symbol hash table. */
+ bfd_boolean (*as_needed_cleanup)
+ (bfd *abfd, struct bfd_link_info *info);
+
/* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend
linker for every symbol which is defined by a dynamic object and
referenced by a regular object. This is called after all the
bfd_boolean (*elf_backend_size_dynamic_sections)
(bfd *output_bfd, 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 *output_bfd, struct bfd_link_info *info);
+
/* The RELOCATE_SECTION function is called by the ELF backend linker
to handle the relocations for a section.
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
going to be the section symbol corresponding to the output
section, which means that the addend must be adjusted
- accordingly. */
- bfd_boolean (*elf_backend_relocate_section)
+ accordingly.
+
+ Returns FALSE on error, TRUE on success, 2 if successful and
+ relocations should be written for this section. */
+ int (*elf_backend_relocate_section)
(bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
Elf_Internal_Sym *local_syms, asection **local_sections);
return the number of additional program segments which this BFD
will need. It should return -1 on error. */
int (*elf_backend_additional_program_headers)
- (bfd *);
+ (bfd *, struct bfd_link_info *);
/* This function is called to modify an existing segment map in a
backend specific fashion. */
bfd_boolean (*elf_backend_modify_segment_map)
(bfd *, struct bfd_link_info *);
+ /* This function is called to modify program headers just before
+ they are written. */
+ bfd_boolean (*elf_backend_modify_program_headers)
+ (bfd *, struct bfd_link_info *);
+
+ /* This function is called before section garbage collection to
+ mark entry symbol sections. */
+ void (*gc_keep)
+ (struct bfd_link_info *);
+
+ /* This function is called during section garbage collection to
+ mark sections that define global symbols. */
+ bfd_boolean (*gc_mark_dynamic_ref)
+ (struct elf_link_hash_entry *, void *);
+
/* This function is called during section gc to discover the section a
particular relocation refers to. */
- asection * (*gc_mark_hook)
- (asection *sec, struct bfd_link_info *, Elf_Internal_Rela *,
- struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+ elf_gc_mark_hook_fn gc_mark_hook;
+
+ /* This function, if defined, is called after the first gc marking pass
+ to allow the backend to mark additional sections. */
+ 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 *abfd, struct bfd_link_info *info, asection *o,
- const Elf_Internal_Rela *relocs);
+ (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
/* This function, if defined, is called after all local symbols and
global symbols converted to locals are emitted into the symtab
- section. It allows the backend to emit special global symbols
+ section. It allows the backend to emit special local symbols
not handled in the hash table. */
+ bfd_boolean (*elf_backend_output_arch_local_syms)
+ (bfd *, struct bfd_link_info *, void *,
+ bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *));
+
+ /* This function, if defined, is called after all symbols are emitted
+ into the symtab section. It allows the backend to emit special
+ global symbols not handled in the hash table. */
bfd_boolean (*elf_backend_output_arch_syms)
(bfd *, struct bfd_link_info *, void *,
bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *,
newly created and plt/got refcounts and dynamic indices should not
be copied. */
void (*elf_backend_copy_indirect_symbol)
- (const struct elf_backend_data *, struct elf_link_hash_entry *,
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
/* Modify any information related to dynamic linking such that the
void (*elf_backend_hide_symbol)
(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
+ /* A function to do additional symbol fixup, called by
+ _bfd_elf_fix_symbol_flags. */
+ bfd_boolean (*elf_backend_fixup_symbol)
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+
/* Merge the backend specific symbol attribute. */
void (*elf_backend_merge_symbol_attribute)
(struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean,
bfd_boolean);
+ /* This function, if defined, will return a string containing the
+ name of a target-specific dynamic tag. */
+ char *(*elf_backend_get_target_dtag)
+ (bfd_vma);
+
+ /* Decide whether an undefined symbol is special and can be ignored.
+ This is the case for OPTIONAL symbols on IRIX. */
+ bfd_boolean (*elf_backend_ignore_undef_symbol)
+ (struct elf_link_hash_entry *);
+
/* Emit relocations. Overrides default routine for emitting relocs,
except during a relocatable link, or if all relocs are being emitted. */
bfd_boolean (*elf_backend_emit_relocs)
/* Count relocations. Not called for relocatable links
or if all relocs are being preserved in the output. */
unsigned int (*elf_backend_count_relocs)
- (asection *, Elf_Internal_Rela *);
+ (struct bfd_link_info *, asection *);
/* This function, if defined, is called when an NT_PRSTATUS note is found
- in a core file. */
+ in a core file. */
bfd_boolean (*elf_backend_grok_prstatus)
(bfd *, Elf_Internal_Note *);
/* This function, if defined, is called when an NT_PSINFO or NT_PRPSINFO
- note is found in a core file. */
+ note is found in a core file. */
bfd_boolean (*elf_backend_grok_psinfo)
(bfd *, Elf_Internal_Note *);
- /* Functions to print VMAs. Special code to handle 64 bit ELF files. */
- void (* elf_backend_sprintf_vma)
- (bfd *, char *, bfd_vma);
- void (* elf_backend_fprintf_vma)
- (bfd *, void *, bfd_vma);
+ /* 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, ...);
/* This function returns class of a reloc type. */
enum elf_reloc_type_class (*elf_backend_reloc_type_class)
bfd_boolean (*elf_backend_ignore_discarded_relocs)
(asection *);
+ /* What to do when ld finds relocations against symbols defined in
+ discarded sections. */
+ unsigned int (*action_discarded)
+ (asection *);
+
/* This function returns the width of FDE pointers in bytes, or 0 if
that can't be determined for some reason. The default definition
goes by the bfd's EI_CLASS. */
/* This function, if defined, may write out the given section.
Returns TRUE if it did so and FALSE if the caller should. */
bfd_boolean (*elf_backend_write_section)
- (bfd *, asection *, bfd_byte *);
+ (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
/* The level of IRIX compatibility we're striving for.
MIPS ELF specific function. */
see elf.c. */
bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *);
+ /* Is symbol defined in common section? */
+ bfd_boolean (*common_definition) (Elf_Internal_Sym *);
+
+ /* Return a common section index for section. */
+ unsigned int (*common_section_index) (asection *);
+
+ /* Return a common section for section. */
+ asection *(*common_section) (asection *);
+
+ /* Return TRUE if we can merge 2 definitions. */
+ bfd_boolean (*merge_symbol) (struct bfd_link_info *,
+ struct elf_link_hash_entry **,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *, asection **,
+ bfd_vma *, unsigned int *,
+ bfd_boolean *, bfd_boolean *,
+ bfd_boolean *, bfd_boolean *,
+ bfd_boolean *, bfd_boolean *,
+ bfd_boolean *, bfd_boolean *,
+ bfd *, asection **,
+ bfd_boolean *, bfd_boolean *,
+ bfd_boolean *, bfd_boolean *,
+ bfd *, asection **);
+
+ /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+ bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
+
+ /* Return TRUE if type is a function symbol type. */
+ bfd_boolean (*is_function_type) (unsigned int type);
+
/* Used to handle bad SHF_LINK_ORDER input. */
bfd_error_handler_type link_order_error_handler;
const struct elf_size_info *s;
- /* An array of 27 target specific special section map arrays,
- covering 'a' to 'z', plus other. */
- const struct bfd_elf_special_section **special_sections;
+ /* An array of target specific special sections. */
+ const struct bfd_elf_special_section *special_sections;
/* The size in bytes of the header for the GOT. This includes the
so-called reserved entries on some systems. */
bfd_vma got_header_size;
+ /* The vendor name to use for a processor-standard attributes section. */
+ const char *obj_attrs_vendor;
+
+ /* The section name to use for a processor-standard attributes section. */
+ const char *obj_attrs_section;
+
+ /* Return 1, 2 or 3 to indicate what type of arguments a
+ processor-specific tag takes. */
+ int (*obj_attrs_arg_type) (int);
+
+ /* The section type to use for an attributes section. */
+ unsigned int obj_attrs_section_type;
+
/* 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 default_use_rela_p : 1;
+ /* True if PLT and copy relocations should be RELA by default. */
+ unsigned rela_plts_and_copies_p : 1;
+
/* Set if RELA relocations for a relocatable link can be handled by
generic code. Backends that set this flag need do nothing in the
backend relocate_section routine for relocatable linking. */
unsigned can_refcount : 1;
unsigned want_got_sym : 1;
unsigned want_dynbss : 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. */
+
+ /* 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;
+
+ /* 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
+ for a PT_GNU_STACK segment to be created. */
+ unsigned default_execstack : 1;
};
/* Information stored for each BFD section in an ELF file. This
struct bfd_symbol *id;
} group;
- /* Optional information about section group; NULL if it doesn't
- belongs to any section group. */
+ /* For a member of a group, points to the SHT_GROUP section.
+ NULL for the SHT_GROUP section itself and non-group sections. */
asection *sec_group;
- /* A linked list of sections in the group. Circular when used by
- the linker. */
+ /* A linked list of member sections in the group. Circular when used by
+ the linker. For the SHT_GROUP section, points at first member. */
asection *next_in_group;
+ /* The FDEs associated with this section. The u.fde.next_in_section
+ field acts as a chain pointer. */
+ struct eh_cie_fde *fde_list;
+
/* A pointer used for various section optimizations. */
void *sec_info;
};
#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)
-/* Return TRUE if section has been discarded. */
-#define elf_discarded_section(sec) \
- (!bfd_is_abs_section (sec) \
- && bfd_is_abs_section ((sec)->output_section) \
- && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \
- && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
+#define xvec_get_elf_backend_data(xvec) \
+ ((const struct elf_backend_data *) (xvec)->backend_data)
#define get_elf_backend_data(abfd) \
- ((const struct elf_backend_data *) (abfd)->xvec->backend_data)
+ xvec_get_elf_backend_data ((abfd)->xvec)
/* This struct is used to pass information to routines called via
elf_link_hash_traverse which must return failure. */
bfd_boolean failed;
};
+/* The maximum number of known object attributes for any target. */
+#define NUM_KNOWN_OBJ_ATTRIBUTES 32
+
+/* The value of an object attribute. type & 1 indicates whether there
+ is an integer value; type & 2 indicates whether there is a string
+ value. */
+
+typedef struct obj_attribute
+{
+ int type;
+ unsigned int i;
+ char *s;
+} obj_attribute;
+
+typedef struct obj_attribute_list
+{
+ struct obj_attribute_list *next;
+ int tag;
+ obj_attribute attr;
+} obj_attribute_list;
+
+/* Object attributes may either be defined by the processor ABI, index
+ OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
+ (and possibly also processor-specific), index OBJ_ATTR_GNU. */
+#define OBJ_ATTR_PROC 0
+#define OBJ_ATTR_GNU 1
+#define OBJ_ATTR_FIRST OBJ_ATTR_PROC
+#define OBJ_ATTR_LAST OBJ_ATTR_GNU
+
+/* The following object attribute tags are taken as generic, for all
+ targets and for "gnu" where there is no target standard. */
+enum
+{
+ Tag_NULL = 0,
+ Tag_File = 1,
+ Tag_Section = 2,
+ Tag_Symbol = 3,
+ Tag_compatibility = 32
+};
+
+/* Enum used to identify target specific extensions to the elf_obj_tdata
+ structure. Note the enums deliberately start from 1 so that we can
+ detect an uninitialized field. The generic value is last so that
+ additions to this enum do not need to modify more than one line. */
+enum elf_object_id
+{
+ ALPHA_ELF_TDATA = 1,
+ ARM_ELF_TDATA,
+ HPPA_ELF_TDATA,
+ I386_ELF_TDATA,
+ MIPS_ELF_TDATA,
+ PPC32_ELF_TDATA,
+ PPC64_ELF_TDATA,
+ S390_ELF_TDATA,
+ SH_ELF_TDATA,
+ SPARC_ELF_TDATA,
+ X86_64_ELF_TDATA,
+ XTENSA_ELF_TDATA,
+ GENERIC_ELF_TDATA
+};
+
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
MIPS ELF linker. FIXME: We should figure out some way to only
include this field for a MIPS ELF target. */
asection **local_stubs;
+ asection **local_call_stubs;
/* Used to determine if PT_GNU_EH_FRAME segment header should be
created. */
/* Segment flags for the PT_GNU_STACK segment. */
unsigned int stack_flags;
- /* Should the PT_GNU_RELRO segment be emitted? */
- bfd_boolean relro;
-
/* Symbol version definitions in external objects. */
Elf_Internal_Verdef *verdef;
asection *elf_data_section;
asection *elf_text_section;
+ /* A pointer to the .eh_frame section. */
+ asection *eh_frame_section;
+
/* 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. */
/* Used to determine if the e_flags field has been initialized */
bfd_boolean flags_init;
+
+ /* Symbol buffer. */
+ void *symbuf;
+
+ obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
+ obj_attribute_list *other_obj_attributes[2];
+
+ /* Called at the end of _bfd_elf_write_object_contents if not NULL. */
+ bfd_boolean (*after_write_object_contents) (bfd *);
+ void *after_write_object_contents_info;
+
+ /* NT_GNU_BUILD_ID note type. */
+ bfd_size_type build_id_size;
+ bfd_byte *build_id;
+
+ /* An identifier used to distinguish different target
+ specific extensions to this structure. */
+ enum elf_object_id object_id;
};
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
+
+#define elf_object_id(bfd) (elf_tdata(bfd) -> object_id)
+#define elf_program_header_size(bfd) (elf_tdata(bfd) -> program_header_size)
#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header)
#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
#define elf_numsections(bfd) (elf_tdata(bfd) -> num_elf_sections)
#define elf_shstrtab(bfd) (elf_tdata(bfd) -> 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_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr)
#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section)
#define elf_dynversym(bfd) (elf_tdata(bfd) -> dynversym_section)
#define elf_dynverdef(bfd) (elf_tdata(bfd) -> dynverdef_section)
#define elf_dynverref(bfd) (elf_tdata(bfd) -> dynverref_section)
+#define elf_eh_frame_section(bfd) \
+ (elf_tdata(bfd) -> eh_frame_section)
#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals)
#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals)
#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms)
#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
+#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes)
+#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes)
+#define elf_known_obj_attributes_proc(bfd) \
+ (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_other_obj_attributes_proc(bfd) \
+ (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
\f
extern void _bfd_elf_swap_verdef_in
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
extern void _bfd_elf_swap_versym_out
(bfd *, const Elf_Internal_Versym *, Elf_External_Versym *);
-extern int _bfd_elf_section_from_bfd_section
+extern unsigned int _bfd_elf_section_from_bfd_section
(bfd *, asection *);
extern char *bfd_elf_string_from_elf_section
(bfd *, unsigned, unsigned);
extern void bfd_elf_print_symbol
(bfd *, void *, asymbol *, bfd_print_symbol_type);
-extern void _bfd_elf_sprintf_vma
- (bfd *, char *, bfd_vma);
-extern void _bfd_elf_fprintf_vma
- (bfd *, void *, bfd_vma);
-
extern unsigned int _bfd_elf_eh_frame_address_size
(bfd *, asection *);
extern bfd_byte _bfd_elf_encode_eh_address
extern unsigned long bfd_elf_hash
(const char *);
+extern unsigned long bfd_elf_gnu_hash
+ (const char *);
extern bfd_reloc_status_type bfd_elf_generic_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-extern bfd_boolean bfd_elf_mkobject
+extern bfd_boolean bfd_elf_allocate_object
+ (bfd *, size_t, enum elf_object_id);
+extern bfd_boolean bfd_elf_make_generic_object
(bfd *);
extern bfd_boolean bfd_elf_mkcorefile
(bfd *);
extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
(bfd *);
extern void _bfd_elf_link_hash_copy_indirect
- (const struct elf_backend_data *, struct elf_link_hash_entry *,
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern void _bfd_elf_link_hash_hide_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
+extern bfd_boolean _bfd_elf_link_hash_fixup_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
extern bfd_boolean _bfd_elf_link_hash_table_init
(struct elf_link_hash_table *, bfd *,
struct bfd_hash_entry *(*)
- (struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *),
+ unsigned int);
extern bfd_boolean _bfd_elf_slurp_version_tables
(bfd *, bfd_boolean);
extern bfd_boolean _bfd_elf_merge_sections
(bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_match_sections_by_type
+ (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 *);
+ (bfd *, struct bfd_section *, struct bfd_link_info *);
extern void bfd_elf_set_group_contents
(bfd *, asection *, void *);
extern asection *_bfd_elf_check_kept_section
- (asection *);
+ (asection *, struct bfd_link_info *);
extern void _bfd_elf_link_just_syms
(asection *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_copy_private_header_data
(bfd *, bfd *);
extern bfd_boolean _bfd_elf_copy_private_symbol_data
(bfd *, asymbol *, bfd *, asymbol *);
+#define _bfd_generic_init_private_section_data \
+ _bfd_elf_init_private_section_data
+extern bfd_boolean _bfd_elf_init_private_section_data
+ (bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_copy_private_section_data
(bfd *, asection *, bfd *, asection *);
extern bfd_boolean _bfd_elf_write_object_contents
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_line
+ (bfd *, asymbol **, asymbol *, const char **, unsigned int *);
+#define _bfd_generic_find_line _bfd_elf_find_line
+extern bfd_boolean _bfd_elf_find_inliner_info
+ (bfd *, 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
- (bfd *, bfd_boolean);
+ (bfd *, struct bfd_link_info *);
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);
+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
- (bfd *, const char *);
+ (bfd *, asection *);
/* If the target doesn't have reloc handling written yet: */
extern void _bfd_elf_no_info_to_howto
extern void _bfd_elf_strtab_finalize
(struct elf_strtab_hash *);
+extern void _bfd_elf_begin_eh_frame_parsing
+ (struct bfd_link_info *info);
+extern void _bfd_elf_parse_eh_frame
+ (bfd *, struct bfd_link_info *, asection *, struct elf_reloc_cookie *);
+extern void _bfd_elf_end_eh_frame_parsing
+ (struct bfd_link_info *info);
+
extern bfd_boolean _bfd_elf_discard_section_eh_frame
(bfd *, struct bfd_link_info *, asection *,
bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *);
struct elf_link_hash_entry **, bfd_boolean *,
bfd_boolean *, bfd_boolean *, bfd_boolean *);
+extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *);
+
extern bfd_boolean _bfd_elf_add_default_symbol
(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_create_got_section
(bfd *, struct bfd_link_info *);
+extern struct elf_link_hash_entry *_bfd_elf_define_linkage_sym
+ (bfd *, struct bfd_link_info *, asection *, const char *);
+extern void _bfd_elf_init_1_index_section
+ (bfd *, struct bfd_link_info *);
+extern void _bfd_elf_init_2_index_sections
+ (bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elfcore_make_pseudosection
(bfd *, char *, size_t, ufile_ptr);
extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
(struct elf_link_hash_entry *, void *);
+extern bfd_boolean _bfd_elf_adjust_dynamic_copy
+ (struct elf_link_hash_entry *, asection *);
+
extern bfd_boolean _bfd_elf_link_sec_merge_syms
(struct elf_link_hash_entry *, void *);
extern bfd_boolean _bfd_elf_symbol_refs_local_p
(struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
-extern bfd_boolean bfd_elf_match_symbols_in_sections
- (asection *sec1, asection *sec2);
+extern bfd_reloc_status_type bfd_elf_perform_complex_relocation
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma);
-extern bfd_boolean _bfd_elf_setup_group_pointers
+extern bfd_boolean _bfd_elf_setup_sections
(bfd *);
+extern void _bfd_elf_set_osabi (bfd * , struct bfd_link_info *);
+
extern const bfd_target *bfd_elf32_object_p
(bfd *);
extern const bfd_target *bfd_elf32_core_file_p
extern bfd_boolean bfd_elf32_core_file_matches_executable_p
(bfd *, bfd *);
-extern void bfd_elf32_swap_symbol_in
+extern bfd_boolean bfd_elf32_swap_symbol_in
(bfd *, const void *, const void *, Elf_Internal_Sym *);
extern void bfd_elf32_swap_symbol_out
(bfd *, const Elf_Internal_Sym *, void *, void *);
(bfd *);
extern int bfd_elf32_write_out_phdrs
(bfd *, const Elf_Internal_Phdr *, unsigned int);
+extern bfd_boolean bfd_elf32_checksum_contents
+ (bfd * , void (*) (const void *, size_t, void *), void *);
extern void bfd_elf32_write_relocs
(bfd *, asection *, void *);
extern bfd_boolean bfd_elf32_slurp_reloc_table
extern bfd_boolean bfd_elf64_core_file_matches_executable_p
(bfd *, bfd *);
-extern void bfd_elf64_swap_symbol_in
+extern bfd_boolean bfd_elf64_swap_symbol_in
(bfd *, const void *, const void *, Elf_Internal_Sym *);
extern void bfd_elf64_swap_symbol_out
(bfd *, const Elf_Internal_Sym *, void *, void *);
(bfd *);
extern int bfd_elf64_write_out_phdrs
(bfd *, const Elf_Internal_Phdr *, unsigned int);
+extern bfd_boolean bfd_elf64_checksum_contents
+ (bfd * , void (*) (const void *, size_t, void *), void *);
extern void bfd_elf64_write_relocs
(bfd *, asection *, void *);
extern bfd_boolean bfd_elf64_slurp_reloc_table
(bfd *, asection *, asymbol **, bfd_boolean);
+extern bfd_boolean _bfd_elf_default_relocs_compatible
+ (const bfd_target *, const bfd_target *);
+
+extern bfd_boolean _bfd_elf_relocs_compatible
+ (const bfd_target *, const bfd_target *);
+
extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
(bfd *, struct bfd_link_info *, const char *);
extern bfd_boolean bfd_elf_link_add_symbols
extern int bfd_elf_link_record_local_dynamic_symbol
(struct bfd_link_info *, bfd *, long);
+extern void bfd_elf_link_mark_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+
extern bfd_boolean _bfd_elf_close_and_cleanup
(bfd *);
+extern bfd_boolean _bfd_elf_common_definition
+ (Elf_Internal_Sym *);
+
+extern unsigned int _bfd_elf_common_section_index
+ (asection *);
+
+extern asection *_bfd_elf_common_section
+ (asection *);
+
extern void _bfd_dwarf2_cleanup_debug_info
(bfd *);
extern bfd_boolean bfd_elf_final_link
(bfd *, struct bfd_link_info *);
+extern void _bfd_elf_gc_keep
+ (struct bfd_link_info *info);
+
+extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol
+ (struct elf_link_hash_entry *h, void *inf);
+
extern bfd_boolean bfd_elf_gc_sections
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_gc_record_vtentry
(bfd *, asection *, struct elf_link_hash_entry *, bfd_vma);
+extern asection *_bfd_elf_gc_mark_hook
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
+extern asection *_bfd_elf_gc_mark_rsec
+ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
+ struct elf_reloc_cookie *);
+
+extern bfd_boolean _bfd_elf_gc_mark_reloc
+ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
+ struct elf_reloc_cookie *);
+
+extern bfd_boolean _bfd_elf_gc_mark_fdes
+ (struct bfd_link_info *, asection *, asection *, elf_gc_mark_hook_fn,
+ struct elf_reloc_cookie *);
+
extern bfd_boolean _bfd_elf_gc_mark
- (struct bfd_link_info *, asection *,
- asection * (*) (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
- struct elf_link_hash_entry *, Elf_Internal_Sym *));
+ (struct bfd_link_info *, asection *, 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_reloc_symbol_deleted_p
(bfd_vma, void *);
-extern struct elf_segment_map *
-_bfd_elf_make_dynamic_segment
+extern struct elf_segment_map * _bfd_elf_make_dynamic_segment
(bfd *, asection *);
+extern bfd_boolean _bfd_elf_map_sections_to_segments
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean _bfd_elf_is_function_type (unsigned int);
+
+extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
+ (bfd * abfd, asection * section);
+
/* 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_prxfpreg
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_ppc_vmx
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_ppc_vsx
+ (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);
extern bfd *_bfd_elf32_bfd_from_remote_memory
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, int));
+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_get_obj_attr_int (bfd *, int, int);
+extern void bfd_elf_add_obj_attr_int (bfd *, int, int, unsigned int);
+#define bfd_elf_add_proc_attr_int(BFD, TAG, VALUE) \
+ bfd_elf_add_obj_attr_int ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
+extern void bfd_elf_add_obj_attr_string (bfd *, int, int, const char *);
+#define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \
+ bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
+extern void bfd_elf_add_obj_attr_compat (bfd *, int, unsigned int,
+ const char *);
+#define bfd_elf_add_proc_attr_compat(BFD, INTVAL, STRVAL) \
+ bfd_elf_add_obj_attr_compat ((BFD), OBJ_ATTR_PROC, (INTVAL), (STRVAL))
+
+extern char *_bfd_elf_attr_strdup (bfd *, const char *);
+extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
+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 *);
+
+/* Large common section. */
+extern asection _bfd_elf_large_com_section;
+
/* SH ELF specific routine. */
extern bfd_boolean _sh_elf_set_mach_from_flags
else if (info->unresolved_syms_in_objects == RM_IGNORE \
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \
; \
- else \
+ else if (!info->relocatable) \
{ \
bfd_boolean err; \
err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR \
} \
while (0)
+/* Will a symbol be bound to the the definition within the shared
+ library, if any. */
+#define SYMBOLIC_BIND(INFO, H) \
+ ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))
+
#endif /* _LIBELF_H_ */