/* 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, 2011, 2012, 2013
- Free Software Foundation, Inc.
+ Copyright (C) 1992-2016 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "elf/internal.h"
#include "bfdlink.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* 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.
struct elf_link_hash_entry *parent;
};
+/* ELF symbol version. */
+enum elf_symbol_version
+ {
+ unknown = 0,
+ unversioned,
+ versioned,
+ versioned_hidden
+ };
+
/* ELF linker hash table entries. */
struct elf_link_hash_entry
struct bfd_link_hash_entry root;
/* Symbol index in output file. This is initialized to -1. It is
- set to -2 if the symbol is used by a reloc. */
+ set to -2 if the symbol is used by a reloc. It is set to -3 if
+ this symbol is defined in a discarded section. */
long indx;
/* Symbol index as a dynamic symbol. Initialized to -1, and remains
unsigned int needs_plt : 1;
/* Symbol appears in a non-ELF input file. */
unsigned int non_elf : 1;
- /* Symbol should be marked as hidden in the version information. */
- unsigned int hidden : 1;
+ /* Symbol version information. */
+ ENUM_BITFIELD (elf_symbol_version) versioned : 2;
/* 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. */
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;
/* Symbol is a unique global symbol. */
unsigned int unique_global : 1;
+ /* Symbol is defined by a shared library with non-default visibility
+ in a read/write section. */
+ unsigned int protected_def : 1;
/* String table index in .dynstr if this is a dynamic symbol. */
unsigned long dynstr_index;
_bfd_elf_symbol_refs_local_p (H, INFO, 1)
/* Common symbols that are turned into definitions don't have the
- DEF_REGULAR flag set, so they might appear to be undefined. */
+ DEF_REGULAR flag set, so they might appear to be undefined.
+ Symbols defined in linker scripts also don't have DEF_REGULAR set. */
#define ELF_COMMON_DEF_P(H) \
(!(H)->def_regular \
&& !(H)->def_dynamic \
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. */
+ might belong to a different .eh_frame input section from the FDE.
+
+ May be NULL to signify that the FDE should be discarded. */
struct eh_cie_fde *cie_inf;
struct eh_cie_fde *next_for_section;
} fde;
struct eh_frame_array_ent
{
bfd_vma initial_loc;
+ bfd_size_type range;
bfd_vma fde;
};
struct htab;
-struct eh_frame_hdr_info
+#define DWARF2_EH_HDR 1
+#define COMPACT_EH_HDR 2
+
+/* Endian-neutral code indicating that a function cannot be unwound. */
+#define COMPACT_EH_CANT_UNWIND_OPCODE 0x015d5d01
+
+struct dwarf_eh_frame_hdr_info
{
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;
+ unsigned int fde_count;
/* 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;
+ struct eh_frame_array_ent *array;
+};
+
+struct compact_eh_frame_hdr_info
+{
+ unsigned int allocated_entries;
+ /* eh_frame_entry fragments. */
+ asection **entries;
+};
+
+struct eh_frame_hdr_info
+{
+ asection *hdr_sec;
+ unsigned int array_count;
+ bfd_boolean frame_hdr_is_compact;
+ union
+ {
+ struct dwarf_eh_frame_hdr_info dwarf;
+ struct compact_eh_frame_hdr_info compact;
+ }
+ u;
};
/* Enum used to identify target specific extensions to the elf_obj_tdata
MICROBLAZE_ELF_DATA,
MIPS_ELF_DATA,
MN10300_ELF_DATA,
+ NDS32_ELF_DATA,
+ NIOS2_ELF_DATA,
+ OR1K_ELF_DATA,
PPC32_ELF_DATA,
PPC64_ELF_DATA,
S390_ELF_DATA,
GENERIC_ELF_DATA
};
+struct elf_sym_strtab
+{
+ Elf_Internal_Sym sym;
+ unsigned long dest_index;
+ unsigned long destshndx_index;
+};
+
/* ELF linker hash table. */
struct elf_link_hash_table
union gotplt_union init_got_offset;
union gotplt_union init_plt_offset;
- /* The number of symbols found in the link which must be put into
- the .dynsym section. */
+ /* The number of symbols found in the link which is intended for the
+ mandatory DT_SYMTAB tag (.dynsym section) in .dynamic section. */
bfd_size_type dynsymcount;
/* The string table of dynamic symbols, which becomes the .dynstr
section. */
struct elf_strtab_hash *dynstr;
+ /* The number of symbol strings found in the link which must be put
+ into the .strtab section. */
+ bfd_size_type strtabcount;
+
+ /* The array size of the symbol string table, which becomes the
+ .strtab section. */
+ bfd_size_type strtabsize;
+
+ /* The array of strings, which becomes the .strtab section. */
+ struct elf_sym_strtab *strtab;
+
/* The number of buckets in the hash table in the .hash section.
This is based on the number of dynamic symbols. */
bfd_size_type bucketcount;
asection *iplt;
asection *irelplt;
asection *irelifunc;
+ asection *dynsym;
};
/* Look up an entry in an ELF linker hash table. */
enum elf_reloc_type_class {
reloc_class_normal,
reloc_class_relative,
- reloc_class_plt,
- reloc_class_copy
+ reloc_class_copy,
+ reloc_class_ifunc,
+ reloc_class_plt
};
struct elf_reloc_cookie
struct bfd_elf_special_section
{
const char *prefix;
- int prefix_length;
+ unsigned int prefix_length;
/* 0 means name must match PREFIX exactly.
-1 means name must start with PREFIX followed by an arbitrary string.
-2 means name must match PREFIX exactly or consist of PREFIX followed
by a dot then anything.
> 0 means name must start with the first PREFIX_LENGTH chars of
PREFIX and finish with the last SUFFIX_LENGTH chars of PREFIX. */
- int suffix_length;
- int type;
+ signed int suffix_length;
+ unsigned int type;
bfd_vma attr;
};
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 NOTICE_AS_NEEDED function is called as the linker is about to
+ handle an as-needed lib (ACT = notice_as_needed), and after the
+ linker has decided to keep the lib (ACT = notice_needed) or when
+ the lib is not needed (ACT = notice_not_needed). */
+ bfd_boolean (*notice_as_needed)
+ (bfd *abfd, struct bfd_link_info *info, enum notice_asneeded_action act);
/* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend
linker for every symbol which is defined by a dynamic object and
unsigned int (*elf_backend_count_relocs)
(struct bfd_link_info *, asection *);
+ /* Count additionals relocations. Called for relocatable links if
+ additional relocations needs to be created. */
+ unsigned int (*elf_backend_count_additional_relocs)
+ (asection *);
+
+ /* Say whether to sort relocs output by ld -r and ld --emit-relocs,
+ by r_offset. If NULL, default to true. */
+ bfd_boolean (*sort_relocs_p)
+ (asection *);
+
/* This function, if defined, is called when an NT_PRSTATUS note is found
in a core file. */
bfd_boolean (*elf_backend_grok_prstatus)
/* This function returns class of a reloc type. */
enum elf_reloc_type_class (*elf_backend_reloc_type_class)
- (const Elf_Internal_Rela *);
+ (const struct bfd_link_info *, const asection *, const Elf_Internal_Rela *);
/* This function, if defined, removes information about discarded functions
from other sections which mention them. */
/* This function implements `bfd_elf_bfd_from_remote_memory';
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,
- bfd_size_type len));
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
+ 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. */
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 **);
+ bfd_boolean (*merge_symbol) (struct elf_link_hash_entry *,
+ const Elf_Internal_Sym *, asection **,
+ bfd_boolean, bfd_boolean,
+ bfd *, const asection *);
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec,
bfd_vma *code_off);
+ /* Return the section which RELOC_SEC applies to. */
+ asection *(*get_reloc_section) (asection *reloc_sec);
+
+ /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
+ has a type >= SHT_LOOS. Returns TRUE if the fields were initialised,
+ FALSE otherwise. Can be called multiple times for a given section,
+ until it returns TRUE. Most of the times it is called ISECTION will be
+ set to an input section that might be associated with the output section.
+ The last time that it is called, ISECTION will be set to NULL. */
+ bfd_boolean (*elf_backend_copy_special_section_fields)
+ (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection,
+ Elf_Internal_Shdr *osection);
+
/* Used to handle bad SHF_LINK_ORDER input. */
bfd_error_handler_type link_order_error_handler;
or give an error and return FALSE. */
bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
+ /* Encoding used for compact EH tables. */
+ int (*compact_eh_encoding) (struct bfd_link_info *);
+
+ /* Opcode representing no unwind. */
+ int (*cant_unwind_opcode) (struct bfd_link_info *);
+
/* 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;
+ /* Flag bits to assign to a section of type SHT_STRTAB. */
+ unsigned long elf_strtab_flags;
+
/* This is TRUE if the linker should act like collect and gather
global constructors and destructors by name. This is TRUE for
MIPS ELF because the Irix 5 tools can not handle the .init
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;
+
+ /* True if elf_section_data(sec)->this_hdr.contents is sec->rawsize
+ in length rather than sec->size in length, if sec->rawsize is
+ non-zero and smaller than sec->size. */
+ unsigned caches_rawsize : 1;
+
+ /* Address of protected data defined in the shared library may be
+ external, i.e., due to copy relocation. */
+ unsigned extern_protected_data : 1;
};
/* Information about reloc sections associated with a bfd_elf_section_data
field acts as a chain pointer. */
struct eh_cie_fde *fde_list;
+ /* Link from a text section to its .eh_frame_entry section. */
+ asection *eh_frame_entry;
+
/* A pointer used for various section optimizations. */
void *sec_info;
};
#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 elf_section_eh_frame_entry(sec) (elf_section_data(sec)->eh_frame_entry)
#define xvec_get_elf_backend_data(xvec) \
((const struct elf_backend_data *) (xvec)->backend_data)
typedef struct obj_attribute_list
{
struct obj_attribute_list *next;
- int tag;
+ unsigned int tag;
obj_attribute attr;
} obj_attribute_list;
bfd_byte data[1];
};
+/* tdata information grabbed from an elf core file. */
+struct core_elf_obj_tdata
+{
+ int signal;
+ int pid;
+ int lwpid;
+ char* program;
+ char* command;
+};
+
+/* Extra tdata information held for output ELF BFDs. */
+struct output_elf_obj_tdata
+{
+ struct elf_segment_map *seg_map;
+ struct elf_strtab_hash *strtab_ptr;
+
+ /* STT_SECTION symbols for each section */
+ asymbol **section_syms;
+
+ /* Used to determine if PT_GNU_EH_FRAME segment header should be
+ created. */
+ asection *eh_frame_hdr;
+
+ /* NT_GNU_BUILD_ID note type info. */
+ struct
+ {
+ bfd_boolean (*after_write_object_contents) (bfd *);
+ const char *style;
+ asection *sec;
+ } build_id;
+
+ /* Records the result of `get_program_header_size'. */
+ bfd_size_type program_header_size;
+
+ /* Used when laying out sections. */
+ file_ptr next_file_pos;
+
+ int num_section_syms;
+ unsigned int shstrtab_section, strtab_section;
+
+ /* Segment flags for the PT_GNU_STACK segment. */
+ unsigned int stack_flags;
+
+ /* This is set to TRUE if the object was created by the backend
+ linker. */
+ bfd_boolean linker;
+
+ /* Used to determine if the e_flags field has been initialized */
+ bfd_boolean flags_init;
+};
+
+/* Indicate if the bfd contains symbols that have the STT_GNU_IFUNC
+ symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
+ field in the ELF header structure. */
+enum elf_gnu_symbols
+ {
+ elf_gnu_symbol_none = 0,
+ elf_gnu_symbol_any = 1 << 0,
+ elf_gnu_symbol_ifunc = (elf_gnu_symbol_any | 1 << 1),
+ elf_gnu_symbol_unique = (elf_gnu_symbol_any | 1 << 2),
+ elf_gnu_symbol_all = (elf_gnu_symbol_ifunc | elf_gnu_symbol_unique)
+ };
+
+typedef struct elf_section_list
+{
+ Elf_Internal_Shdr hdr;
+ unsigned int ndx;
+ struct elf_section_list * next;
+} elf_section_list;
+
+
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */
Elf_Internal_Shdr **elf_sect_ptr;
Elf_Internal_Phdr *phdr;
- struct elf_segment_map *segment_map;
- struct elf_strtab_hash *strtab_ptr;
- int num_locals;
- int num_globals;
- unsigned int num_elf_sections; /* elf_sect_ptr size */
- int num_section_syms;
- asymbol **section_syms; /* STT_SECTION symbols for each section */
Elf_Internal_Shdr symtab_hdr;
Elf_Internal_Shdr shstrtab_hdr;
Elf_Internal_Shdr strtab_hdr;
Elf_Internal_Shdr dynversym_hdr;
Elf_Internal_Shdr dynverref_hdr;
Elf_Internal_Shdr dynverdef_hdr;
- Elf_Internal_Shdr symtab_shndx_hdr;
- unsigned int symtab_section, shstrtab_section;
- unsigned int strtab_section, dynsymtab_section;
- unsigned int symtab_shndx_section;
- unsigned int dynversym_section, dynverdef_section, dynverref_section;
- file_ptr next_file_pos;
+ elf_section_list * symtab_shndx_list;
bfd_vma gp; /* The gp value */
unsigned int gp_size; /* The gp size */
-
- /* Information grabbed from an elf core file. */
- int core_signal;
- int core_pid;
- int core_lwpid;
- char* core_program;
- char* core_command;
+ unsigned int num_elf_sections; /* elf_sect_ptr size */
/* A mapping from external symbols to entries in the linker hash
table, used when linking. This is indexed by the symbol index
are used by a dynamic object. */
const char *dt_audit;
- /* Records the result of `get_program_header_size'. */
- bfd_size_type program_header_size;
-
/* Used by find_nearest_line entry point. */
void *line_info;
- /* Used by MIPS ELF find_nearest_line entry point. The structure
- could be included directly in this one, but there's no point to
- wasting the memory just for the infrequently called
- find_nearest_line. */
- struct mips_elf_find_line *find_line_info;
-
/* A place to stash dwarf1 info for this bfd. */
struct dwarf1_debug *dwarf1_find_line_info;
/* A place to stash dwarf2 info for this bfd. */
void *dwarf2_find_line_info;
- /* An array of stub sections indexed by symbol number, used by the
- 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. */
- asection *eh_frame_hdr;
-
- Elf_Internal_Shdr **group_sect_ptr;
- int num_group;
+ /* Stash away info for yet another find line/function variant. */
+ void *elf_find_function_cache;
/* Number of symbol version definitions we are about to emit. */
unsigned int cverdefs;
/* Number of symbol version references we are about to emit. */
unsigned int cverrefs;
- /* Segment flags for the PT_GNU_STACK segment. */
- unsigned int stack_flags;
-
/* Symbol version definitions in external objects. */
Elf_Internal_Verdef *verdef;
/* Symbol version references to external objects. */
Elf_Internal_Verneed *verref;
- /* The Irix 5 support uses two virtual sections, which represent
- text/data symbols defined in dynamic objects. */
- asymbol *elf_data_symbol;
- asymbol *elf_text_symbol;
- 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. */
- enum dynamic_lib_link_class dyn_lib_class;
-
- /* This is set to TRUE if the object was created by the backend
- linker. */
- bfd_boolean linker;
-
- /* Irix 5 often screws up the symbol table, sorting local symbols
- after global symbols. This flag is set if the symbol table in
- this BFD appears to be screwed up. If it is, we ignore the
- sh_info field in the symbol table header, and always read all the
- symbols. */
- bfd_boolean bad_symtab;
-
- /* 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;
-
/* 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 or STB_GNU_UNIQUE binding. Used to set the osabi
- field in the ELF header structure. */
- bfd_boolean has_gnu_symbols;
+ Elf_Internal_Shdr **group_sect_ptr;
+ int num_group;
+
+ unsigned int symtab_section, dynsymtab_section;
+ unsigned int dynversym_section, dynverdef_section, dynverref_section;
/* An identifier used to distinguish different target
specific extensions to this structure. */
enum elf_target_id object_id;
+
+ /* Whether a dyanmic object was specified normally on the linker
+ command line, or was specified when --as-needed was in effect,
+ or was found via a DT_NEEDED entry. */
+ enum dynamic_lib_link_class dyn_lib_class;
+
+ /* Irix 5 often screws up the symbol table, sorting local symbols
+ after global symbols. This flag is set if the symbol table in
+ this BFD appears to be screwed up. If it is, we ignore the
+ sh_info field in the symbol table header, and always read all the
+ symbols. */
+ bfd_boolean bad_symtab;
+
+ enum elf_gnu_symbols has_gnu_symbols;
+
+ /* Information grabbed from an elf core file. */
+ struct core_elf_obj_tdata *core;
+
+ /* More information held for output ELF BFDs. */
+ struct output_elf_obj_tdata *o;
};
#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_program_header_size(bfd) (elf_tdata(bfd) -> o->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_seg_map(bfd) (elf_tdata(bfd) -> o->seg_map)
+#define elf_next_file_pos(bfd) (elf_tdata(bfd) -> o->next_file_pos)
+#define elf_eh_frame_hdr(bfd) (elf_tdata(bfd) -> o->eh_frame_hdr)
+#define elf_linker(bfd) (elf_tdata(bfd) -> o->linker)
+#define elf_stack_flags(bfd) (elf_tdata(bfd) -> o->stack_flags)
+#define elf_shstrtab(bfd) (elf_tdata(bfd) -> o->strtab_ptr)
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
-#define elf_symtab_shndx(bfd) (elf_tdata(bfd) -> symtab_shndx_section)
+#define elf_symtab_shndx_list(bfd) (elf_tdata(bfd) -> symtab_shndx_list)
+#define elf_strtab_sec(bfd) (elf_tdata(bfd) -> o->strtab_section)
+#define elf_shstrtab_sec(bfd) (elf_tdata(bfd) -> o->shstrtab_section)
#define elf_symtab_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr)
#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section)
#define elf_dynversym(bfd) (elf_tdata(bfd) -> dynversym_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_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms)
+#define elf_section_syms(bfd) (elf_tdata(bfd) -> o->section_syms)
+#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> o->num_section_syms)
#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo)
#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus)
#define elf_gp(bfd) (elf_tdata(bfd) -> gp)
#define elf_dt_audit(bfd) (elf_tdata(bfd) -> dt_audit)
#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_flags_init(bfd) (elf_tdata(bfd) -> o->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) \
(bfd *, bfd *);
extern bfd_boolean _bfd_elf_print_private_bfd_data
(bfd *, void *);
+const char * _bfd_elf_get_symbol_version_string
+ (bfd *, asymbol *, bfd_boolean *);
extern void bfd_elf_print_symbol
(bfd *, void *, asymbol *, bfd_print_symbol_type);
(bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
- (const Elf_Internal_Rela *);
+ (const struct bfd_link_info *, const asection *,
+ const Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rela_local_sym
(bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rel_local_sym
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
(bfd *);
+extern void _bfd_elf_link_hash_table_free
+ (bfd *);
extern void _bfd_elf_link_hash_copy_indirect
(struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern bfd_boolean _bfd_elf_set_arch_mach
(bfd *, enum bfd_architecture, unsigned long);
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 *);
+ (bfd *, asymbol **, asection *, 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 *);
+extern asymbol *_bfd_elf_find_function
+ (bfd *, asymbol **, asection *, bfd_vma, const char **, const char **);
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
extern int _bfd_elf_sizeof_headers
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_new_section_hook
(bfd *, asection *);
-extern bfd_boolean _bfd_elf_init_reloc_shdr
- (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
(struct sym_cache *, bfd *, unsigned long);
extern asection *bfd_section_from_elf_index
(bfd *, unsigned int);
-extern struct bfd_strtab_hash *_bfd_elf_stringtab_init
- (void);
extern struct elf_strtab_hash * _bfd_elf_strtab_init
(void);
(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_refs
+extern unsigned int _bfd_elf_strtab_refcount
+ (struct elf_strtab_hash *, bfd_size_type);
+extern void _bfd_elf_strtab_clear_all_refs
+ (struct elf_strtab_hash *tab);
+extern void _bfd_elf_strtab_restore_size
(struct elf_strtab_hash *, bfd_size_type);
-#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
extern void _bfd_elf_strtab_finalize
(struct elf_strtab_hash *);
-extern void _bfd_elf_begin_eh_frame_parsing
- (struct bfd_link_info *info);
+extern bfd_boolean bfd_elf_parse_eh_frame_entries
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_parse_eh_frame_entry
+ (struct bfd_link_info *, asection *, struct elf_reloc_cookie *);
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
+extern bfd_boolean _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_vma);
extern bfd_boolean _bfd_elf_write_section_eh_frame
(bfd *, struct bfd_link_info *, asection *, bfd_byte *);
+bfd_boolean _bfd_elf_write_section_eh_frame_entry
+ (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
+extern bfd_boolean _bfd_elf_fixup_eh_frame_hdr (struct bfd_link_info *);
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_eh_frame_entry_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 *, bfd_boolean *, unsigned int *,
- 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 long _bfd_elf_link_lookup_local_dynindx
(struct bfd_link_info *, bfd *, long);
extern bfd_boolean _bfd_elf_compute_section_file_positions
(bfd *, struct bfd_link_info *);
-extern void _bfd_elf_assign_file_positions_for_relocs
- (bfd *);
extern file_ptr _bfd_elf_assign_file_position_for_section
(Elf_Internal_Shdr *, file_ptr, bfd_boolean);
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_create_got_section
(bfd *, struct bfd_link_info *);
+extern asection *_bfd_elf_section_for_symbol
+ (struct elf_reloc_cookie *, unsigned long, bfd_boolean);
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
struct elf_link_hash_entry **);
extern bfd_boolean _bfd_elf_adjust_dynamic_copy
- (struct elf_link_hash_entry *, asection *);
+ (struct bfd_link_info *, 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);
extern bfd_boolean _bfd_elf_setup_sections
(bfd *);
-extern void _bfd_elf_set_osabi (bfd * , struct bfd_link_info *);
+extern void _bfd_elf_post_process_headers (bfd * , struct bfd_link_info *);
extern const bfd_target *bfd_elf32_object_p
(bfd *);
extern bfd_boolean _bfd_elf_relocs_compatible
(const bfd_target *, const bfd_target *);
+extern bfd_boolean _bfd_elf_notice_as_needed
+ (bfd *, struct bfd_link_info *, enum notice_asneeded_action);
extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
(bfd *, struct bfd_link_info *, const char *);
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_add_dynamic_entry
(struct bfd_link_info *, bfd_vma, bfd_vma);
+extern bfd_boolean _bfd_elf_link_check_relocs
+ (bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_link_record_dynamic_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *);
extern asection *_bfd_elf_gc_mark_rsec
(struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
- struct elf_reloc_cookie *);
+ struct elf_reloc_cookie *, bfd_boolean *);
extern bfd_boolean _bfd_elf_gc_mark_reloc
(struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
extern bfd_boolean bfd_elf_gc_common_final_link
(bfd *, struct bfd_link_info *);
+extern asection *_bfd_elf_is_start_stop
+ (const struct bfd_link_info *, struct elf_link_hash_entry *);
+
extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
(bfd_vma, void *);
extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *,
bfd_vma *);
+extern asection *_bfd_elf_get_reloc_section (asection *);
+
extern int bfd_elf_get_default_section_type (flagword);
extern bfd_boolean bfd_elf_lookup_section_flags
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_s390_system_call
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_tdb
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_vxrs_low
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_vxrs_high
+ (bfd *, char *, int *, const void *, int);
extern char *elfcore_write_arm_vfp
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_aarch_tls
extern char *elfcore_write_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,
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
extern bfd *_bfd_elf64_bfd_from_remote_memory
- (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
extern bfd_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);
+extern int bfd_elf_get_obj_attr_int (bfd *, int, unsigned int);
+extern void bfd_elf_add_obj_attr_int (bfd *, int, unsigned 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 *);
+extern void bfd_elf_add_obj_attr_string (bfd *, int, unsigned 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 *);
+extern void bfd_elf_add_obj_attr_int_string (bfd *, int, unsigned 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 int _bfd_elf_obj_attrs_arg_type (bfd *, int, unsigned 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_create_ifunc_sections
(bfd *, struct bfd_link_info *);
-extern asection * _bfd_elf_create_ifunc_dyn_reloc
- (bfd *, struct bfd_link_info *, asection *sec, asection *sreloc,
- struct elf_dyn_relocs **);
extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
(struct bfd_link_info *, struct elf_link_hash_entry *,
- struct elf_dyn_relocs **, unsigned int, unsigned int);
+ struct elf_dyn_relocs **, bfd_boolean *, unsigned int,
+ unsigned int, unsigned int);
+extern long _bfd_elf_ifunc_get_synthetic_symtab
+ (bfd *, long, asymbol **, long, asymbol **, asymbol **, asection *,
+ bfd_vma *(*) (bfd *, asymbol **, asection *, asection *));
extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
#define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, \
r_symndx, symtab_hdr, sym_hashes, \
h, sec, relocation, \
- unresolved_reloc, warned) \
+ unresolved_reloc, warned, ignored) \
do \
{ \
/* It seems this can happen with erroneous or unsupported \
\
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; \
\
+ if (info->wrap_hash != NULL \
+ && (input_section->flags & SEC_DEBUGGING) != 0) \
+ h = ((struct elf_link_hash_entry *) \
+ unwrap_hash_lookup (info, input_bfd, &h->root)); \
+ \
while (h->root.type == bfd_link_hash_indirect \
|| h->root.type == bfd_link_hash_warning) \
h = (struct elf_link_hash_entry *) h->root.u.i.link; \
\
warned = FALSE; \
+ ignored = FALSE; \
unresolved_reloc = FALSE; \
relocation = 0; \
if (h->root.type == bfd_link_hash_defined \
; \
else if (info->unresolved_syms_in_objects == RM_IGNORE \
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \
- ; \
- else if (!info->relocatable) \
+ ignored = TRUE; \
+ else if (!bfd_link_relocatable (info)) \
{ \
bfd_boolean err; \
err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR \
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); \
- if (!info->callbacks->undefined_symbol (info, \
- h->root.root.string, \
- input_bfd, \
- input_section, \
- rel->r_offset, err)) \
- return FALSE; \
+ (*info->callbacks->undefined_symbol) (info, \
+ h->root.root.string, \
+ input_bfd, \
+ input_section, \
+ rel->r_offset, err); \
warned = TRUE; \
} \
(void) unresolved_reloc; \
(void) warned; \
+ (void) ignored; \
} \
while (0)
_bfd_clear_contents (howto, input_bfd, input_section, \
contents + rel[index].r_offset); \
\
- if (info->relocatable \
+ if (bfd_link_relocatable (info) \
&& (input_section->flags & SEC_DEBUGGING)) \
{ \
/* Only remove relocations in debug sections since other \
rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
\
/* Avoid empty output section. */ \
- if (rel_hdr->sh_size > count * rel_hdr->sh_entsize) \
+ if (rel_hdr->sh_size > rel_hdr->sh_entsize) \
{ \
- rel_hdr->sh_size -= count * rel_hdr->sh_entsize; \
+ rel_hdr->sh_size -= rel_hdr->sh_entsize; \
rel_hdr = _bfd_elf_single_rel_hdr (input_section); \
- rel_hdr->sh_size -= count * rel_hdr->sh_entsize; \
+ rel_hdr->sh_size -= rel_hdr->sh_entsize; \
\
memmove (rel, rel + count, \
(relend - rel - count) * sizeof (*rel)); \
\
- input_section->reloc_count -= count; \
+ input_section->reloc_count--; \
relend -= count; \
rel--; \
continue; \
(!(H)->unique_global \
&& ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)))
+#ifdef __cplusplus
+}
+#endif
#endif /* _LIBELF_H_ */