X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf-bfd.h;h=610aafc0cefdb3a6eec23d9e251f0709019eb791;hb=ba9935866dfbda1e569a1c2003cbc544c6e67927;hp=76be811ec291bf359731d511a9855dadcb1cbc8a;hpb=7325306f39112471924c0f2bf92734473686ae58;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 76be811ec2..610aafc0ce 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1,13 +1,14 @@ /* BFD back-end data structures for ELF files. Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 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, @@ -17,20 +18,24 @@ 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 of a single entry. This is normally only applicable to reloc and - symbol table sections. */ -#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_size / (shdr)->sh_entsize) + symbol table sections. + PR 9934: It is possible to have relocations that do not refer to + symbols, thus it is also possible to have a relocation section in + an object file, but no symbol table. */ +#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_entsize > 0 ? (shdr)->sh_size / (shdr)->sh_entsize : 0) /* If size isn't specified as 64 or 32, NAME macro should fail. */ #ifndef NAME @@ -155,6 +160,8 @@ struct elf_link_hash_entry 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 @@ -259,55 +266,89 @@ struct elf_link_loaded_list }; /* 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]; }; @@ -317,19 +358,22 @@ struct eh_frame_array_ent 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. */ @@ -342,6 +386,10 @@ struct elf_link_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. */ @@ -375,6 +423,12 @@ struct elf_link_hash_table 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; @@ -403,10 +457,6 @@ struct elf_link_hash_table /* 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. */ @@ -439,7 +489,7 @@ struct sym_sec_cache { bfd *abfd; unsigned long indx[LOCAL_SYM_CACHE_SIZE]; - asection *sec[LOCAL_SYM_CACHE_SIZE]; + unsigned int shndx[LOCAL_SYM_CACHE_SIZE]; }; /* Constant information held for an ELF backend. */ @@ -464,9 +514,11 @@ struct elf_size_info { (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 *); @@ -546,7 +598,7 @@ struct bfd_elf_special_section PREFIX and finish with the last SUFFIX_LENGTH chars of PREFIX. */ int suffix_length; int type; - int attr; + bfd_vma attr; }; enum action_discarded @@ -555,6 +607,10 @@ enum action_discarded 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. */ @@ -563,6 +619,9 @@ struct elf_backend_data /* 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; @@ -571,6 +630,9 @@ struct elf_backend_data 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; @@ -683,8 +745,10 @@ struct elf_backend_data const char **name, flagword *flags, asection **sec, bfd_vma *value); /* If this field is not NULL, it is called by the elf_link_output_sym - phase of a link for each symbol which will appear in the object file. */ - bfd_boolean (*elf_backend_link_output_symbol_hook) + phase of a link for each symbol which will appear in the object file. + On error, this function returns 0. 1 is returned when the symbol + should be output, 2 is returned when the symbol should be discarded. */ + int (*elf_backend_link_output_symbol_hook) (struct bfd_link_info *info, const char *, Elf_Internal_Sym *, asection *, struct elf_link_hash_entry *); @@ -704,6 +768,10 @@ struct elf_backend_data 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 @@ -725,6 +793,13 @@ struct elf_backend_data 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 @@ -760,6 +835,11 @@ struct elf_backend_data 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. @@ -787,8 +867,11 @@ struct elf_backend_data 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); @@ -826,30 +909,42 @@ struct elf_backend_data 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 *h, void *inf); + (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 @@ -865,8 +960,16 @@ struct elf_backend_data /* 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 *, @@ -896,6 +999,11 @@ struct elf_backend_data (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) @@ -910,23 +1018,21 @@ struct elf_backend_data /* 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) @@ -974,7 +1080,7 @@ struct elf_backend_data /* 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. */ @@ -1022,6 +1128,12 @@ struct elf_backend_data 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; @@ -1041,6 +1153,31 @@ struct elf_backend_data so-called reserved entries on some systems. */ bfd_vma got_header_size; + /* The size of the GOT entry for the symbol pointed to by H if non-NULL, + otherwise by the local symbol with index SYMNDX in IBFD. */ + bfd_vma (*got_elt_size) (bfd *, struct bfd_link_info *, + struct elf_link_hash_entry *h, + bfd *ibfd, unsigned long symndx); + + /* 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 function determines the order in which any attributes are written. + It must be defined for input in the range 4..NUM_KNOWN_OBJ_ATTRIBUTES-1 + (this range is used in order to make unity easy). The returned value is + the actual tag number to place in the input position. */ + int (*obj_attrs_order) (int); + /* 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 @@ -1070,6 +1207,9 @@ struct elf_backend_data 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. */ @@ -1088,10 +1228,17 @@ struct elf_backend_data 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 @@ -1160,14 +1307,18 @@ struct bfd_elf_section_data 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; }; @@ -1179,56 +1330,82 @@ struct bfd_elf_section_data #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. */ +/* The maximum number of known object attributes for any target. */ +#define NUM_KNOWN_OBJ_ATTRIBUTES 71 -struct elf_info_failed +/* The value of an object attribute. The type indicates whether the attribute + holds and integer, a string, or both. It can also indicate that there can + be no default (i.e. all values must be written to file, even zero). */ + +typedef struct obj_attribute { - bfd_boolean failed; - struct bfd_link_info *info; - struct bfd_elf_version_tree *verdefs; -}; +#define ATTR_TYPE_FLAG_INT_VAL (1 << 0) +#define ATTR_TYPE_FLAG_STR_VAL (1 << 1) +#define ATTR_TYPE_FLAG_NO_DEFAULT (1 << 2) + +#define ATTR_TYPE_HAS_INT_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_INT_VAL) +#define ATTR_TYPE_HAS_STR_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_STR_VAL) +#define ATTR_TYPE_HAS_NO_DEFAULT(TYPE) ((TYPE) & ATTR_TYPE_FLAG_NO_DEFAULT) -/* This structure is used to pass information to - _bfd_elf_link_assign_sym_version. */ + int type; + unsigned int i; + char *s; +} obj_attribute; -struct elf_assign_sym_version_info +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 { - /* Output BFD. */ - bfd *output_bfd; - /* General link information. */ - struct bfd_link_info *info; - /* Version tree. */ - struct bfd_elf_version_tree *verdefs; - /* Whether we had a failure. */ - bfd_boolean failed; + Tag_NULL = 0, + Tag_File = 1, + Tag_Section = 2, + Tag_Symbol = 3, + Tag_compatibility = 32 }; -/* This structure is used to pass information to - _bfd_elf_link_find_version_dependencies. */ - -struct elf_find_verdep_info +/* 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 { - /* Output BFD. */ - bfd *output_bfd; - /* General link information. */ - struct bfd_link_info *info; - /* The number of dependencies. */ - unsigned int vers; - /* Whether we had a failure. */ - bfd_boolean failed; + 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 @@ -1317,6 +1494,7 @@ struct elf_obj_tdata 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. */ @@ -1334,9 +1512,6 @@ struct elf_obj_tdata /* 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; @@ -1350,6 +1525,9 @@ struct elf_obj_tdata 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. */ @@ -1368,19 +1546,48 @@ struct elf_obj_tdata /* 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; + + /* 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; + + /* 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) @@ -1397,6 +1604,12 @@ struct elf_obj_tdata #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]) extern void _bfd_elf_swap_verdef_in (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *); @@ -1419,12 +1632,10 @@ extern void _bfd_elf_swap_versym_in 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 char *bfd_elf_get_str_section - (bfd *, unsigned); 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 *); @@ -1438,11 +1649,6 @@ extern bfd_boolean _bfd_elf_print_private_bfd_data 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 @@ -1462,15 +1668,17 @@ extern bfd_vma _bfd_elf_section_offset 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 Elf_Internal_Shdr *bfd_elf_find_section - (bfd *, char *); extern bfd_boolean _bfd_elf_make_section_from_shdr (bfd *, Elf_Internal_Shdr *, const char *, int); extern bfd_boolean _bfd_elf_make_section_from_phdr @@ -1489,7 +1697,8 @@ extern bfd_boolean _bfd_elf_link_hash_fixup_symbol 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 @@ -1499,11 +1708,11 @@ extern bfd_boolean _bfd_elf_match_sections_by_type 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 @@ -1536,6 +1745,10 @@ extern long _bfd_elf_get_reloc_upper_bound (bfd *, sec_ptr); extern long _bfd_elf_canonicalize_reloc (bfd *, sec_ptr, arelent **, asymbol **); +extern asection * _bfd_elf_get_dynamic_reloc_section + (bfd *, asection *, bfd_boolean); +extern asection * _bfd_elf_make_dynamic_reloc_section + (asection *, bfd *, unsigned int, bfd *, bfd_boolean); extern long _bfd_elf_get_dynamic_reloc_upper_bound (bfd *); extern long _bfd_elf_canonicalize_dynamic_reloc @@ -1561,7 +1774,7 @@ extern bfd_boolean _bfd_elf_find_inliner_info #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 @@ -1611,6 +1824,13 @@ extern bfd_boolean _bfd_elf_strtab_emit 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 *); @@ -1631,19 +1851,7 @@ extern bfd_boolean _bfd_elf_merge_symbol struct elf_link_hash_entry **, bfd_boolean *, bfd_boolean *, bfd_boolean *, bfd_boolean *); -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_boolean *, bfd_boolean); - -extern bfd_boolean _bfd_elf_export_symbol - (struct elf_link_hash_entry *, void *); - -extern bfd_boolean _bfd_elf_link_find_version_dependencies - (struct elf_link_hash_entry *, void *); - -extern bfd_boolean _bfd_elf_link_assign_sym_version - (struct elf_link_hash_entry *, void *); +extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *); extern long _bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *, bfd *, long); @@ -1667,6 +1875,10 @@ 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); @@ -1676,21 +1888,12 @@ extern char *_bfd_elfcore_strndup extern Elf_Internal_Rela *_bfd_elf_link_read_relocs (bfd *, asection *, void *, Elf_Internal_Rela *, bfd_boolean); -extern bfd_boolean _bfd_elf_link_size_reloc_section - (bfd *, Elf_Internal_Shdr *, asection *); - extern bfd_boolean _bfd_elf_link_output_relocs (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, struct elf_link_hash_entry **); -extern bfd_boolean _bfd_elf_fix_symbol_flags - (struct elf_link_hash_entry *, struct elf_info_failed *); - -extern bfd_boolean _bfd_elf_adjust_dynamic_symbol - (struct elf_link_hash_entry *, void *); - -extern bfd_boolean _bfd_elf_link_sec_merge_syms - (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_dynamic_symbol_p (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean); @@ -1698,12 +1901,14 @@ extern bfd_boolean _bfd_elf_dynamic_symbol_p 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_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 @@ -1715,7 +1920,7 @@ extern int bfd_elf32_core_file_failing_signal 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 *); @@ -1741,6 +1946,8 @@ extern bfd_boolean bfd_elf32_write_shdrs_and_ehdr (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 @@ -1757,7 +1964,7 @@ extern int bfd_elf64_core_file_failing_signal 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 *); @@ -1783,11 +1990,19 @@ extern bfd_boolean bfd_elf64_write_shdrs_and_ehdr (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 @@ -1816,6 +2031,10 @@ extern asection *_bfd_elf_common_section 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_reloc_status_type _bfd_elf_rel_vtable_reloc_fn (bfd *, arelent *, struct bfd_symbol *, void *, asection *, bfd *, char **); @@ -1823,6 +2042,9 @@ extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn 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); @@ -1835,10 +2057,24 @@ extern bfd_boolean bfd_elf_gc_record_vtinherit 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 *); @@ -1849,10 +2085,17 @@ extern bfd_boolean bfd_elf_gc_common_final_link 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); @@ -1866,8 +2109,14 @@ extern char *elfcore_write_prfpreg (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, @@ -1876,14 +2125,33 @@ 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)); +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_int_string (bfd *, int, int, unsigned int, + const char *); +#define bfd_elf_add_proc_attr_int_string(BFD, TAG, INTVAL, STRVAL) \ + bfd_elf_add_obj_attr_int_string ((BFD), OBJ_ATTR_PROC, (TAG), \ + (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 *); + +extern bfd_boolean _bfd_elf_create_ifunc_sections + (bfd *, struct bfd_link_info *); + /* Large common section. */ extern asection _bfd_elf_large_com_section; -/* SH ELF specific routine. */ - -extern bfd_boolean _sh_elf_set_mach_from_flags - (bfd *); - /* 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 about initializing any .plt and .got entries in relocate_section. */ @@ -1935,7 +2203,7 @@ 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 \ @@ -1951,4 +2219,9 @@ extern bfd_boolean _sh_elf_set_mach_from_flags } \ 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_ */