Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Functions | Variables
elf.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "libiberty.h"

Go to the source code of this file.

Classes

union  elf_internal_group
struct  elf_symbuf_symbol
struct  elf_symbuf_head
struct  elf_symbol
union  elf_symbol.u

Defines

#define _SYSCALL32
#define ARCH_SIZE   0
#define IS_VALID_GROUP_SECTION_HEADER(shdr)
#define TOEND(x)   (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
#define SEGMENT_END(segment, start)
#define SECTION_SIZE(section, segment)
#define IS_CONTAINED_BY_VMA(section, segment)
#define IS_CONTAINED_BY_LMA(section, segment, base)
#define IS_COREFILE_NOTE(p, s)
#define IS_SOLARIS_PT_INTERP(p, s)
#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed)
#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)
#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)   (seg1->field >= SEGMENT_END (seg2, seg2->field))
#define SEGMENT_OVERLAPS(seg1, seg2)
#define MAP_ONESYMTAB   (SHN_HIOS + 1)
#define MAP_DYNSYMTAB   (SHN_HIOS + 2)
#define MAP_STRTAB   (SHN_HIOS + 3)
#define MAP_SHSTRTAB   (SHN_HIOS + 4)
#define MAP_SYM_SHNDX   (SHN_HIOS + 5)
#define BFD_QNT_CORE_INFO   7
#define BFD_QNT_CORE_STATUS   8
#define BFD_QNT_CORE_GREG   9
#define BFD_QNT_CORE_FPREG   10

Typedefs

typedef union elf_internal_group Elf_Internal_Group

Functions

static int elf_sort_sections (const void *, const void *)
static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *)
static bfd_boolean prep_headers (bfd *)
static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int)
static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type)
void _bfd_elf_swap_verdef_in (bfd *abfd, const Elf_External_Verdef *src, Elf_Internal_Verdef *dst)
void _bfd_elf_swap_verdef_out (bfd *abfd, const Elf_Internal_Verdef *src, Elf_External_Verdef *dst)
void _bfd_elf_swap_verdaux_in (bfd *abfd, const Elf_External_Verdaux *src, Elf_Internal_Verdaux *dst)
void _bfd_elf_swap_verdaux_out (bfd *abfd, const Elf_Internal_Verdaux *src, Elf_External_Verdaux *dst)
void _bfd_elf_swap_verneed_in (bfd *abfd, const Elf_External_Verneed *src, Elf_Internal_Verneed *dst)
void _bfd_elf_swap_verneed_out (bfd *abfd, const Elf_Internal_Verneed *src, Elf_External_Verneed *dst)
void _bfd_elf_swap_vernaux_in (bfd *abfd, const Elf_External_Vernaux *src, Elf_Internal_Vernaux *dst)
void _bfd_elf_swap_vernaux_out (bfd *abfd, const Elf_Internal_Vernaux *src, Elf_External_Vernaux *dst)
void _bfd_elf_swap_versym_in (bfd *abfd, const Elf_External_Versym *src, Elf_Internal_Versym *dst)
void _bfd_elf_swap_versym_out (bfd *abfd, const Elf_Internal_Versym *src, Elf_External_Versym *dst)
unsigned long bfd_elf_hash (const char *namearg)
unsigned long bfd_elf_gnu_hash (const char *namearg)
bfd_boolean bfd_elf_mkobject (bfd *abfd)
bfd_boolean bfd_elf_mkcorefile (bfd *abfd)
char * bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
char * bfd_elf_string_from_elf_section (bfd *abfd, unsigned int shindex, unsigned int strindex)
Elf_Internal_Sym * bfd_elf_get_elf_syms (bfd *ibfd, Elf_Internal_Shdr *symtab_hdr, size_t symcount, size_t symoffset, Elf_Internal_Sym *intsym_buf, void *extsym_buf, Elf_External_Sym_Shndx *extshndx_buf)
const char * bfd_elf_sym_name (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, Elf_Internal_Sym *isym, asection *sym_sec)
static const char * group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
static bfd_boolean setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
bfd_boolean _bfd_elf_setup_sections (bfd *abfd)
bfd_boolean bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
bfd_boolean _bfd_elf_make_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, const char *name, int shindex)
struct elf_internal_shdrbfd_elf_find_section (bfd *abfd, char *name)
bfd_reloc_status_type bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, asymbol *symbol, void *data ATTRIBUTE_UNUSED, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
static void merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
bfd_boolean _bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
void _bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
bfd_boolean _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
static const char * get_segment_type (unsigned int p_type)
bfd_boolean _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
void bfd_elf_print_symbol (bfd *abfd, void *filep, asymbol *symbol, bfd_print_symbol_type how)
struct bfd_hash_entry_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string)
void _bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info, struct elf_link_hash_entry *dir, struct elf_link_hash_entry *ind)
void _bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h, bfd_boolean force_local)
bfd_boolean _bfd_elf_link_hash_table_init (struct elf_link_hash_table *table, bfd *abfd, struct bfd_hash_entry *(*newfunc)(struct bfd_hash_entry *, struct bfd_hash_table *, const char *), unsigned int entsize)
struct bfd_link_hash_table_bfd_elf_link_hash_table_create (bfd *abfd)
void bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
int bfd_elf_get_dyn_lib_class (bfd *abfd)
void bfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class)
struct bfd_link_needed_listbfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
struct bfd_link_needed_listbfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
const char * bfd_elf_get_dt_soname (bfd *abfd)
bfd_boolean bfd_elf_get_bfd_needed_list (bfd *abfd, struct bfd_link_needed_list **pneeded)
struct bfd_strtab_hash_bfd_elf_stringtab_init (void)
bfd_boolean bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
asectionbfd_section_from_r_symndx (bfd *abfd, struct sym_sec_cache *cache, asection *sec, unsigned long r_symndx)
asectionbfd_section_from_elf_index (bfd *abfd, unsigned int index)
struct bfd_elf_special_section_bfd_elf_get_special_section (const char *name, const struct bfd_elf_special_section *spec, unsigned int rela)
struct bfd_elf_special_section_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
bfd_boolean _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
bfd_boolean _bfd_elf_make_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index, const char *typename)
bfd_boolean bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index)
bfd_boolean _bfd_elf_init_reloc_shdr (bfd *abfd, Elf_Internal_Shdr *rel_hdr, asection *asect, bfd_boolean use_rela_p)
static void elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
void bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
static bfd_boolean assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
static bfd_boolean sym_is_global (bfd *abfd, asymbol *sym)
static bfd_boolean ignore_section_sym (bfd *abfd, asymbol *sym)
static bfd_boolean elf_map_symbols (bfd *abfd)
static file_ptr align_file_position (file_ptr off, int align)
file_ptr _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, file_ptr offset, bfd_boolean align)
bfd_boolean _bfd_elf_compute_section_file_positions (bfd *abfd, struct bfd_link_info *link_info)
static bfd_size_type get_program_header_size (bfd *abfd, struct bfd_link_info *info)
static struct elf_segment_mapmake_mapping (bfd *abfd, asection **sections, unsigned int from, unsigned int to, bfd_boolean phdr)
struct elf_segment_map_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
static bfd_boolean elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
bfd_boolean _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
static file_ptr vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
static bfd_boolean assign_file_positions_for_load_sections (bfd *abfd, struct bfd_link_info *link_info)
static bfd_boolean assign_file_positions_for_non_load_sections (bfd *abfd, struct bfd_link_info *link_info)
void _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
bfd_boolean _bfd_elf_write_object_contents (bfd *abfd)
bfd_boolean _bfd_elf_write_corefile_contents (bfd *abfd)
int _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
int _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
static bfd_boolean rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
static bfd_boolean copy_elf_program_header (bfd *ibfd, bfd *obfd)
static bfd_boolean copy_private_bfd_data (bfd *ibfd, bfd *obfd)
bfd_boolean _bfd_elf_init_private_section_data (bfd *ibfd, asection *isec, bfd *obfd, asection *osec, struct bfd_link_info *link_info)
bfd_boolean _bfd_elf_copy_private_section_data (bfd *ibfd, asection *isec, bfd *obfd, asection *osec)
bfd_boolean _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
bfd_boolean _bfd_elf_copy_private_symbol_data (bfd *ibfd, asymbol *isymarg, bfd *obfd, asymbol *osymarg)
long _bfd_elf_get_symtab_upper_bound (bfd *abfd)
long _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
long _bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr asect)
long _bfd_elf_canonicalize_reloc (bfd *abfd, sec_ptr section, arelent **relptr, asymbol **symbols)
long _bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
long _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, asymbol **allocation)
long _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
long _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage, asymbol **syms)
bfd_boolean _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
asymbol_bfd_elf_make_empty_symbol (bfd *abfd)
void _bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol, symbol_info *ret)
bfd_boolean _bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
alent_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol ATTRIBUTE_UNUSED)
bfd_boolean _bfd_elf_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long machine)
static bfd_boolean elf_find_function (bfd *abfd ATTRIBUTE_UNUSED, asection *section, asymbol **symbols, bfd_vma offset, const char **filename_ptr, const char **functionname_ptr)
bfd_boolean _bfd_elf_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset, const char **filename_ptr, const char **functionname_ptr, unsigned int *line_ptr)
bfd_boolean _bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol, const char **filename_ptr, unsigned int *line_ptr)
bfd_boolean _bfd_elf_find_inliner_info (bfd *abfd, const char **filename_ptr, const char **functionname_ptr, unsigned int *line_ptr)
int _bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
bfd_boolean _bfd_elf_set_section_contents (bfd *abfd, sec_ptr section, const void *location, file_ptr offset, bfd_size_type count)
void _bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr ATTRIBUTE_UNUSED, Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
bfd_boolean _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
bfd_boolean _bfd_elf_close_and_cleanup (bfd *abfd)
bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED, struct bfd_symbol *symbol ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED, bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
static int elfcore_make_pid (bfd *abfd)
static bfd_boolean elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
bfd_boolean _bfd_elfcore_make_pseudosection (bfd *abfd, char *name, size_t size, ufile_ptr filepos)
static bfd_boolean elfcore_make_note_pseudosection (bfd *abfd, char *name, Elf_Internal_Note *note)
static bfd_boolean elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
static bfd_boolean elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
char * _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
static bfd_boolean elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
static bfd_boolean elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
static bfd_boolean elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
static bfd_boolean elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
static bfd_boolean elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
static bfd_boolean elfcore_grok_nto_regs (bfd *abfd, Elf_Internal_Note *note, long tid, char *base)
static bfd_boolean elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
char * elfcore_write_note (bfd *abfd, char *buf, int *bufsiz, const char *name, int type, const void *input, int size)
char * elfcore_write_prfpreg (bfd *abfd, char *buf, int *bufsiz, const void *fpregs, int size)
char * elfcore_write_prxfpreg (bfd *abfd, char *buf, int *bufsiz, const void *xfpregs, int size)
long bfd_get_elf_phdr_upper_bound (bfd *abfd)
int bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
void _bfd_elf_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
void _bfd_elf_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
enum elf_reloc_type_class _bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
bfd_vma _bfd_elf_rela_local_sym (bfd *abfd, Elf_Internal_Sym *sym, asection **psec, Elf_Internal_Rela *rel)
bfd_vma _bfd_elf_rel_local_sym (bfd *abfd, Elf_Internal_Sym *sym, asection **psec, bfd_vma addend)
bfd_vma _bfd_elf_section_offset (bfd *abfd, struct bfd_link_info *info, asection *sec, bfd_vma offset)
bfdbfd_elf_bfd_from_remote_memory (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, int(*target_read_memory)(bfd_vma, bfd_byte *, int))
long _bfd_elf_get_synthetic_symtab (bfd *abfd, long symcount ATTRIBUTE_UNUSED, asymbol **syms ATTRIBUTE_UNUSED, long dynsymcount, asymbol **dynsyms, asymbol **ret)
static int elf_sort_elf_symbol (const void *arg1, const void *arg2)
static int elf_sym_name_compare (const void *arg1, const void *arg2)
static struct elf_symbuf_headelf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
bfd_boolean bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, struct bfd_link_info *info)
bfd_boolean _bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec, bfd *bbfd, const asection *bsec)
void _bfd_elf_set_osabi (bfd *abfd, struct bfd_link_info *link_info ATTRIBUTE_UNUSED)

Variables

const char *const bfd_elf_section_type_names []
static struct bfd_elf_special_section []
static struct
bfd_elf_special_section
special_sections []
asection _bfd_elf_large_com_section

Class Documentation

union elf_internal_group

Definition at line 455 of file elf.c.

Collaboration diagram for elf_internal_group:
Class Members
unsigned int flags
Elf_Internal_Shdr * shdr
struct elf_symbuf_symbol

Definition at line 8801 of file elf.c.

Class Members
unsigned char st_info
unsigned long st_name
unsigned char st_other
struct elf_symbuf_head

Definition at line 8808 of file elf.c.

Collaboration diagram for elf_symbuf_head:
Class Members
bfd_size_type count
struct elf_symbuf_symbol * ssym
unsigned int st_shndx
struct elf_symbol

Definition at line 8815 of file elf.c.

Class Members
const char * name
union elf_symbol u
union elf_symbol.u

Definition at line 8817 of file elf.c.

Class Members
Elf_Internal_Sym * isym
struct elf_symbuf_symbol * ssym

Define Documentation

#define _SYSCALL32

Definition at line 35 of file elf.c.

#define ARCH_SIZE   0

Definition at line 40 of file elf.c.

#define BFD_QNT_CORE_FPREG   10

Definition at line 8154 of file elf.c.

#define BFD_QNT_CORE_GREG   9

Definition at line 8153 of file elf.c.

#define BFD_QNT_CORE_INFO   7

Definition at line 8151 of file elf.c.

#define BFD_QNT_CORE_STATUS   8

Definition at line 8152 of file elf.c.

#define INCLUDE_SECTION_IN_SEGMENT (   section,
  segment,
  bed 
)
Value:
(IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)           \
   && section->output_section != NULL)
#define IS_CONTAINED_BY_LMA (   section,
  segment,
  base 
)
Value:
(section->lma >= base                                                 \
   && (section->lma + SECTION_SIZE (section, segment)                 \
       <= SEGMENT_END (segment, base)))
#define IS_CONTAINED_BY_VMA (   section,
  segment 
)
Value:
(section->vma >= segment->p_vaddr                              \
   && (section->vma + SECTION_SIZE (section, segment)                 \
       <= (SEGMENT_END (segment, segment->p_vaddr))))
#define IS_COREFILE_NOTE (   p,
  s 
)
Value:
(p->p_type == PT_NOTE                                                 \
   && bfd_get_format (ibfd) == bfd_core                               \
   && s->vma == 0 && s->lma == 0                               \
   && (bfd_vma) s->filepos >= p->p_offset                      \
   && ((bfd_vma) s->filepos + s->size                                 \
       <= p->p_offset + p->p_filesz))
#define IS_SECTION_IN_INPUT_SEGMENT (   section,
  segment,
  bed 
)
Value:
((((segment->p_paddr                                           \
      ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)      \
      : IS_CONTAINED_BY_VMA (section, segment))                       \
     && (section->flags & SEC_ALLOC) != 0)                            \
    || IS_COREFILE_NOTE (segment, section))                           \
   && segment->p_type != PT_GNU_STACK                                 \
   && (segment->p_type != PT_TLS                               \
       || (section->flags & SEC_THREAD_LOCAL))                        \
   && (segment->p_type == PT_LOAD                              \
       || segment->p_type == PT_TLS                                   \
       || (section->flags & SEC_THREAD_LOCAL) == 0)                   \
   && (segment->p_type != PT_DYNAMIC                                  \
       || SECTION_SIZE (section, segment) > 0                         \
       || (segment->p_paddr                                    \
           ? segment->p_paddr != section->lma                         \
           : segment->p_vaddr != section->vma)                        \
       || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic")  \
           == 0))                                              \
   && ! section->segment_mark)
#define IS_SOLARIS_PT_INTERP (   p,
  s 
)
Value:
(p->p_vaddr == 0                                               \
   && p->p_paddr == 0                                                 \
   && p->p_memsz == 0                                                 \
   && p->p_filesz > 0                                                 \
   && (s->flags & SEC_HAS_CONTENTS) != 0                       \
   && s->size > 0                                              \
   && (bfd_vma) s->filepos >= p->p_offset                      \
   && ((bfd_vma) s->filepos + s->size                                 \
       <= p->p_offset + p->p_filesz))
#define IS_VALID_GROUP_SECTION_HEADER (   shdr)
Value:
(   (shdr)->sh_type == SHT_GROUP          \
        && (shdr)->sh_size >= (2 * GRP_ENTRY_SIZE)      \
        && (shdr)->sh_entsize == GRP_ENTRY_SIZE  \
        && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
#define MAP_DYNSYMTAB   (SHN_HIOS + 2)

Definition at line 6168 of file elf.c.

#define MAP_ONESYMTAB   (SHN_HIOS + 1)

Definition at line 6167 of file elf.c.

#define MAP_SHSTRTAB   (SHN_HIOS + 4)

Definition at line 6170 of file elf.c.

#define MAP_STRTAB   (SHN_HIOS + 3)

Definition at line 6169 of file elf.c.

#define MAP_SYM_SHNDX   (SHN_HIOS + 5)

Definition at line 6171 of file elf.c.

#define SECTION_SIZE (   section,
  segment 
)
Value:
(((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL))            \
    != SEC_THREAD_LOCAL || segment->p_type == PT_TLS)                 \
   ? section->size : 0)
#define SEGMENT_AFTER_SEGMENT (   seg1,
  seg2,
  field 
)    (seg1->field >= SEGMENT_END (seg2, seg2->field))
#define SEGMENT_END (   segment,
  start 
)
Value:
(start + (segment->p_memsz > segment->p_filesz                 \
           ? segment->p_memsz : segment->p_filesz))
#define SEGMENT_OVERLAPS (   seg1,
  seg2 
)
Value:
(   !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr)                     \
        || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr))               \
   && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr)                   \
        || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
#define TOEND (   x)    (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)

Typedef Documentation


Function Documentation

Definition at line 3495 of file elf.c.

{
  if (align)
    {
      unsigned int al;

      al = i_shdrp->sh_addralign;
      if (al > 1)
       offset = BFD_ALIGN (offset, al);
    }
  i_shdrp->sh_offset = offset;
  if (i_shdrp->bfd_section != NULL)
    i_shdrp->bfd_section->filepos = offset;
  if (i_shdrp->sh_type != SHT_NOBITS)
    offset += i_shdrp->sh_size;
  return offset;
}

Here is the caller graph for this function:

Definition at line 5029 of file elf.c.

{
  file_ptr off;
  unsigned int i, num_sec;
  Elf_Internal_Shdr **shdrpp;

  off = elf_tdata (abfd)->next_file_pos;

  num_sec = elf_numsections (abfd);
  for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
    {
      Elf_Internal_Shdr *shdrp;

      shdrp = *shdrpp;
      if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
         && shdrp->sh_offset == -1)
       off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
    }

  elf_tdata (abfd)->next_file_pos = off;
}

Here is the call graph for this function:

Here is the caller graph for this function:

long _bfd_elf_canonicalize_dynamic_reloc ( bfd abfd,
arelent **  storage,
asymbol **  syms 
)

Definition at line 6635 of file elf.c.

{
  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
  asection *s;
  long ret;

  if (elf_dynsymtab (abfd) == 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  ret = 0;
  for (s = abfd->sections; s != NULL; s = s->next)
    {
      if ((s->flags & SEC_LOAD) != 0
         && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
         && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
             || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
       {
         arelent *p;
         long count, i;

         if (! (*slurp_relocs) (abfd, s, syms, TRUE))
           return -1;
         count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
         p = s->relocation;
         for (i = 0; i < count; i++)
           *storage++ = p++;
         ret += count;
       }
    }

  *storage = NULL;

  return ret;
}

Here is the call graph for this function:

long _bfd_elf_canonicalize_dynamic_symtab ( bfd abfd,
asymbol **  allocation 
)

Definition at line 6586 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);

  if (symcount >= 0)
    bfd_get_dynamic_symcount (abfd) = symcount;
  return symcount;
}
long _bfd_elf_canonicalize_reloc ( bfd abfd,
sec_ptr  section,
arelent **  relptr,
asymbol **  symbols 
)

Definition at line 6553 of file elf.c.

{
  arelent *tblptr;
  unsigned int i;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
    return -1;

  tblptr = section->relocation;
  for (i = 0; i < section->reloc_count; i++)
    *relptr++ = tblptr++;

  *relptr = NULL;

  return section->reloc_count;
}
long _bfd_elf_canonicalize_symtab ( bfd abfd,
asymbol **  allocation 
)

Definition at line 6575 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);

  if (symcount >= 0)
    bfd_get_symcount (abfd) = symcount;
  return symcount;
}

Definition at line 7388 of file elf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3520 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bfd_boolean failed;
  struct bfd_strtab_hash *strtab = NULL;
  Elf_Internal_Shdr *shstrtab_hdr;

  if (abfd->output_has_begun)
    return TRUE;

  /* Do any elf backend specific processing first.  */
  if (bed->elf_backend_begin_write_processing)
    (*bed->elf_backend_begin_write_processing) (abfd, link_info);

  if (! prep_headers (abfd))
    return FALSE;

  /* Post process the headers if necessary.  */
  if (bed->elf_backend_post_process_headers)
    (*bed->elf_backend_post_process_headers) (abfd, link_info);

  failed = FALSE;
  bfd_map_over_sections (abfd, elf_fake_sections, &failed);
  if (failed)
    return FALSE;

  if (!assign_section_numbers (abfd, link_info))
    return FALSE;

  /* The backend linker builds symbol table information itself.  */
  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
    {
      /* Non-zero if doing a relocatable link.  */
      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));

      if (! swap_out_syms (abfd, &strtab, relocatable_p))
       return FALSE;
    }

  if (link_info == NULL)
    {
      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
      if (failed)
       return FALSE;
    }

  shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
  /* sh_name was set in prep_headers.  */
  shstrtab_hdr->sh_type = SHT_STRTAB;
  shstrtab_hdr->sh_flags = 0;
  shstrtab_hdr->sh_addr = 0;
  shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
  shstrtab_hdr->sh_entsize = 0;
  shstrtab_hdr->sh_link = 0;
  shstrtab_hdr->sh_info = 0;
  /* sh_offset is set in assign_file_positions_except_relocs.  */
  shstrtab_hdr->sh_addralign = 1;

  if (!assign_file_positions_except_relocs (abfd, link_info))
    return FALSE;

  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
    {
      file_ptr off;
      Elf_Internal_Shdr *hdr;

      off = elf_tdata (abfd)->next_file_pos;

      hdr = &elf_tdata (abfd)->symtab_hdr;
      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);

      hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
      if (hdr->sh_size != 0)
       off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);

      hdr = &elf_tdata (abfd)->strtab_hdr;
      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);

      elf_tdata (abfd)->next_file_pos = off;

      /* Now that we know where the .strtab section goes, write it
         out.  */
      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
         || ! _bfd_stringtab_emit (abfd, strtab))
       return FALSE;
      _bfd_stringtab_free (strtab);
    }

  abfd->output_has_begun = TRUE;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1098 of file elf.c.

{
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  BFD_ASSERT (!elf_flags_init (obfd)
             || (elf_elfheader (obfd)->e_flags
                == elf_elfheader (ibfd)->e_flags));

  elf_gp (obfd) = elf_gp (ibfd);
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
  elf_flags_init (obfd) = TRUE;
  return TRUE;
}

Here is the caller graph for this function:

Definition at line 6118 of file elf.c.

{
  asection *isec;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  /* Copy over private BFD data if it has not already been copied.
     This must be done here, rather than in the copy_private_bfd_data
     entry point, because the latter is called after the section
     contents have been set, which means that the program headers have
     already been worked out.  */
  if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL)
    {
      if (! copy_private_bfd_data (ibfd, obfd))
       return FALSE;
    }

  /* _bfd_elf_copy_private_section_data copied over the SHF_GROUP flag
     but this might be wrong if we deleted the group section.  */
  for (isec = ibfd->sections; isec != NULL; isec = isec->next)
    if (elf_section_type (isec) == SHT_GROUP
       && isec->output_section == NULL)
      {
       asection *first = elf_next_in_group (isec);
       asection *s = first;
       while (s != NULL)
         {
           if (s->output_section != NULL)
             {
              elf_section_flags (s->output_section) &= ~SHF_GROUP;
              elf_group_name (s->output_section) = NULL;
             }
           s = elf_next_in_group (s);
           if (s == first)
             break;
         }
      }

  return TRUE;
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_copy_private_section_data ( bfd ibfd,
asection isec,
bfd obfd,
asection osec 
)

Definition at line 6089 of file elf.c.

{
  Elf_Internal_Shdr *ihdr, *ohdr;

  if (ibfd->xvec->flavour != bfd_target_elf_flavour
      || obfd->xvec->flavour != bfd_target_elf_flavour)
    return TRUE;

  ihdr = &elf_section_data (isec)->this_hdr;
  ohdr = &elf_section_data (osec)->this_hdr;

  ohdr->sh_entsize = ihdr->sh_entsize;

  if (ihdr->sh_type == SHT_SYMTAB
      || ihdr->sh_type == SHT_DYNSYM
      || ihdr->sh_type == SHT_GNU_verneed
      || ihdr->sh_type == SHT_GNU_verdef)
    ohdr->sh_info = ihdr->sh_info;

  return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
                                        NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_elf_copy_private_symbol_data ( bfd ibfd,
asymbol isymarg,
bfd obfd,
asymbol osymarg 
)

Definition at line 6174 of file elf.c.

{
  elf_symbol_type *isym, *osym;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  isym = elf_symbol_from (ibfd, isymarg);
  osym = elf_symbol_from (obfd, osymarg);

  if (isym != NULL
      && osym != NULL
      && bfd_is_abs_section (isym->symbol.section))
    {
      unsigned int shndx;

      shndx = isym->internal_elf_sym.st_shndx;
      if (shndx == elf_onesymtab (ibfd))
       shndx = MAP_ONESYMTAB;
      else if (shndx == elf_dynsymtab (ibfd))
       shndx = MAP_DYNSYMTAB;
      else if (shndx == elf_tdata (ibfd)->strtab_section)
       shndx = MAP_STRTAB;
      else if (shndx == elf_tdata (ibfd)->shstrtab_section)
       shndx = MAP_SHSTRTAB;
      else if (shndx == elf_tdata (ibfd)->symtab_shndx_section)
       shndx = MAP_SYM_SHNDX;
      osym->internal_elf_sym.st_shndx = shndx;
    }

  return TRUE;
}
bfd_boolean _bfd_elf_find_inliner_info ( bfd abfd,
const char **  filename_ptr,
const char **  functionname_ptr,
unsigned int line_ptr 
)

Definition at line 7219 of file elf.c.

{
  bfd_boolean found;
  found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
                                    functionname_ptr, line_ptr,
                                    & elf_tdata (abfd)->dwarf2_find_line_info);
  return found;
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_find_line ( bfd abfd,
asymbol **  symbols,
asymbol symbol,
const char **  filename_ptr,
unsigned int line_ptr 
)

Definition at line 7204 of file elf.c.

{
  return _bfd_dwarf2_find_line (abfd, symbols, symbol,
                            filename_ptr, line_ptr, 0,
                            &elf_tdata (abfd)->dwarf2_find_line_info);
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_find_nearest_line ( bfd abfd,
asection section,
asymbol **  symbols,
bfd_vma  offset,
const char **  filename_ptr,
const char **  functionname_ptr,
unsigned int line_ptr 
)

Definition at line 7147 of file elf.c.

{
  bfd_boolean found;

  if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
                                 filename_ptr, functionname_ptr,
                                 line_ptr))
    {
      if (!*functionname_ptr)
       elf_find_function (abfd, section, symbols, offset,
                        *filename_ptr ? NULL : filename_ptr,
                        functionname_ptr);

      return TRUE;
    }

  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
                                 filename_ptr, functionname_ptr,
                                 line_ptr, 0,
                                 &elf_tdata (abfd)->dwarf2_find_line_info))
    {
      if (!*functionname_ptr)
       elf_find_function (abfd, section, symbols, offset,
                        *filename_ptr ? NULL : filename_ptr,
                        functionname_ptr);

      return TRUE;
    }

  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
                                        &found, filename_ptr,
                                        functionname_ptr, line_ptr,
                                        &elf_tdata (abfd)->line_info))
    return FALSE;
  if (found && (*functionname_ptr || *line_ptr))
    return TRUE;

  if (symbols == NULL)
    return FALSE;

  if (! elf_find_function (abfd, section, symbols, offset,
                        filename_ptr, functionname_ptr))
    return FALSE;

  *line_ptr = 0;
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _bfd_elf_fprintf_vma ( bfd *abfd  ATTRIBUTE_UNUSED,
void *  stream,
bfd_vma  value 
)

Definition at line 8577 of file elf.c.

{
#ifdef BFD64
  Elf_Internal_Ehdr *i_ehdrp;      /* Elf file header, internal form */

  i_ehdrp = elf_elfheader (abfd);
  if (i_ehdrp == NULL)
    fprintf_vma ((FILE *) stream, value);
  else
    {
      if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
       {
#if BFD_HOST_64BIT_LONG
         fprintf ((FILE *) stream, "%016lx", value);
#else
         fprintf ((FILE *) stream, "%08lx%08lx",
                 _bfd_int64_high (value), _bfd_int64_low (value));
#endif
       }
      else
       fprintf ((FILE *) stream, "%08lx",
               (unsigned long) (value & 0xffffffff));
    }
#else
  fprintf_vma ((FILE *) stream, value);
#endif
}

Here is the call graph for this function:

Definition at line 6603 of file elf.c.

{
  long ret;
  asection *s;

  if (elf_dynsymtab (abfd) == 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  ret = sizeof (arelent *);
  for (s = abfd->sections; s != NULL; s = s->next)
    if ((s->flags & SEC_LOAD) != 0
       && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
       && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
           || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
      ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
             * sizeof (arelent *));

  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6523 of file elf.c.

{
  long symcount;
  long symtab_size;
  Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;

  if (elf_dynsymtab (abfd) == 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
  symtab_size = (symcount + 1) * (sizeof (asymbol *));
  if (symcount > 0)
    symtab_size -= sizeof (asymbol *);

  return symtab_size;
}

Here is the call graph for this function:

alent* _bfd_elf_get_lineno ( bfd *abfd  ATTRIBUTE_UNUSED,
asymbol *symbol  ATTRIBUTE_UNUSED 
)

Definition at line 7044 of file elf.c.

{
  abort ();
  return NULL;
}
long _bfd_elf_get_reloc_upper_bound ( bfd *abfd  ATTRIBUTE_UNUSED,
sec_ptr  asect 
)

Definition at line 6544 of file elf.c.

{
  return (asect->reloc_count + 1) * sizeof (arelent *);
}

Definition at line 2478 of file elf.c.

{
  int i;
  const struct bfd_elf_special_section *spec;
  const struct elf_backend_data *bed;

  /* See if this is one of the special sections.  */
  if (sec->name == NULL)
    return NULL;

  bed = get_elf_backend_data (abfd);
  spec = bed->special_sections;
  if (spec)
    {
      spec = _bfd_elf_get_special_section (sec->name,
                                      bed->special_sections,
                                      sec->use_rela_p);
      if (spec != NULL)
       return spec;
    }

  if (sec->name[0] != '.')
    return NULL;

  i = sec->name[1] - 'b';
  if (i < 0 || i > 't' - 'b')
    return NULL;

  spec = special_sections[i];

  if (spec == NULL)
    return NULL;

  return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2430 of file elf.c.

{
  int i;
  int len;

  len = strlen (name);

  for (i = 0; spec[i].prefix != NULL; i++)
    {
      int suffix_len;
      int prefix_len = spec[i].prefix_length;

      if (len < prefix_len)
       continue;
      if (memcmp (name, spec[i].prefix, prefix_len) != 0)
       continue;

      suffix_len = spec[i].suffix_length;
      if (suffix_len <= 0)
       {
         if (name[prefix_len] != 0)
           {
             if (suffix_len == 0)
              continue;
             if (name[prefix_len] != '.'
                && (suffix_len == -2
                    || (rela && spec[i].type == SHT_REL)))
              continue;
           }
       }
      else
       {
         if (len < prefix_len + suffix_len)
           continue;
         if (memcmp (name + len - suffix_len,
                    spec[i].prefix + prefix_len,
                    suffix_len) != 0)
           continue;
       }
      return &spec[i];
    }

  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _bfd_elf_get_symbol_info ( bfd *abfd  ATTRIBUTE_UNUSED,
asymbol symbol,
symbol_info ret 
)

Definition at line 7007 of file elf.c.

{
  bfd_symbol_info (symbol, ret);
}

Here is the call graph for this function:

Definition at line 6508 of file elf.c.

{
  long symcount;
  long symtab_size;
  Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;

  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
  symtab_size = (symcount + 1) * (sizeof (asymbol *));
  if (symcount > 0)
    symtab_size -= sizeof (asymbol *);

  return symtab_size;
}
long _bfd_elf_get_synthetic_symtab ( bfd abfd,
long symcount  ATTRIBUTE_UNUSED,
asymbol **syms  ATTRIBUTE_UNUSED,
long  dynsymcount,
asymbol **  dynsyms,
asymbol **  ret 
)

Definition at line 8710 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  asection *relplt;
  asymbol *s;
  const char *relplt_name;
  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
  arelent *p;
  long count, i, n;
  size_t size;
  Elf_Internal_Shdr *hdr;
  char *names;
  asection *plt;

  *ret = NULL;

  if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
    return 0;

  if (dynsymcount <= 0)
    return 0;

  if (!bed->plt_sym_val)
    return 0;

  relplt_name = bed->relplt_name;
  if (relplt_name == NULL)
    relplt_name = bed->default_use_rela_p ? ".rela.plt" : ".rel.plt";
  relplt = bfd_get_section_by_name (abfd, relplt_name);
  if (relplt == NULL)
    return 0;

  hdr = &elf_section_data (relplt)->this_hdr;
  if (hdr->sh_link != elf_dynsymtab (abfd)
      || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
    return 0;

  plt = bfd_get_section_by_name (abfd, ".plt");
  if (plt == NULL)
    return 0;

  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
    return -1;

  count = relplt->size / hdr->sh_entsize;
  size = count * sizeof (asymbol);
  p = relplt->relocation;
  for (i = 0; i < count; i++, s++, p++)
    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");

  s = *ret = bfd_malloc (size);
  if (s == NULL)
    return -1;

  names = (char *) (s + count);
  p = relplt->relocation;
  n = 0;
  for (i = 0; i < count; i++, s++, p++)
    {
      size_t len;
      bfd_vma addr;

      addr = bed->plt_sym_val (i, plt, p);
      if (addr == (bfd_vma) -1)
       continue;

      *s = **p->sym_ptr_ptr;
      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
        we are defining a symbol, ensure one of them is set.  */
      if ((s->flags & BSF_LOCAL) == 0)
       s->flags |= BSF_GLOBAL;
      s->section = plt;
      s->value = addr - plt->vma;
      s->name = names;
      len = strlen ((*p->sym_ptr_ptr)->name);
      memcpy (names, (*p->sym_ptr_ptr)->name, len);
      names += len;
      memcpy (names, "@plt", sizeof ("@plt"));
      names += sizeof ("@plt");
      ++n;
    }

  return n;
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_init_private_section_data ( bfd ibfd,
asection isec,
bfd obfd,
asection osec,
struct bfd_link_info link_info 
)

Definition at line 6022 of file elf.c.

{
  Elf_Internal_Shdr *ihdr, *ohdr;
  bfd_boolean need_group = link_info == NULL || link_info->relocatable;

  if (ibfd->xvec->flavour != bfd_target_elf_flavour
      || obfd->xvec->flavour != bfd_target_elf_flavour)
    return TRUE;

  /* Don't copy the output ELF section type from input if the
     output BFD section flags have been set to something different.
     elf_fake_sections will set ELF section type based on BFD
     section flags.  */
  if (osec->flags == isec->flags || !osec->flags)
    {
      BFD_ASSERT (osec->flags == isec->flags 
                || (!osec->flags
                    && elf_section_type (osec) == SHT_NULL));
      elf_section_type (osec) = elf_section_type (isec);
    }

  /* FIXME: Is this correct for all OS/PROC specific flags?  */
  elf_section_flags (osec) |= (elf_section_flags (isec)
                            & (SHF_MASKOS | SHF_MASKPROC));

  /* Set things up for objcopy and relocatable link.  The output
     SHT_GROUP section will have its elf_next_in_group pointing back
     to the input group members.  Ignore linker created group section.
     See elfNN_ia64_object_p in elfxx-ia64.c.  */
  if (need_group)
    {
      if (elf_sec_group (isec) == NULL
         || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
       {
         if (elf_section_flags (isec) & SHF_GROUP)
           elf_section_flags (osec) |= SHF_GROUP;
         elf_next_in_group (osec) = elf_next_in_group (isec);
         elf_group_name (osec) = elf_group_name (isec);
       }
    }

  ihdr = &elf_section_data (isec)->this_hdr;

  /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
     don't use the output section of the linked-to section since it
     may be NULL at this point.  */
  if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
    {
      ohdr = &elf_section_data (osec)->this_hdr;
      ohdr->sh_flags |= SHF_LINK_ORDER;
      elf_linked_to_section (osec) = elf_linked_to_section (isec);
    }

  osec->use_rela_p = isec->use_rela_p;

  return TRUE;
}

Here is the caller graph for this function:

bfd_boolean _bfd_elf_init_reloc_shdr ( bfd abfd,
Elf_Internal_Shdr rel_hdr,
asection asect,
bfd_boolean  use_rela_p 
)

Definition at line 2703 of file elf.c.

{
  char *name;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);

  name = bfd_alloc (abfd, amt);
  if (name == NULL)
    return FALSE;
  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
  rel_hdr->sh_name =
    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
                                   FALSE);
  if (rel_hdr->sh_name == (unsigned int) -1)
    return FALSE;
  rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
  rel_hdr->sh_entsize = (use_rela_p
                      ? bed->s->sizeof_rela
                      : bed->s->sizeof_rel);
  rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
  rel_hdr->sh_flags = 0;
  rel_hdr->sh_addr = 0;
  rel_hdr->sh_size = 0;
  rel_hdr->sh_offset = 0;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_elf_is_local_label_name ( bfd *abfd  ATTRIBUTE_UNUSED,
const char *  name 
)

Definition at line 7019 of file elf.c.

{
  /* Normal local symbols start with ``.L''.  */
  if (name[0] == '.' && name[1] == 'L')
    return TRUE;

  /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
     DWARF debugging symbols starting with ``..''.  */
  if (name[0] == '.' && name[1] == '.')
    return TRUE;

  /* gcc will sometimes generate symbols beginning with ``_.L_'' when
     emitting DWARF debugging output.  I suspect this is actually a
     small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
     ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
     underscore to be emitted on some ELF targets).  For ease of use,
     we treat such symbols as local.  */
  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
    return TRUE;

  return FALSE;
}

Definition at line 1532 of file elf.c.

{
  struct elf_link_hash_table *htab;

  /* Copy down any references that we may have already seen to the
     symbol which just became indirect.  */

  dir->ref_dynamic |= ind->ref_dynamic;
  dir->ref_regular |= ind->ref_regular;
  dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
  dir->non_got_ref |= ind->non_got_ref;
  dir->needs_plt |= ind->needs_plt;
  dir->pointer_equality_needed |= ind->pointer_equality_needed;

  if (ind->root.type != bfd_link_hash_indirect)
    return;

  /* Copy over the global and procedure linkage table refcount entries.
     These may have been already set up by a check_relocs routine.  */
  htab = elf_hash_table (info);
  if (ind->got.refcount > htab->init_got_refcount.refcount)
    {
      if (dir->got.refcount < 0)
       dir->got.refcount = 0;
      dir->got.refcount += ind->got.refcount;
      ind->got.refcount = htab->init_got_refcount.refcount;
    }

  if (ind->plt.refcount > htab->init_plt_refcount.refcount)
    {
      if (dir->plt.refcount < 0)
       dir->plt.refcount = 0;
      dir->plt.refcount += ind->plt.refcount;
      ind->plt.refcount = htab->init_plt_refcount.refcount;
    }

  if (ind->dynindx != -1)
    {
      if (dir->dynindx != -1)
       _bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index);
      dir->dynindx = ind->dynindx;
      dir->dynstr_index = ind->dynstr_index;
      ind->dynindx = -1;
      ind->dynstr_index = 0;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1582 of file elf.c.

{
  h->plt = elf_hash_table (info)->init_plt_offset;
  h->needs_plt = 0;
  if (force_local)
    {
      h->forced_local = 1;
      if (h->dynindx != -1)
       {
         h->dynindx = -1;
         _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
                              h->dynstr_index);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct bfd_hash_entry* _bfd_elf_link_hash_newfunc ( struct bfd_hash_entry entry,
struct bfd_hash_table table,
const char *  string 
) [read]

Definition at line 1491 of file elf.c.

{
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (entry == NULL)
    {
      entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
      if (entry == NULL)
       return entry;
    }

  /* Call the allocation method of the superclass.  */
  entry = _bfd_link_hash_newfunc (entry, table, string);
  if (entry != NULL)
    {
      struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
      struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;

      /* Set local fields.  */
      ret->indx = -1;
      ret->dynindx = -1;
      ret->got = htab->init_got_refcount;
      ret->plt = htab->init_plt_refcount;
      memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry)
                           - offsetof (struct elf_link_hash_entry, size)));
      /* Assume that we have been called by a non-ELF symbol reader.
         This flag is then reset by the code which reads an ELF input
         file.  This ensures that a symbol created by a non-ELF symbol
         reader will have the flag set correctly.  */
      ret->non_elf = 1;
    }

  return entry;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1631 of file elf.c.

{
  struct elf_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct elf_link_hash_table);

  ret = bfd_malloc (amt);
  if (ret == NULL)
    return NULL;

  if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc,
                                   sizeof (struct elf_link_hash_entry)))
    {
      free (ret);
      return NULL;
    }

  return &ret->root;
}

Here is the call graph for this function:

Definition at line 1604 of file elf.c.

{
  bfd_boolean ret;
  int can_refcount = get_elf_backend_data (abfd)->can_refcount;

  memset (table, 0, sizeof * table);
  table->init_got_refcount.refcount = can_refcount - 1;
  table->init_plt_refcount.refcount = can_refcount - 1;
  table->init_got_offset.offset = -(bfd_vma) 1;
  table->init_plt_offset.offset = -(bfd_vma) 1;
  /* The first dynamic symbol is a dummy.  */
  table->dynsymcount = 1;

  ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
  table->root.type = bfd_link_elf_hash_table;

  return ret;
}

Here is the call graph for this function:

void _bfd_elf_link_just_syms ( asection sec,
struct bfd_link_info info 
)

Definition at line 1084 of file elf.c.

struct elf_segment_map* _bfd_elf_make_dynamic_segment ( bfd abfd,
asection dynsec 
) [read]

Definition at line 3737 of file elf.c.

{
  struct elf_segment_map *m;

  m = bfd_zalloc (abfd, sizeof (struct elf_segment_map));
  if (m == NULL)
    return NULL;
  m->next = NULL;
  m->p_type = PT_DYNAMIC;
  m->count = 1;
  m->sections[0] = dynsec;
  
  return m;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6991 of file elf.c.

{
  elf_symbol_type *newsym;
  bfd_size_type amt = sizeof (elf_symbol_type);

  newsym = bfd_zalloc (abfd, amt);
  if (!newsym)
    return NULL;
  else
    {
      newsym->symbol.the_bfd = abfd;
      return &newsym->symbol;
    }
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_make_section_from_phdr ( bfd abfd,
Elf_Internal_Phdr *  hdr,
int  index,
const char *  typename 
)

Definition at line 2577 of file elf.c.

{
  asection *newsect;
  char *name;
  char namebuf[64];
  size_t len;
  int split;

  split = ((hdr->p_memsz > 0)
           && (hdr->p_filesz > 0)
           && (hdr->p_memsz > hdr->p_filesz));
  sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
  len = strlen (namebuf) + 1;
  name = bfd_alloc (abfd, len);
  if (!name)
    return FALSE;
  memcpy (name, namebuf, len);
  newsect = bfd_make_section (abfd, name);
  if (newsect == NULL)
    return FALSE;
  newsect->vma = hdr->p_vaddr;
  newsect->lma = hdr->p_paddr;
  newsect->size = hdr->p_filesz;
  newsect->filepos = hdr->p_offset;
  newsect->flags |= SEC_HAS_CONTENTS;
  newsect->alignment_power = bfd_log2 (hdr->p_align);
  if (hdr->p_type == PT_LOAD)
    {
      newsect->flags |= SEC_ALLOC;
      newsect->flags |= SEC_LOAD;
      if (hdr->p_flags & PF_X)
       {
         /* FIXME: all we known is that it has execute PERMISSION,
            may be data.  */
         newsect->flags |= SEC_CODE;
       }
    }
  if (!(hdr->p_flags & PF_W))
    {
      newsect->flags |= SEC_READONLY;
    }

  if (split)
    {
      sprintf (namebuf, "%s%db", typename, index);
      len = strlen (namebuf) + 1;
      name = bfd_alloc (abfd, len);
      if (!name)
       return FALSE;
      memcpy (name, namebuf, len);
      newsect = bfd_make_section (abfd, name);
      if (newsect == NULL)
       return FALSE;
      newsect->vma = hdr->p_vaddr + hdr->p_filesz;
      newsect->lma = hdr->p_paddr + hdr->p_filesz;
      newsect->size = hdr->p_memsz - hdr->p_filesz;
      if (hdr->p_type == PT_LOAD)
       {
         newsect->flags |= SEC_ALLOC;
         if (hdr->p_flags & PF_X)
           newsect->flags |= SEC_CODE;
       }
      if (!(hdr->p_flags & PF_W))
       newsect->flags |= SEC_READONLY;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_elf_make_section_from_shdr ( bfd abfd,
Elf_Internal_Shdr hdr,
const char *  name,
int  shindex 
)

Definition at line 770 of file elf.c.

{
  asection *newsect;
  flagword flags;
  const struct elf_backend_data *bed;

  if (hdr->bfd_section != NULL)
    {
      BFD_ASSERT (strcmp (name,
                       bfd_get_section_name (abfd, hdr->bfd_section)) == 0);
      return TRUE;
    }

  newsect = bfd_make_section_anyway (abfd, name);
  if (newsect == NULL)
    return FALSE;

  hdr->bfd_section = newsect;
  elf_section_data (newsect)->this_hdr = *hdr;
  elf_section_data (newsect)->this_idx = shindex;

  /* Always use the real type/flags.  */
  elf_section_type (newsect) = hdr->sh_type;
  elf_section_flags (newsect) = hdr->sh_flags;

  newsect->filepos = hdr->sh_offset;

  if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
      || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
      || ! bfd_set_section_alignment (abfd, newsect,
                                  bfd_log2 ((bfd_vma) hdr->sh_addralign)))
    return FALSE;

  flags = SEC_NO_FLAGS;
  if (hdr->sh_type != SHT_NOBITS)
    flags |= SEC_HAS_CONTENTS;
  if (hdr->sh_type == SHT_GROUP)
    flags |= SEC_GROUP | SEC_EXCLUDE;
  if ((hdr->sh_flags & SHF_ALLOC) != 0)
    {
      flags |= SEC_ALLOC;
      if (hdr->sh_type != SHT_NOBITS)
       flags |= SEC_LOAD;
    }
  if ((hdr->sh_flags & SHF_WRITE) == 0)
    flags |= SEC_READONLY;
  if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
    flags |= SEC_CODE;
  else if ((flags & SEC_LOAD) != 0)
    flags |= SEC_DATA;
  if ((hdr->sh_flags & SHF_MERGE) != 0)
    {
      flags |= SEC_MERGE;
      newsect->entsize = hdr->sh_entsize;
      if ((hdr->sh_flags & SHF_STRINGS) != 0)
       flags |= SEC_STRINGS;
    }
  if (hdr->sh_flags & SHF_GROUP)
    if (!setup_group (abfd, hdr, newsect))
      return FALSE;
  if ((hdr->sh_flags & SHF_TLS) != 0)
    flags |= SEC_THREAD_LOCAL;

  if ((flags & SEC_ALLOC) == 0)
    {
      /* The debugging sections appear to be recognized only by name,
        not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
      static const struct
       {
         const char *name;
         int len;
       } debug_sections [] =
       {
         { STRING_COMMA_LEN ("debug") },  /* 'd' */
         { NULL,             0  }, /* 'e' */
         { NULL,             0  }, /* 'f' */
         { STRING_COMMA_LEN ("gnu.linkonce.wi.") },     /* 'g' */
         { NULL,             0  }, /* 'h' */
         { NULL,             0  }, /* 'i' */
         { NULL,             0  }, /* 'j' */
         { NULL,             0  }, /* 'k' */
         { STRING_COMMA_LEN ("line") },   /* 'l' */
         { NULL,             0  }, /* 'm' */
         { NULL,             0  }, /* 'n' */
         { NULL,             0  }, /* 'o' */
         { NULL,             0  }, /* 'p' */
         { NULL,             0  }, /* 'q' */
         { NULL,             0  }, /* 'r' */
         { STRING_COMMA_LEN ("stab") }    /* 's' */
       };
      
      if (name [0] == '.')
       {
         int i = name [1] - 'd';
         if (i >= 0
             && i < (int) ARRAY_SIZE (debug_sections)
             && debug_sections [i].name != NULL
             && strncmp (&name [1], debug_sections [i].name,
                       debug_sections [i].len) == 0)
           flags |= SEC_DEBUGGING;
       }
    }

  /* As a GNU extension, if the name begins with .gnu.linkonce, we
     only link a single copy of the section.  This is used to support
     g++.  g++ will emit each template expansion in its own section.
     The symbols will be defined as weak, so that multiple definitions
     are permitted.  The GNU linker extension is to actually discard
     all but one of the sections.  */
  if (CONST_STRNEQ (name, ".gnu.linkonce")
      && elf_next_in_group (newsect) == NULL)
    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;

  bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_section_flags)
    if (! bed->elf_backend_section_flags (&flags, hdr))
      return FALSE;

  if (! bfd_set_section_flags (abfd, newsect, flags))
    return FALSE;

  if ((flags & SEC_ALLOC) != 0)
    {
      Elf_Internal_Phdr *phdr;
      unsigned int i;

      /* Look through the phdrs to see if we need to adjust the lma.
         If all the p_paddr fields are zero, we ignore them, since
         some ELF linkers produce such output.  */
      phdr = elf_tdata (abfd)->phdr;
      for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
       {
         if (phdr->p_paddr != 0)
           break;
       }
      if (i < elf_elfheader (abfd)->e_phnum)
       {
         phdr = elf_tdata (abfd)->phdr;
         for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
           {
             /* This section is part of this segment if its file
               offset plus size lies within the segment's memory
               span and, if the section is loaded, the extent of the
               loaded data lies within the extent of the segment.

               Note - we used to check the p_paddr field as well, and
               refuse to set the LMA if it was 0.  This is wrong
               though, as a perfectly valid initialised segment can
               have a p_paddr of zero.  Some architectures, eg ARM,
                place special significance on the address 0 and
                executables need to be able to have a segment which
                covers this address.  */
             if (phdr->p_type == PT_LOAD
                && (bfd_vma) hdr->sh_offset >= phdr->p_offset
                && (hdr->sh_offset + hdr->sh_size
                    <= phdr->p_offset + phdr->p_memsz)
                && ((flags & SEC_LOAD) == 0
                    || (hdr->sh_offset + hdr->sh_size
                       <= phdr->p_offset + phdr->p_filesz)))
              {
                if ((flags & SEC_LOAD) == 0)
                  newsect->lma = (phdr->p_paddr
                                + hdr->sh_addr - phdr->p_vaddr);
                else
                  /* We used to use the same adjustment for SEC_LOAD
                     sections, but that doesn't work if the segment
                     is packed with code from multiple VMAs.
                     Instead we calculate the section LMA based on
                     the segment LMA.  It is assumed that the
                     segment will contain sections with contiguous
                     LMAs, even if the VMAs are not.  */
                  newsect->lma = (phdr->p_paddr
                                + hdr->sh_offset - phdr->p_offset);

                /* With contiguous segments, we can't tell from file
                   offsets whether a section with zero size should
                   be placed at the end of one segment or the
                   beginning of the next.  Decide based on vaddr.  */
                if (hdr->sh_addr >= phdr->p_vaddr
                    && (hdr->sh_addr + hdr->sh_size
                       <= phdr->p_vaddr + phdr->p_memsz))
                  break;
              }
           }
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3801 of file elf.c.

{
  unsigned int count;
  struct elf_segment_map *m;
  asection **sections = NULL;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if (elf_tdata (abfd)->segment_map == NULL
      && bfd_count_sections (abfd) != 0)
    {
      asection *s;
      unsigned int i;
      struct elf_segment_map *mfirst;
      struct elf_segment_map **pm;
      asection *last_hdr;
      bfd_vma last_size;
      unsigned int phdr_index;
      bfd_vma maxpagesize;
      asection **hdrpp;
      bfd_boolean phdr_in_segment = TRUE;
      bfd_boolean writable;
      int tls_count = 0;
      asection *first_tls = NULL;
      asection *dynsec, *eh_frame_hdr;
      bfd_size_type amt;

      /* Select the allocated sections, and sort them.  */

      sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *));
      if (sections == NULL)
       goto error_return;

      i = 0;
      for (s = abfd->sections; s != NULL; s = s->next)
       {
         if ((s->flags & SEC_ALLOC) != 0)
           {
             sections[i] = s;
             ++i;
           }
       }
      BFD_ASSERT (i <= bfd_count_sections (abfd));
      count = i;

      qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);

      /* Build the mapping.  */

      mfirst = NULL;
      pm = &mfirst;

      /* If we have a .interp section, then create a PT_PHDR segment for
        the program headers and a PT_INTERP segment for the .interp
        section.  */
      s = bfd_get_section_by_name (abfd, ".interp");
      if (s != NULL && (s->flags & SEC_LOAD) != 0)
       {
         amt = sizeof (struct elf_segment_map);
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           goto error_return;
         m->next = NULL;
         m->p_type = PT_PHDR;
         /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not.  */
         m->p_flags = PF_R | PF_X;
         m->p_flags_valid = 1;
         m->includes_phdrs = 1;

         *pm = m;
         pm = &m->next;

         amt = sizeof (struct elf_segment_map);
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           goto error_return;
         m->next = NULL;
         m->p_type = PT_INTERP;
         m->count = 1;
         m->sections[0] = s;

         *pm = m;
         pm = &m->next;
       }

      /* Look through the sections.  We put sections in the same program
        segment when the start of the second section can be placed within
        a few bytes of the end of the first section.  */
      last_hdr = NULL;
      last_size = 0;
      phdr_index = 0;
      maxpagesize = bed->maxpagesize;
      writable = FALSE;
      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
      if (dynsec != NULL
         && (dynsec->flags & SEC_LOAD) == 0)
       dynsec = NULL;

      /* Deal with -Ttext or something similar such that the first section
        is not adjacent to the program headers.  This is an
        approximation, since at this point we don't know exactly how many
        program headers we will need.  */
      if (count > 0)
       {
         bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size;

         if (phdr_size == (bfd_size_type) -1)
           phdr_size = get_program_header_size (abfd, info);
         if ((abfd->flags & D_PAGED) == 0
             || sections[0]->lma < phdr_size
             || sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
           phdr_in_segment = FALSE;
       }

      for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
       {
         asection *hdr;
         bfd_boolean new_segment;

         hdr = *hdrpp;

         /* See if this section and the last one will fit in the same
            segment.  */

         if (last_hdr == NULL)
           {
             /* If we don't have a segment yet, then we don't need a new
               one (we build the last one after this loop).  */
             new_segment = FALSE;
           }
         else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
           {
             /* If this section has a different relation between the
               virtual address and the load address, then we need a new
               segment.  */
             new_segment = TRUE;
           }
         else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
                 < BFD_ALIGN (hdr->lma, maxpagesize))
           {
             /* If putting this section in this segment would force us to
               skip a page in the segment, then we need a new segment.  */
             new_segment = TRUE;
           }
         else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
                 && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
           {
             /* We don't want to put a loadable section after a
               nonloadable section in the same segment.
               Consider .tbss sections as loadable for this purpose.  */
             new_segment = TRUE;
           }
         else if ((abfd->flags & D_PAGED) == 0)
           {
             /* If the file is not demand paged, which means that we
               don't require the sections to be correctly aligned in the
               file, then there is no other reason for a new segment.  */
             new_segment = FALSE;
           }
         else if (! writable
                 && (hdr->flags & SEC_READONLY) == 0
                 && (((last_hdr->lma + last_size - 1)
                     & ~(maxpagesize - 1))
                     != (hdr->lma & ~(maxpagesize - 1))))
           {
             /* We don't want to put a writable section in a read only
               segment, unless they are on the same page in memory
               anyhow.  We already know that the last section does not
               bring us past the current section on the page, so the
               only case in which the new section is not on the same
               page as the previous section is when the previous section
               ends precisely on a page boundary.  */
             new_segment = TRUE;
           }
         else
           {
             /* Otherwise, we can use the same segment.  */
             new_segment = FALSE;
           }

         /* Allow interested parties a chance to override our decision.  */
         if (last_hdr && info->callbacks->override_segment_assignment)
           new_segment = info->callbacks->override_segment_assignment (info, abfd, hdr, last_hdr, new_segment);

         if (! new_segment)
           {
             if ((hdr->flags & SEC_READONLY) == 0)
              writable = TRUE;
             last_hdr = hdr;
             /* .tbss sections effectively have zero size.  */
             if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
                != SEC_THREAD_LOCAL)
              last_size = hdr->size;
             else
              last_size = 0;
             continue;
           }

         /* We need a new program segment.  We must create a new program
            header holding all the sections from phdr_index until hdr.  */

         m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
         if (m == NULL)
           goto error_return;

         *pm = m;
         pm = &m->next;

         if ((hdr->flags & SEC_READONLY) == 0)
           writable = TRUE;
         else
           writable = FALSE;

         last_hdr = hdr;
         /* .tbss sections effectively have zero size.  */
         if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
           last_size = hdr->size;
         else
           last_size = 0;
         phdr_index = i;
         phdr_in_segment = FALSE;
       }

      /* Create a final PT_LOAD program segment.  */
      if (last_hdr != NULL)
       {
         m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
         if (m == NULL)
           goto error_return;

         *pm = m;
         pm = &m->next;
       }

      /* If there is a .dynamic section, throw in a PT_DYNAMIC segment.  */
      if (dynsec != NULL)
       {
         m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
         if (m == NULL)
           goto error_return;
         *pm = m;
         pm = &m->next;
       }

      /* For each loadable .note section, add a PT_NOTE segment.  We don't
        use bfd_get_section_by_name, because if we link together
        nonloadable .note sections and loadable .note sections, we will
        generate two .note sections in the output file.  FIXME: Using
        names for section types is bogus anyhow.  */
      for (s = abfd->sections; s != NULL; s = s->next)
       {
         if ((s->flags & SEC_LOAD) != 0
             && CONST_STRNEQ (s->name, ".note"))
           {
             amt = sizeof (struct elf_segment_map);
             m = bfd_zalloc (abfd, amt);
             if (m == NULL)
              goto error_return;
             m->next = NULL;
             m->p_type = PT_NOTE;
             m->count = 1;
             m->sections[0] = s;

             *pm = m;
             pm = &m->next;
           }
         if (s->flags & SEC_THREAD_LOCAL)
           {
             if (! tls_count)
              first_tls = s;
             tls_count++;
           }
       }

      /* If there are any SHF_TLS output sections, add PT_TLS segment.  */
      if (tls_count > 0)
       {
         int i;

         amt = sizeof (struct elf_segment_map);
         amt += (tls_count - 1) * sizeof (asection *);
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           goto error_return;
         m->next = NULL;
         m->p_type = PT_TLS;
         m->count = tls_count;
         /* Mandated PF_R.  */
         m->p_flags = PF_R;
         m->p_flags_valid = 1;
         for (i = 0; i < tls_count; ++i)
           {
             BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
             m->sections[i] = first_tls;
             first_tls = first_tls->next;
           }

         *pm = m;
         pm = &m->next;
       }

      /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
        segment.  */
      eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
      if (eh_frame_hdr != NULL
         && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
       {
         amt = sizeof (struct elf_segment_map);
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           goto error_return;
         m->next = NULL;
         m->p_type = PT_GNU_EH_FRAME;
         m->count = 1;
         m->sections[0] = eh_frame_hdr->output_section;

         *pm = m;
         pm = &m->next;
       }

      if (elf_tdata (abfd)->stack_flags)
       {
         amt = sizeof (struct elf_segment_map);
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           goto error_return;
         m->next = NULL;
         m->p_type = PT_GNU_STACK;
         m->p_flags = elf_tdata (abfd)->stack_flags;
         m->p_flags_valid = 1;

         *pm = m;
         pm = &m->next;
       }

      if (dynsec != NULL && elf_tdata (abfd)->relro)
       {
         /* We make a PT_GNU_RELRO segment only when there is a
            PT_DYNAMIC segment.  */
         amt = sizeof (struct elf_segment_map);
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           goto error_return;
         m->next = NULL;
         m->p_type = PT_GNU_RELRO;
         m->p_flags = PF_R;
         m->p_flags_valid = 1;

         *pm = m;
         pm = &m->next;
       }

      free (sections);
      elf_tdata (abfd)->segment_map = mfirst;
    }

  if (!elf_modify_segment_map (abfd, info))
    return FALSE;

  for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
    ++count;
  elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr;

  return TRUE;

 error_return:
  if (sections != NULL)
    free (sections);
  return FALSE;
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_match_sections_by_type ( bfd abfd,
const asection asec,
bfd bbfd,
const asection bsec 
)

Definition at line 9148 of file elf.c.

{
  if (asec == NULL
      || bsec == NULL
      || abfd->xvec->flavour != bfd_target_elf_flavour
      || bbfd->xvec->flavour != bfd_target_elf_flavour)
    return TRUE;

  return elf_section_type (asec) == elf_section_type (bsec);
}

Definition at line 1052 of file elf.c.

{
  bfd *ibfd;
  asection *sec;

  if (!is_elf_hash_table (info->hash))
    return FALSE;

  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
    if ((ibfd->flags & DYNAMIC) == 0)
      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
       if ((sec->flags & SEC_MERGE) != 0
           && !bfd_is_abs_section (sec->output_section))
         {
           struct bfd_elf_section_data *secdata;

           secdata = elf_section_data (sec);
           if (! _bfd_add_merge_section (abfd,
                                     &elf_hash_table (info)->merge_info,
                                     sec, &secdata->sec_info))
             return FALSE;
           else if (secdata->sec_info)
             sec->sec_info_type = ELF_INFO_TYPE_MERGE;
         }

  if (elf_hash_table (info)->merge_info != NULL)
    _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info,
                      merge_sections_remove_hook);
  return TRUE;
}

Here is the call graph for this function:

Definition at line 2515 of file elf.c.

{
  struct bfd_elf_section_data *sdata;
  const struct elf_backend_data *bed;
  const struct bfd_elf_special_section *ssect;

  sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
  if (sdata == NULL)
    {
      sdata = bfd_zalloc (abfd, sizeof (*sdata));
      if (sdata == NULL)
       return FALSE;
      sec->used_by_bfd = sdata;
    }

  /* Indicate whether or not this section should use RELA relocations.  */
  bed = get_elf_backend_data (abfd);
  sec->use_rela_p = bed->default_use_rela_p;

  /* When we read a file, we don't need to set ELF section type and
     flags.  They will be overridden in _bfd_elf_make_section_from_shdr
     anyway.  We will set ELF section type and flags for all linker
     created sections.  If user specifies BFD section flags, we will
     set ELF section type and flags based on BFD section flags in
     elf_fake_sections.  */
  if ((!sec->flags && abfd->direction != read_direction)
      || (sec->flags & SEC_LINKER_CREATED) != 0)
    {
      ssect = (*bed->get_sec_type_attr) (abfd, sec);
      if (ssect != NULL)
       {
         elf_section_type (sec) = ssect->type;
         elf_section_flags (sec) = ssect->attr;
       }
    }

  return _bfd_generic_new_section_hook (abfd, sec);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _bfd_elf_no_info_to_howto ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent *cache_ptr  ATTRIBUTE_UNUSED,
Elf_Internal_Rela *dst  ATTRIBUTE_UNUSED 
)

Definition at line 7284 of file elf.c.

{
  abort ();
}
bfd_boolean _bfd_elf_print_private_bfd_data ( bfd abfd,
void *  farg 
)

Definition at line 1139 of file elf.c.

{
  FILE *f = farg;
  Elf_Internal_Phdr *p;
  asection *s;
  bfd_byte *dynbuf = NULL;

  p = elf_tdata (abfd)->phdr;
  if (p != NULL)
    {
      unsigned int i, c;

      fprintf (f, _("\nProgram Header:\n"));
      c = elf_elfheader (abfd)->e_phnum;
      for (i = 0; i < c; i++, p++)
       {
         const char *pt = get_segment_type (p->p_type);
         char buf[20];

         if (pt == NULL)
           {
             sprintf (buf, "0x%lx", p->p_type);
             pt = buf;
           }
         fprintf (f, "%8s off    0x", pt);
         bfd_fprintf_vma (abfd, f, p->p_offset);
         fprintf (f, " vaddr 0x");
         bfd_fprintf_vma (abfd, f, p->p_vaddr);
         fprintf (f, " paddr 0x");
         bfd_fprintf_vma (abfd, f, p->p_paddr);
         fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
         fprintf (f, "         filesz 0x");
         bfd_fprintf_vma (abfd, f, p->p_filesz);
         fprintf (f, " memsz 0x");
         bfd_fprintf_vma (abfd, f, p->p_memsz);
         fprintf (f, " flags %c%c%c",
                 (p->p_flags & PF_R) != 0 ? 'r' : '-',
                 (p->p_flags & PF_W) != 0 ? 'w' : '-',
                 (p->p_flags & PF_X) != 0 ? 'x' : '-');
         if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
           fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
         fprintf (f, "\n");
       }
    }

  s = bfd_get_section_by_name (abfd, ".dynamic");
  if (s != NULL)
    {
      int elfsec;
      unsigned long shlink;
      bfd_byte *extdyn, *extdynend;
      size_t extdynsize;
      void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);

      fprintf (f, _("\nDynamic Section:\n"));

      if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
       goto error_return;

      elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
      if (elfsec == -1)
       goto error_return;
      shlink = elf_elfsections (abfd)[elfsec]->sh_link;

      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;

      extdyn = dynbuf;
      extdynend = extdyn + s->size;
      for (; extdyn < extdynend; extdyn += extdynsize)
       {
         Elf_Internal_Dyn dyn;
         const char *name;
         char ab[20];
         bfd_boolean stringp;

         (*swap_dyn_in) (abfd, extdyn, &dyn);

         if (dyn.d_tag == DT_NULL)
           break;

         stringp = FALSE;
         switch (dyn.d_tag)
           {
           default:
             sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
             name = ab;
             break;

           case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
           case DT_PLTRELSZ: name = "PLTRELSZ"; break;
           case DT_PLTGOT: name = "PLTGOT"; break;
           case DT_HASH: name = "HASH"; break;
           case DT_STRTAB: name = "STRTAB"; break;
           case DT_SYMTAB: name = "SYMTAB"; break;
           case DT_RELA: name = "RELA"; break;
           case DT_RELASZ: name = "RELASZ"; break;
           case DT_RELAENT: name = "RELAENT"; break;
           case DT_STRSZ: name = "STRSZ"; break;
           case DT_SYMENT: name = "SYMENT"; break;
           case DT_INIT: name = "INIT"; break;
           case DT_FINI: name = "FINI"; break;
           case DT_SONAME: name = "SONAME"; stringp = TRUE; break;
           case DT_RPATH: name = "RPATH"; stringp = TRUE; break;
           case DT_SYMBOLIC: name = "SYMBOLIC"; break;
           case DT_REL: name = "REL"; break;
           case DT_RELSZ: name = "RELSZ"; break;
           case DT_RELENT: name = "RELENT"; break;
           case DT_PLTREL: name = "PLTREL"; break;
           case DT_DEBUG: name = "DEBUG"; break;
           case DT_TEXTREL: name = "TEXTREL"; break;
           case DT_JMPREL: name = "JMPREL"; break;
           case DT_BIND_NOW: name = "BIND_NOW"; break;
           case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
           case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
           case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
           case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
           case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break;
           case DT_FLAGS: name = "FLAGS"; break;
           case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
           case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
           case DT_CHECKSUM: name = "CHECKSUM"; break;
           case DT_PLTPADSZ: name = "PLTPADSZ"; break;
           case DT_MOVEENT: name = "MOVEENT"; break;
           case DT_MOVESZ: name = "MOVESZ"; break;
           case DT_FEATURE: name = "FEATURE"; break;
           case DT_POSFLAG_1: name = "POSFLAG_1"; break;
           case DT_SYMINSZ: name = "SYMINSZ"; break;
           case DT_SYMINENT: name = "SYMINENT"; break;
           case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break;
           case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break;
           case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break;
           case DT_PLTPAD: name = "PLTPAD"; break;
           case DT_MOVETAB: name = "MOVETAB"; break;
           case DT_SYMINFO: name = "SYMINFO"; break;
           case DT_RELACOUNT: name = "RELACOUNT"; break;
           case DT_RELCOUNT: name = "RELCOUNT"; break;
           case DT_FLAGS_1: name = "FLAGS_1"; break;
           case DT_VERSYM: name = "VERSYM"; break;
           case DT_VERDEF: name = "VERDEF"; break;
           case DT_VERDEFNUM: name = "VERDEFNUM"; break;
           case DT_VERNEED: name = "VERNEED"; break;
           case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
           case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
           case DT_USED: name = "USED"; break;
           case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
           case DT_GNU_HASH: name = "GNU_HASH"; break;
           }

         fprintf (f, "  %-11s ", name);
         if (! stringp)
           fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
         else
           {
             const char *string;
             unsigned int tagv = dyn.d_un.d_val;

             string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
             if (string == NULL)
              goto error_return;
             fprintf (f, "%s", string);
           }
         fprintf (f, "\n");
       }

      free (dynbuf);
      dynbuf = NULL;
    }

  if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
      || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
    {
      if (! _bfd_elf_slurp_version_tables (abfd, FALSE))
       return FALSE;
    }

  if (elf_dynverdef (abfd) != 0)
    {
      Elf_Internal_Verdef *t;

      fprintf (f, _("\nVersion definitions:\n"));
      for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
       {
         fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
                 t->vd_flags, t->vd_hash,
                 t->vd_nodename ? t->vd_nodename : "<corrupt>");
         if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
           {
             Elf_Internal_Verdaux *a;

             fprintf (f, "\t");
             for (a = t->vd_auxptr->vda_nextptr;
                 a != NULL;
                 a = a->vda_nextptr)
              fprintf (f, "%s ",
                      a->vda_nodename ? a->vda_nodename : "<corrupt>");
             fprintf (f, "\n");
           }
       }
    }

  if (elf_dynverref (abfd) != 0)
    {
      Elf_Internal_Verneed *t;

      fprintf (f, _("\nVersion References:\n"));
      for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
       {
         Elf_Internal_Vernaux *a;

         fprintf (f, _("  required from %s:\n"),
                 t->vn_filename ? t->vn_filename : "<corrupt>");
         for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
           fprintf (f, "    0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
                   a->vna_flags, a->vna_other,
                   a->vna_nodename ? a->vna_nodename : "<corrupt>");
       }
    }

  return TRUE;

 error_return:
  if (dynbuf != NULL)
    free (dynbuf);
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_vma _bfd_elf_rel_local_sym ( bfd abfd,
Elf_Internal_Sym *  sym,
asection **  psec,
bfd_vma  addend 
)

Definition at line 8652 of file elf.c.

{
  asection *sec = *psec;

  if (sec->sec_info_type != ELF_INFO_TYPE_MERGE)
    return sym->st_value + addend;

  return _bfd_merged_section_offset (abfd, psec,
                                 elf_section_data (sec)->sec_info,
                                 sym->st_value + addend);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent *re  ATTRIBUTE_UNUSED,
struct bfd_symbol *symbol  ATTRIBUTE_UNUSED,
void *data  ATTRIBUTE_UNUSED,
asection *is  ATTRIBUTE_UNUSED,
bfd *obfd  ATTRIBUTE_UNUSED,
char **errmsg  ATTRIBUTE_UNUSED 
)

Definition at line 7407 of file elf.c.

{
  return bfd_reloc_ok;
}
bfd_vma _bfd_elf_rela_local_sym ( bfd abfd,
Elf_Internal_Sym *  sym,
asection **  psec,
Elf_Internal_Rela rel 
)

Definition at line 8615 of file elf.c.

{
  asection *sec = *psec;
  bfd_vma relocation;

  relocation = (sec->output_section->vma
              + sec->output_offset
              + sym->st_value);
  if ((sec->flags & SEC_MERGE)
      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
    {
      rel->r_addend =
       _bfd_merged_section_offset (abfd, psec,
                                elf_section_data (sec)->sec_info,
                                sym->st_value + rel->r_addend);
      if (sec != *psec)
       {
         /* If we have changed the section, and our original section is
            marked with SEC_EXCLUDE, it means that the original
            SEC_MERGE section has been completely subsumed in some
            other SEC_MERGE section.  In this case, we need to leave
            some info around for --emit-relocs.  */
         if ((sec->flags & SEC_EXCLUDE) != 0)
           sec->kept_section = *psec;
         sec = *psec;
       }
      rel->r_addend -= relocation;
      rel->r_addend += sec->output_section->vma + sec->output_offset;
    }
  return relocation;
}

Here is the call graph for this function:

Definition at line 8606 of file elf.c.

{
  return reloc_class_normal;
}

Definition at line 5115 of file elf.c.

{
  const struct elf_backend_data *bed;
  int index;

  if (elf_section_data (asect) != NULL
      && elf_section_data (asect)->this_idx != 0)
    return elf_section_data (asect)->this_idx;

  if (bfd_is_abs_section (asect))
    index = SHN_ABS;
  else if (bfd_is_com_section (asect))
    index = SHN_COMMON;
  else if (bfd_is_und_section (asect))
    index = SHN_UNDEF;
  else
    index = -1;

  bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_section_from_bfd_section)
    {
      int retval = index;

      if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
       return retval;
    }

  if (index == -1)
    bfd_set_error (bfd_error_nonrepresentable_section);

  return index;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_vma _bfd_elf_section_offset ( bfd abfd,
struct bfd_link_info info,
asection sec,
bfd_vma  offset 
)

Definition at line 8668 of file elf.c.

{
  switch (sec->sec_info_type)
    {
    case ELF_INFO_TYPE_STABS:
      return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
                                   offset);
    case ELF_INFO_TYPE_EH_FRAME:
      return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
    default:
      return offset;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_elf_set_arch_mach ( bfd abfd,
enum bfd_architecture  arch,
unsigned long  machine 
)

Definition at line 7052 of file elf.c.

{
  /* If this isn't the right architecture for this backend, and this
     isn't the generic backend, fail.  */
  if (arch != get_elf_backend_data (abfd)->arch
      && arch != bfd_arch_unknown
      && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
    return FALSE;

  return bfd_default_set_arch_mach (abfd, arch, machine);
}

Here is the call graph for this function:

void _bfd_elf_set_osabi ( bfd abfd,
struct bfd_link_info *link_info  ATTRIBUTE_UNUSED 
)

Definition at line 9161 of file elf.c.

{
  Elf_Internal_Ehdr * i_ehdrp;     /* ELF file header, internal form.  */

  i_ehdrp = elf_elfheader (abfd);

  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
}
bfd_boolean _bfd_elf_set_section_contents ( bfd abfd,
sec_ptr  section,
const void *  location,
file_ptr  offset,
bfd_size_type  count 
)

Definition at line 7261 of file elf.c.

{
  Elf_Internal_Shdr *hdr;
  bfd_signed_vma pos;

  if (! abfd->output_has_begun
      && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
    return FALSE;

  hdr = &elf_section_data (section)->this_hdr;
  pos = hdr->sh_offset + offset;
  if (bfd_seek (abfd, pos, SEEK_SET) != 0
      || bfd_bwrite (location, count, abfd) != count)
    return FALSE;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 672 of file elf.c.

{
  unsigned int i;
  unsigned int num_group = elf_tdata (abfd)->num_group;
  bfd_boolean result = TRUE;
  asection *s;

  /* Process SHF_LINK_ORDER.  */
  for (s = abfd->sections; s != NULL; s = s->next)
    {
      Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
      if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
       {
         unsigned int elfsec = this_hdr->sh_link;
         /* FIXME: The old Intel compiler and old strip/objcopy may
            not set the sh_link or sh_info fields.  Hence we could
            get the situation where elfsec is 0.  */
         if (elfsec == 0)
           {
             const struct elf_backend_data *bed
              = get_elf_backend_data (abfd);
             if (bed->link_order_error_handler)
              bed->link_order_error_handler
                (_("%B: warning: sh_link not set for section `%A'"),
                 abfd, s);
           }
         else
           {
             asection *link;

             this_hdr = elf_elfsections (abfd)[elfsec];

             /* PR 1991, 2008:
               Some strip/objcopy may leave an incorrect value in
               sh_link.  We don't want to proceed.  */
             link = this_hdr->bfd_section;
             if (link == NULL)
              {
                (*_bfd_error_handler)
                  (_("%B: sh_link [%d] in section `%A' is incorrect"),
                   s->owner, s, elfsec);
                result = FALSE;
              }

             elf_linked_to_section (s) = link;
           }
       }
    }

  /* Process section groups.  */
  if (num_group == (unsigned) -1)
    return result;

  for (i = 0; i < num_group; i++)
    {
      Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
      Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
      unsigned int n_elt = shdr->sh_size / 4;

      while (--n_elt != 0)
       if ((++idx)->shdr->bfd_section)
         elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
       else if (idx->shdr->sh_type == SHT_RELA
               || idx->shdr->sh_type == SHT_REL)
         /* We won't include relocation sections in section groups in
            output object files. We adjust the group section size here
            so that relocatable link will work correctly when
            relocation sections are in section group in input object
            files.  */
         shdr->bfd_section->size -= 4;
       else
         {
           /* There are some unknown sections in the group.  */
           (*_bfd_error_handler)
             (_("%B: unknown [%d] section `%s' in group [%s]"),
              abfd,
              (unsigned int) idx->shdr->sh_type,
              bfd_elf_string_from_elf_section (abfd,
                                          (elf_elfheader (abfd)
                                           ->e_shstrndx),
                                          idx->shdr->sh_name),
              shdr->bfd_section->name);
           result = FALSE;
         }
    }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 7232 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  int ret = bed->s->sizeof_ehdr;

  if (!info->relocatable)
    {
      bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size;

      if (phdr_size == (bfd_size_type) -1)
       {
         struct elf_segment_map *m;

         phdr_size = 0;
         for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
           phdr_size += bed->s->sizeof_phdr;

         if (phdr_size == 0)
           phdr_size = get_program_header_size (abfd, info);
       }

      elf_tdata (abfd)->program_header_size = phdr_size;
      ret += phdr_size;
    }

  return ret;
}

Here is the call graph for this function:

bfd_boolean _bfd_elf_slurp_version_tables ( bfd abfd,
bfd_boolean  default_imported_symver 
)

Definition at line 6679 of file elf.c.

{
  bfd_byte *contents = NULL;
  unsigned int freeidx = 0;

  if (elf_dynverref (abfd) != 0)
    {
      Elf_Internal_Shdr *hdr;
      Elf_External_Verneed *everneed;
      Elf_Internal_Verneed *iverneed;
      unsigned int i;
      bfd_byte *contents_end;

      hdr = &elf_tdata (abfd)->dynverref_hdr;

      elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info,
                                         sizeof (Elf_Internal_Verneed));
      if (elf_tdata (abfd)->verref == NULL)
       goto error_return;

      elf_tdata (abfd)->cverrefs = hdr->sh_info;

      contents = bfd_malloc (hdr->sh_size);
      if (contents == NULL)
       {
error_return_verref:
         elf_tdata (abfd)->verref = NULL;
         elf_tdata (abfd)->cverrefs = 0;
         goto error_return;
       }
      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
         || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
       goto error_return_verref;

      if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
       goto error_return_verref;

      BFD_ASSERT (sizeof (Elf_External_Verneed)
                == sizeof (Elf_External_Vernaux));
      contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
      everneed = (Elf_External_Verneed *) contents;
      iverneed = elf_tdata (abfd)->verref;
      for (i = 0; i < hdr->sh_info; i++, iverneed++)
       {
         Elf_External_Vernaux *evernaux;
         Elf_Internal_Vernaux *ivernaux;
         unsigned int j;

         _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);

         iverneed->vn_bfd = abfd;

         iverneed->vn_filename =
           bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
                                        iverneed->vn_file);
         if (iverneed->vn_filename == NULL)
           goto error_return_verref;

         if (iverneed->vn_cnt == 0)
           iverneed->vn_auxptr = NULL;
         else
           {
             iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt,
                                          sizeof (Elf_Internal_Vernaux));
             if (iverneed->vn_auxptr == NULL)
              goto error_return_verref;
           }

         if (iverneed->vn_aux
             > (size_t) (contents_end - (bfd_byte *) everneed))
           goto error_return_verref;

         evernaux = ((Elf_External_Vernaux *)
                    ((bfd_byte *) everneed + iverneed->vn_aux));
         ivernaux = iverneed->vn_auxptr;
         for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
           {
             _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);

             ivernaux->vna_nodename =
              bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
                                           ivernaux->vna_name);
             if (ivernaux->vna_nodename == NULL)
              goto error_return_verref;

             if (j + 1 < iverneed->vn_cnt)
              ivernaux->vna_nextptr = ivernaux + 1;
             else
              ivernaux->vna_nextptr = NULL;

             if (ivernaux->vna_next
                > (size_t) (contents_end - (bfd_byte *) evernaux))
              goto error_return_verref;

             evernaux = ((Elf_External_Vernaux *)
                       ((bfd_byte *) evernaux + ivernaux->vna_next));

             if (ivernaux->vna_other > freeidx)
              freeidx = ivernaux->vna_other;
           }

         if (i + 1 < hdr->sh_info)
           iverneed->vn_nextref = iverneed + 1;
         else
           iverneed->vn_nextref = NULL;

         if (iverneed->vn_next
             > (size_t) (contents_end - (bfd_byte *) everneed))
           goto error_return_verref;

         everneed = ((Elf_External_Verneed *)
                    ((bfd_byte *) everneed + iverneed->vn_next));
       }

      free (contents);
      contents = NULL;
    }

  if (elf_dynverdef (abfd) != 0)
    {
      Elf_Internal_Shdr *hdr;
      Elf_External_Verdef *everdef;
      Elf_Internal_Verdef *iverdef;
      Elf_Internal_Verdef *iverdefarr;
      Elf_Internal_Verdef iverdefmem;
      unsigned int i;
      unsigned int maxidx;
      bfd_byte *contents_end_def, *contents_end_aux;

      hdr = &elf_tdata (abfd)->dynverdef_hdr;

      contents = bfd_malloc (hdr->sh_size);
      if (contents == NULL)
       goto error_return;
      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
         || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
       goto error_return;

      if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
       goto error_return;

      BFD_ASSERT (sizeof (Elf_External_Verdef)
                >= sizeof (Elf_External_Verdaux));
      contents_end_def = contents + hdr->sh_size
                      - sizeof (Elf_External_Verdef);
      contents_end_aux = contents + hdr->sh_size
                      - sizeof (Elf_External_Verdaux);

      /* We know the number of entries in the section but not the maximum
        index.  Therefore we have to run through all entries and find
        the maximum.  */
      everdef = (Elf_External_Verdef *) contents;
      maxidx = 0;
      for (i = 0; i < hdr->sh_info; ++i)
       {
         _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);

         if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
           maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);

         if (iverdefmem.vd_next
             > (size_t) (contents_end_def - (bfd_byte *) everdef))
           goto error_return;

         everdef = ((Elf_External_Verdef *)
                   ((bfd_byte *) everdef + iverdefmem.vd_next));
       }

      if (default_imported_symver)
       {
         if (freeidx > maxidx)
           maxidx = ++freeidx;
         else
           freeidx = ++maxidx;
       }
      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx,
                                         sizeof (Elf_Internal_Verdef));
      if (elf_tdata (abfd)->verdef == NULL)
       goto error_return;

      elf_tdata (abfd)->cverdefs = maxidx;

      everdef = (Elf_External_Verdef *) contents;
      iverdefarr = elf_tdata (abfd)->verdef;
      for (i = 0; i < hdr->sh_info; i++)
       {
         Elf_External_Verdaux *everdaux;
         Elf_Internal_Verdaux *iverdaux;
         unsigned int j;

         _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);

         if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
           {
error_return_verdef:
             elf_tdata (abfd)->verdef = NULL;
             elf_tdata (abfd)->cverdefs = 0;
             goto error_return;
           }

         iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
         memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));

         iverdef->vd_bfd = abfd;

         if (iverdef->vd_cnt == 0)
           iverdef->vd_auxptr = NULL;
         else
           {
             iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt,
                                          sizeof (Elf_Internal_Verdaux));
             if (iverdef->vd_auxptr == NULL)
              goto error_return_verdef;
           }

         if (iverdef->vd_aux
             > (size_t) (contents_end_aux - (bfd_byte *) everdef))
           goto error_return_verdef;

         everdaux = ((Elf_External_Verdaux *)
                    ((bfd_byte *) everdef + iverdef->vd_aux));
         iverdaux = iverdef->vd_auxptr;
         for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
           {
             _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);

             iverdaux->vda_nodename =
              bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
                                           iverdaux->vda_name);
             if (iverdaux->vda_nodename == NULL)
              goto error_return_verdef;

             if (j + 1 < iverdef->vd_cnt)
              iverdaux->vda_nextptr = iverdaux + 1;
             else
              iverdaux->vda_nextptr = NULL;

             if (iverdaux->vda_next
                > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
              goto error_return_verdef;

             everdaux = ((Elf_External_Verdaux *)
                       ((bfd_byte *) everdaux + iverdaux->vda_next));
           }

         if (iverdef->vd_cnt)
           iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;

         if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
           iverdef->vd_nextdef = iverdef + 1;
         else
           iverdef->vd_nextdef = NULL;

         everdef = ((Elf_External_Verdef *)
                   ((bfd_byte *) everdef + iverdef->vd_next));
       }

      free (contents);
      contents = NULL;
    }
  else if (default_imported_symver)
    {
      if (freeidx < 3)
       freeidx = 3;
      else
       freeidx++;

      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx,
                                         sizeof (Elf_Internal_Verdef));
      if (elf_tdata (abfd)->verdef == NULL)
       goto error_return;

      elf_tdata (abfd)->cverdefs = freeidx;
    }

  /* Create a default version based on the soname.  */
  if (default_imported_symver)
    {
      Elf_Internal_Verdef *iverdef;
      Elf_Internal_Verdaux *iverdaux;

      iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];;

      iverdef->vd_version = VER_DEF_CURRENT;
      iverdef->vd_flags = 0;
      iverdef->vd_ndx = freeidx;
      iverdef->vd_cnt = 1;

      iverdef->vd_bfd = abfd;

      iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
      if (iverdef->vd_nodename == NULL)
       goto error_return_verdef;
      iverdef->vd_nextdef = NULL;
      iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
      if (iverdef->vd_auxptr == NULL)
       goto error_return_verdef;

      iverdaux = iverdef->vd_auxptr;
      iverdaux->vda_nodename = iverdef->vd_nodename;
      iverdaux->vda_nextptr = NULL;
    }

  return TRUE;

 error_return:
  if (contents != NULL)
    free (contents);
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _bfd_elf_sprintf_vma ( bfd *abfd  ATTRIBUTE_UNUSED,
char *  buf,
bfd_vma  value 
)

Definition at line 8549 of file elf.c.

{
#ifdef BFD64
  Elf_Internal_Ehdr *i_ehdrp;      /* Elf file header, internal form */

  i_ehdrp = elf_elfheader (abfd);
  if (i_ehdrp == NULL)
    sprintf_vma (buf, value);
  else
    {
      if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
       {
#if BFD_HOST_64BIT_LONG
         sprintf (buf, "%016lx", value);
#else
         sprintf (buf, "%08lx%08lx", _bfd_int64_high (value),
                 _bfd_int64_low (value));
#endif
       }
      else
       sprintf (buf, "%08lx", (unsigned long) (value & 0xffffffff));
    }
#else
  sprintf_vma (buf, value);
#endif
}

Definition at line 1803 of file elf.c.

{
  struct bfd_strtab_hash *ret;

  ret = _bfd_stringtab_init ();
  if (ret != NULL)
    {
      bfd_size_type loc;

      loc = _bfd_stringtab_add (ret, "", TRUE, FALSE);
      BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1);
      if (loc == (bfd_size_type) -1)
       {
         _bfd_stringtab_free (ret);
         ret = NULL;
       }
    }
  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 89 of file elf.c.

{
  dst->vda_name = H_GET_32 (abfd, src->vda_name);
  dst->vda_next = H_GET_32 (abfd, src->vda_next);
}

Here is the caller graph for this function:

Definition at line 100 of file elf.c.

{
  H_PUT_32 (abfd, src->vda_name, dst->vda_name);
  H_PUT_32 (abfd, src->vda_next, dst->vda_next);
}

Here is the caller graph for this function:

Definition at line 57 of file elf.c.

{
  dst->vd_version = H_GET_16 (abfd, src->vd_version);
  dst->vd_flags   = H_GET_16 (abfd, src->vd_flags);
  dst->vd_ndx     = H_GET_16 (abfd, src->vd_ndx);
  dst->vd_cnt     = H_GET_16 (abfd, src->vd_cnt);
  dst->vd_hash    = H_GET_32 (abfd, src->vd_hash);
  dst->vd_aux     = H_GET_32 (abfd, src->vd_aux);
  dst->vd_next    = H_GET_32 (abfd, src->vd_next);
}

Here is the caller graph for this function:

Definition at line 73 of file elf.c.

{
  H_PUT_16 (abfd, src->vd_version, dst->vd_version);
  H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
  H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
  H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
  H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
  H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
  H_PUT_32 (abfd, src->vd_next, dst->vd_next);
}

Here is the caller graph for this function:

Definition at line 139 of file elf.c.

{
  dst->vna_hash  = H_GET_32 (abfd, src->vna_hash);
  dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
  dst->vna_other = H_GET_16 (abfd, src->vna_other);
  dst->vna_name  = H_GET_32 (abfd, src->vna_name);
  dst->vna_next  = H_GET_32 (abfd, src->vna_next);
}

Here is the caller graph for this function:

Definition at line 153 of file elf.c.

{
  H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
  H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
  H_PUT_16 (abfd, src->vna_other, dst->vna_other);
  H_PUT_32 (abfd, src->vna_name, dst->vna_name);
  H_PUT_32 (abfd, src->vna_next, dst->vna_next);
}

Here is the caller graph for this function:

Definition at line 111 of file elf.c.

{
  dst->vn_version = H_GET_16 (abfd, src->vn_version);
  dst->vn_cnt     = H_GET_16 (abfd, src->vn_cnt);
  dst->vn_file    = H_GET_32 (abfd, src->vn_file);
  dst->vn_aux     = H_GET_32 (abfd, src->vn_aux);
  dst->vn_next    = H_GET_32 (abfd, src->vn_next);
}

Here is the caller graph for this function:

Definition at line 125 of file elf.c.

{
  H_PUT_16 (abfd, src->vn_version, dst->vn_version);
  H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
  H_PUT_32 (abfd, src->vn_file, dst->vn_file);
  H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
  H_PUT_32 (abfd, src->vn_next, dst->vn_next);
}

Here is the caller graph for this function:

void _bfd_elf_swap_versym_in ( bfd abfd,
const Elf_External_Versym *  src,
Elf_Internal_Versym dst 
)

Definition at line 167 of file elf.c.

{
  dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
}

Here is the caller graph for this function:

void _bfd_elf_swap_versym_out ( bfd abfd,
const Elf_Internal_Versym src,
Elf_External_Versym *  dst 
)

Definition at line 177 of file elf.c.

{
  H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
}

Here is the caller graph for this function:

int _bfd_elf_symbol_from_bfd_symbol ( bfd abfd,
asymbol **  asym_ptr_ptr 
)

Definition at line 5152 of file elf.c.

{
  asymbol *asym_ptr = *asym_ptr_ptr;
  int idx;
  flagword flags = asym_ptr->flags;

  /* When gas creates relocations against local labels, it creates its
     own symbol for the section, but does put the symbol into the
     symbol chain, so udata is 0.  When the linker is generating
     relocatable output, this section symbol may be for one of the
     input sections rather than the output section.  */
  if (asym_ptr->udata.i == 0
      && (flags & BSF_SECTION_SYM)
      && asym_ptr->section)
    {
      asection *sec;
      int indx;

      sec = asym_ptr->section;
      if (sec->owner != abfd && sec->output_section != NULL)
       sec = sec->output_section;
      if (sec->owner == abfd
         && (indx = sec->index) < elf_num_section_syms (abfd)
         && elf_section_syms (abfd)[indx] != NULL)
       asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
    }

  idx = asym_ptr->udata.i;

  if (idx == 0)
    {
      /* This case can occur when using --strip-symbol on a symbol
         which is used in a relocation entry.  */
      (*_bfd_error_handler)
       (_("%B: symbol `%s' required but not present"),
        abfd, bfd_asymbol_name (asym_ptr));
      bfd_set_error (bfd_error_no_symbols);
      return -1;
    }

#if DEBUG & 4
  {
    fprintf (stderr,
            "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n",
            (long) asym_ptr, asym_ptr->name, idx, flags,
            elf_symbol_flags (flags));
    fflush (stderr);
  }
#endif

  return idx;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_elf_validate_reloc ( bfd abfd,
arelent areloc 
)

Definition at line 7294 of file elf.c.

{
  /* Check whether we really have an ELF howto.  */

  if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
    {
      bfd_reloc_code_real_type code;
      reloc_howto_type *howto;

      /* Alien reloc: Try to determine its type to replace it with an
        equivalent ELF reloc.  */

      if (areloc->howto->pc_relative)
       {
         switch (areloc->howto->bitsize)
           {
           case 8:
             code = BFD_RELOC_8_PCREL;
             break;
           case 12:
             code = BFD_RELOC_12_PCREL;
             break;
           case 16:
             code = BFD_RELOC_16_PCREL;
             break;
           case 24:
             code = BFD_RELOC_24_PCREL;
             break;
           case 32:
             code = BFD_RELOC_32_PCREL;
             break;
           case 64:
             code = BFD_RELOC_64_PCREL;
             break;
           default:
             goto fail;
           }

         howto = bfd_reloc_type_lookup (abfd, code);

         if (areloc->howto->pcrel_offset != howto->pcrel_offset)
           {
             if (howto->pcrel_offset)
              areloc->addend += areloc->address;
             else
              areloc->addend -= areloc->address; /* addend is unsigned!! */
           }
       }
      else
       {
         switch (areloc->howto->bitsize)
           {
           case 8:
             code = BFD_RELOC_8;
             break;
           case 14:
             code = BFD_RELOC_14;
             break;
           case 16:
             code = BFD_RELOC_16;
             break;
           case 26:
             code = BFD_RELOC_26;
             break;
           case 32:
             code = BFD_RELOC_32;
             break;
           case 64:
             code = BFD_RELOC_64;
             break;
           default:
             goto fail;
           }

         howto = bfd_reloc_type_lookup (abfd, code);
       }

      if (howto)
       areloc->howto = howto;
      else
       goto fail;
    }

  return TRUE;

 fail:
  (*_bfd_error_handler)
    (_("%B: unsupported relocation type %s"),
     abfd, areloc->howto->name);
  bfd_set_error (bfd_error_bad_value);
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5106 of file elf.c.

{
  /* Hopefully this can be done just like an object file.  */
  return _bfd_elf_write_object_contents (abfd);
}

Here is the call graph for this function:

Definition at line 5052 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  Elf_Internal_Ehdr *i_ehdrp;
  Elf_Internal_Shdr **i_shdrp;
  bfd_boolean failed;
  unsigned int count, num_sec;

  if (! abfd->output_has_begun
      && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
    return FALSE;

  i_shdrp = elf_elfsections (abfd);
  i_ehdrp = elf_elfheader (abfd);

  failed = FALSE;
  bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
  if (failed)
    return FALSE;

  _bfd_elf_assign_file_positions_for_relocs (abfd);

  /* After writing the headers, we need to write the sections too...  */
  num_sec = elf_numsections (abfd);
  for (count = 1; count < num_sec; count++)
    {
      if (bed->elf_backend_section_processing)
       (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
      if (i_shdrp[count]->contents)
       {
         bfd_size_type amt = i_shdrp[count]->sh_size;

         if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
             || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
           return FALSE;
       }
      if (count == SHN_LORESERVE - 1)
       count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
    }

  /* Write out the section header names.  */
  if (elf_shstrtab (abfd) != NULL
      && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
          || ! _bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
    return FALSE;

  if (bed->elf_backend_final_write_processing)
    (*bed->elf_backend_final_write_processing) (abfd,
                                          elf_tdata (abfd)->linker);

  return bed->s->write_shdrs_and_ehdr (abfd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_elfcore_make_pseudosection ( bfd abfd,
char *  name,
size_t  size,
ufile_ptr  filepos 
)

Definition at line 7464 of file elf.c.

{
  char buf[100];
  char *threaded_name;
  size_t len;
  asection *sect;

  /* Build the section name.  */

  sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
  len = strlen (buf) + 1;
  threaded_name = bfd_alloc (abfd, len);
  if (threaded_name == NULL)
    return FALSE;
  memcpy (threaded_name, buf, len);

  sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
                                        SEC_HAS_CONTENTS);
  if (sect == NULL)
    return FALSE;
  sect->size = size;
  sect->filepos = filepos;
  sect->alignment_power = 2;

  return elfcore_maybe_make_sect (abfd, name, sect);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* _bfd_elfcore_strndup ( bfd abfd,
char *  start,
size_t  max 
)

Definition at line 7621 of file elf.c.

{
  char *dups;
  char *end = memchr (start, '\0', max);
  size_t len;

  if (end == NULL)
    len = max;
  else
    len = end - start;

  dups = bfd_alloc (abfd, len + 1);
  if (dups == NULL)
    return NULL;

  memcpy (dups, start, len);
  dups[len] = '\0';

  return dups;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static file_ptr align_file_position ( file_ptr  off,
int  align 
) [inline, static]

Definition at line 3486 of file elf.c.

{
  return (off + align - 1) & ~(align - 1);
}

Here is the caller graph for this function:

static bfd_boolean assign_file_positions_except_relocs ( bfd abfd,
struct bfd_link_info link_info 
) [static]

Definition at line 4850 of file elf.c.

{
  struct elf_obj_tdata *tdata = elf_tdata (abfd);
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
  file_ptr off;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
      && bfd_get_format (abfd) != bfd_core)
    {
      Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
      unsigned int num_sec = elf_numsections (abfd);
      Elf_Internal_Shdr **hdrpp;
      unsigned int i;

      /* Start after the ELF header.  */
      off = i_ehdrp->e_ehsize;

      /* We are not creating an executable, which means that we are
        not creating a program header, and that the actual order of
        the sections in the file is unimportant.  */
      for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
       {
         Elf_Internal_Shdr *hdr;

         hdr = *hdrpp;
         if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
              && hdr->bfd_section == NULL)
             || i == tdata->symtab_section
             || i == tdata->symtab_shndx_section
             || i == tdata->strtab_section)
           {
             hdr->sh_offset = -1;
           }
         else
           off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);

         if (i == SHN_LORESERVE - 1)
           {
             i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
             hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
           }
       }
    }
  else
    {
      unsigned int alloc;

      /* Assign file positions for the loaded sections based on the
         assignment of sections to segments.  */
      if (!assign_file_positions_for_load_sections (abfd, link_info))
       return FALSE;

      /* And for non-load sections.  */
      if (!assign_file_positions_for_non_load_sections (abfd, link_info))
       return FALSE;

      if (bed->elf_backend_modify_program_headers != NULL)
       {
         if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
           return FALSE;
       }

      /* Write out the program headers.  */
      alloc = tdata->program_header_size / bed->s->sizeof_phdr;
      if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
         || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
       return FALSE;

      off = tdata->next_file_pos;
    }

  /* Place the section headers.  */
  off = align_file_position (off, 1 << bed->s->log_file_align);
  i_ehdrp->e_shoff = off;
  off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;

  tdata->next_file_pos = off;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean assign_file_positions_for_load_sections ( bfd abfd,
struct bfd_link_info link_info 
) [static]

Definition at line 4263 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct elf_segment_map *m;
  Elf_Internal_Phdr *phdrs;
  Elf_Internal_Phdr *p;
  file_ptr off, voff;
  bfd_size_type maxpagesize;
  unsigned int alloc;
  unsigned int i, j;

  if (link_info == NULL
      && !elf_modify_segment_map (abfd, link_info))
    return FALSE;

  alloc = 0;
  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
    ++alloc;

  elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
  elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
  elf_elfheader (abfd)->e_phnum = alloc;

  if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1)
    elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr;
  else
    BFD_ASSERT (elf_tdata (abfd)->program_header_size
              >= alloc * bed->s->sizeof_phdr);

  if (alloc == 0)
    {
      elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr;
      return TRUE;
    }

  phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
  elf_tdata (abfd)->phdr = phdrs;
  if (phdrs == NULL)
    return FALSE;

  maxpagesize = 1;
  if ((abfd->flags & D_PAGED) != 0)
    maxpagesize = bed->maxpagesize;

  off = bed->s->sizeof_ehdr;
  off += alloc * bed->s->sizeof_phdr;

  for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
       m != NULL;
       m = m->next, p++, j++)
    {
      asection **secpp;

      /* If elf_segment_map is not from map_sections_to_segments, the
         sections may not be correctly ordered.  NOTE: sorting should
        not be done to the PT_NOTE section of a corefile, which may
        contain several pseudo-sections artificially created by bfd.
        Sorting these pseudo-sections breaks things badly.  */
      if (m->count > 1
         && !(elf_elfheader (abfd)->e_type == ET_CORE
              && m->p_type == PT_NOTE))
       qsort (m->sections, (size_t) m->count, sizeof (asection *),
              elf_sort_sections);

      /* An ELF segment (described by Elf_Internal_Phdr) may contain a
        number of sections with contents contributing to both p_filesz
        and p_memsz, followed by a number of sections with no contents
        that just contribute to p_memsz.  In this loop, OFF tracks next
        available file offset for PT_LOAD and PT_NOTE segments.  VOFF is
        an adjustment we use for segments that have no file contents
        but need zero filled memory allocation.  */
      voff = 0;
      p->p_type = m->p_type;
      p->p_flags = m->p_flags;

      if (m->count == 0)
       p->p_vaddr = 0;
      else
       p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset;

      if (m->p_paddr_valid)
       p->p_paddr = m->p_paddr;
      else if (m->count == 0)
       p->p_paddr = 0;
      else
       p->p_paddr = m->sections[0]->lma;

      if (p->p_type == PT_LOAD
         && (abfd->flags & D_PAGED) != 0)
       {
         /* p_align in demand paged PT_LOAD segments effectively stores
            the maximum page size.  When copying an executable with
            objcopy, we set m->p_align from the input file.  Use this
            value for maxpagesize rather than bed->maxpagesize, which
            may be different.  Note that we use maxpagesize for PT_TLS
            segment alignment later in this function, so we are relying
            on at least one PT_LOAD segment appearing before a PT_TLS
            segment.  */
         if (m->p_align_valid)
           maxpagesize = m->p_align;

         p->p_align = maxpagesize;
       }
      else if (m->count == 0)
       p->p_align = 1 << bed->s->log_file_align;
      else if (m->p_align_valid)
       p->p_align = m->p_align;
      else
       p->p_align = 0;

      if (p->p_type == PT_LOAD
         && m->count > 0)
       {
         bfd_size_type align;
         bfd_vma adjust;
         unsigned int align_power = 0;

         if (m->p_align_valid)
           align = p->p_align;
         else
           {
             for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
              {
                unsigned int secalign;
                
                secalign = bfd_get_section_alignment (abfd, *secpp);
                if (secalign > align_power)
                  align_power = secalign;
              }
             align = (bfd_size_type) 1 << align_power;
             if (align < maxpagesize)
              align = maxpagesize;
           }

         adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
         off += adjust;
         if (adjust != 0
             && !m->includes_filehdr
             && !m->includes_phdrs
             && (ufile_ptr) off >= align)
           {
             /* If the first section isn't loadable, the same holds for
               any other sections.  Since the segment won't need file
               space, we can make p_offset overlap some prior segment.
               However, .tbss is special.  If a segment starts with
               .tbss, we need to look at the next section to decide
               whether the segment has any loadable sections.  */
             i = 0;
             while ((m->sections[i]->flags & SEC_LOAD) == 0
                   && (m->sections[i]->flags & SEC_HAS_CONTENTS) == 0)
              {
                if ((m->sections[i]->flags & SEC_THREAD_LOCAL) == 0
                    || ++i >= m->count)
                  {
                    off -= adjust;
                    voff = adjust - align;
                    break;
                  }
              }
           }
       }
      /* Make sure the .dynamic section is the first section in the
        PT_DYNAMIC segment.  */
      else if (p->p_type == PT_DYNAMIC
              && m->count > 1
              && strcmp (m->sections[0]->name, ".dynamic") != 0)
       {
         _bfd_error_handler
           (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
            abfd);
         bfd_set_error (bfd_error_bad_value);
         return FALSE;
       }

      p->p_offset = 0;
      p->p_filesz = 0;
      p->p_memsz = 0;

      if (m->includes_filehdr)
       {
         if (! m->p_flags_valid)
           p->p_flags |= PF_R;
         p->p_filesz = bed->s->sizeof_ehdr;
         p->p_memsz = bed->s->sizeof_ehdr;
         if (m->count > 0)
           {
             BFD_ASSERT (p->p_type == PT_LOAD);

             if (p->p_vaddr < (bfd_vma) off)
              {
                (*_bfd_error_handler)
                  (_("%B: Not enough room for program headers, try linking with -N"),
                   abfd);
                bfd_set_error (bfd_error_bad_value);
                return FALSE;
              }

             p->p_vaddr -= off;
             if (! m->p_paddr_valid)
              p->p_paddr -= off;
           }
       }

      if (m->includes_phdrs)
       {
         if (! m->p_flags_valid)
           p->p_flags |= PF_R;

         if (!m->includes_filehdr)
           {
             p->p_offset = bed->s->sizeof_ehdr;

             if (m->count > 0)
              {
                BFD_ASSERT (p->p_type == PT_LOAD);
                p->p_vaddr -= off - p->p_offset;
                if (! m->p_paddr_valid)
                  p->p_paddr -= off - p->p_offset;
              }
           }

         p->p_filesz += alloc * bed->s->sizeof_phdr;
         p->p_memsz += alloc * bed->s->sizeof_phdr;
       }

      if (p->p_type == PT_LOAD
         || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
       {
         if (! m->includes_filehdr && ! m->includes_phdrs)
           p->p_offset = off + voff;
         else
           {
             file_ptr adjust;

             adjust = off - (p->p_offset + p->p_filesz);
             p->p_filesz += adjust;
             p->p_memsz += adjust;
           }
       }

      /* Set up p_filesz, p_memsz, p_align and p_flags from the section
        maps.  Set filepos for sections in PT_LOAD segments, and in
        core files, for sections in PT_NOTE segments.
        assign_file_positions_for_non_load_sections will set filepos
        for other sections and update p_filesz for other segments.  */
      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
       {
         asection *sec;
         flagword flags;
         bfd_size_type align;

         sec = *secpp;
         flags = sec->flags;
         align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);

         if (p->p_type == PT_LOAD
             || p->p_type == PT_TLS)
           {
             bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_filesz);

             if ((flags & SEC_LOAD) != 0
                || ((flags & SEC_ALLOC) != 0
                    && ((flags & SEC_THREAD_LOCAL) == 0
                       || p->p_type == PT_TLS)))
              {
                if (adjust < 0)
                  {
                    (*_bfd_error_handler)
                     (_("%B: section %A lma 0x%lx overlaps previous sections"),
                      abfd, sec, (unsigned long) sec->lma);
                    adjust = 0;
                  }
                p->p_memsz += adjust;

                if ((flags & SEC_LOAD) != 0)
                  {
                    off += adjust;
                    p->p_filesz += adjust;
                  }
              }
           }

         if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
           {
             /* The section at i == 0 is the one that actually contains
               everything.  */
             if (i == 0)
              {
                sec->filepos = off;
                off += sec->size;
                p->p_filesz = sec->size;
                p->p_memsz = 0;
                p->p_align = 1;
              }
             else
              {
                /* The rest are fake sections that shouldn't be written.  */
                sec->filepos = 0;
                sec->size = 0;
                sec->flags = 0;
                continue;
              }
           }
         else
           {
             if (p->p_type == PT_LOAD)
              {
                sec->filepos = off + voff;
                /* FIXME: The SEC_HAS_CONTENTS test here dates back to
                   1997, and the exact reason for it isn't clear.  One
                   plausible explanation is that it is to work around
                   a problem we have with linker scripts using data
                   statements in NOLOAD sections.  I don't think it
                   makes a great deal of sense to have such a section
                   assigned to a PT_LOAD segment, but apparently
                   people do this.  The data statement results in a
                   bfd_data_link_order being built, and these need
                   section contents to write into.  Eventually, we get
                   to _bfd_elf_write_object_contents which writes any
                   section with contents to the output.  Make room
                   here for the write, so that following segments are
                   not trashed.  */
                if ((flags & SEC_LOAD) != 0
                    || (flags & SEC_HAS_CONTENTS) != 0)
                  off += sec->size;
              }

             if ((flags & SEC_LOAD) != 0)
              {
                p->p_filesz += sec->size;
                p->p_memsz += sec->size;
              }

             /* .tbss is special.  It doesn't contribute to p_memsz of
               normal segments.  */
             else if ((flags & SEC_ALLOC) != 0
                     && ((flags & SEC_THREAD_LOCAL) == 0
                        || p->p_type == PT_TLS))
              p->p_memsz += sec->size;

             if (p->p_type == PT_TLS
                && sec->size == 0
                && (sec->flags & SEC_HAS_CONTENTS) == 0)
              {
                struct bfd_link_order *o = sec->map_tail.link_order;
                if (o != NULL)
                  p->p_memsz += o->offset + o->size;
              }

             if (p->p_type == PT_GNU_RELRO)
              p->p_align = 1;
             else if (align > p->p_align
                     && !m->p_align_valid
                     && (p->p_type != PT_LOAD
                        || (abfd->flags & D_PAGED) == 0))
              p->p_align = align;
           }

         if (! m->p_flags_valid)
           {
             p->p_flags |= PF_R;
             if ((flags & SEC_CODE) != 0)
              p->p_flags |= PF_X;
             if ((flags & SEC_READONLY) == 0)
              p->p_flags |= PF_W;
           }
       }

      /* Check if all sections are in the segment.  Skip PT_GNU_RELRO
        and PT_NOTE segments since they will be processed by
        assign_file_positions_for_non_load_sections later.  */
      if (p->p_type != PT_GNU_RELRO
         && p->p_type != PT_NOTE)
       for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
         {
           Elf_Internal_Shdr *this_hdr;
           asection *sec;

           sec = *secpp;
           this_hdr = &(elf_section_data(sec)->this_hdr);
           if (this_hdr->sh_size != 0
              && !ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, p))
             {
              (*_bfd_error_handler)
                (_("%B: section `%A' can't be allocated in segment %d"),
                 abfd, sec, j);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
             }
         }
    }

  elf_tdata (abfd)->next_file_pos = off;
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean assign_file_positions_for_non_load_sections ( bfd abfd,
struct bfd_link_info link_info 
) [static]

Definition at line 4663 of file elf.c.

{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  Elf_Internal_Shdr **i_shdrpp;
  Elf_Internal_Shdr **hdrpp;
  Elf_Internal_Phdr *phdrs;
  Elf_Internal_Phdr *p;
  struct elf_segment_map *m;
  bfd_vma filehdr_vaddr, filehdr_paddr;
  bfd_vma phdrs_vaddr, phdrs_paddr;
  file_ptr off;
  unsigned int num_sec;
  unsigned int i;
  unsigned int count;

  i_shdrpp = elf_elfsections (abfd);
  num_sec = elf_numsections (abfd);
  off = elf_tdata (abfd)->next_file_pos;
  for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
    {
      struct elf_obj_tdata *tdata = elf_tdata (abfd);
      Elf_Internal_Shdr *hdr;

      hdr = *hdrpp;
      if (hdr->bfd_section != NULL
         && (hdr->bfd_section->filepos != 0
             || (hdr->sh_type == SHT_NOBITS
                && hdr->contents == NULL)))
       hdr->sh_offset = hdr->bfd_section->filepos;
      else if ((hdr->sh_flags & SHF_ALLOC) != 0)
       {
         if (hdr->sh_size != 0)
           ((*_bfd_error_handler)
            (_("%B: warning: allocated section `%s' not in segment"),
             abfd,
             (hdr->bfd_section == NULL
              ? "*unknown*"
              : hdr->bfd_section->name)));
         /* We don't need to page align empty sections.  */
         if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
           off += vma_page_aligned_bias (hdr->sh_addr, off,
                                     bed->maxpagesize);
         else
           off += vma_page_aligned_bias (hdr->sh_addr, off,
                                     hdr->sh_addralign);
         off = _bfd_elf_assign_file_position_for_section (hdr, off,
                                                    FALSE);
       }
      else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
              && hdr->bfd_section == NULL)
              || hdr == i_shdrpp[tdata->symtab_section]
              || hdr == i_shdrpp[tdata->symtab_shndx_section]
              || hdr == i_shdrpp[tdata->strtab_section])
       hdr->sh_offset = -1;
      else
       off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);

      if (i == SHN_LORESERVE - 1)
       {
         i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
         hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
       }
    }

  /* Now that we have set the section file positions, we can set up
     the file positions for the non PT_LOAD segments.  */
  count = 0;
  filehdr_vaddr = 0;
  filehdr_paddr = 0;
  phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
  phdrs_paddr = 0;
  phdrs = elf_tdata (abfd)->phdr;
  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
       m != NULL;
       m = m->next, p++)
    {
      ++count;
      if (p->p_type != PT_LOAD)
       continue;

      if (m->includes_filehdr)
       {
         filehdr_vaddr = p->p_vaddr;
         filehdr_paddr = p->p_paddr;
       }
      if (m->includes_phdrs)
       {
         phdrs_vaddr = p->p_vaddr;
         phdrs_paddr = p->p_paddr;
         if (m->includes_filehdr)
           {
             phdrs_vaddr += bed->s->sizeof_ehdr;
             phdrs_paddr += bed->s->sizeof_ehdr;
           }
       }
    }

  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
       m != NULL;
       m = m->next, p++)
    {
      if (m->count != 0)
       {
         if (p->p_type != PT_LOAD
             && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core))
           {
             Elf_Internal_Shdr *hdr;
             BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);

             hdr = &elf_section_data (m->sections[m->count - 1])->this_hdr;
             p->p_filesz = (m->sections[m->count - 1]->filepos
                          - m->sections[0]->filepos);
             if (hdr->sh_type != SHT_NOBITS)
              p->p_filesz += hdr->sh_size;

             p->p_offset = m->sections[0]->filepos;
           }
       }
      else
       {
         if (m->includes_filehdr)
           {
             p->p_vaddr = filehdr_vaddr;
             if (! m->p_paddr_valid)
              p->p_paddr = filehdr_paddr;
           }
         else if (m->includes_phdrs)
           {
             p->p_vaddr = phdrs_vaddr;
             if (! m->p_paddr_valid)
              p->p_paddr = phdrs_paddr;
           }
         else if (p->p_type == PT_GNU_RELRO)
           {
             Elf_Internal_Phdr *lp;

             for (lp = phdrs; lp < phdrs + count; ++lp)
              {
                if (lp->p_type == PT_LOAD
                    && lp->p_vaddr <= link_info->relro_end
                    && lp->p_vaddr >= link_info->relro_start
                    && (lp->p_vaddr + lp->p_filesz
                       >= link_info->relro_end))
                  break;
              }

             if (lp < phdrs + count
                && link_info->relro_end > lp->p_vaddr)
              {
                p->p_vaddr = lp->p_vaddr;
                p->p_paddr = lp->p_paddr;
                p->p_offset = lp->p_offset;
                p->p_filesz = link_info->relro_end - lp->p_vaddr;
                p->p_memsz = p->p_filesz;
                p->p_align = 1;
                p->p_flags = (lp->p_flags & ~PF_W);
              }
             else
              {
                memset (p, 0, sizeof *p);
                p->p_type = PT_NULL;
              }
           }
       }
    }

  elf_tdata (abfd)->next_file_pos = off;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean assign_section_numbers ( bfd abfd,
struct bfd_link_info link_info 
) [static]

Definition at line 3003 of file elf.c.

{
  struct elf_obj_tdata *t = elf_tdata (abfd);
  asection *sec;
  unsigned int section_number, secn;
  Elf_Internal_Shdr **i_shdrp;
  struct bfd_elf_section_data *d;

  section_number = 1;

  _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));

  /* SHT_GROUP sections are in relocatable files only.  */
  if (link_info == NULL || link_info->relocatable)
    {
      /* Put SHT_GROUP sections first.  */
      for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
         d = elf_section_data (sec);

         if (d->this_hdr.sh_type == SHT_GROUP)
           { 
             if (sec->flags & SEC_LINKER_CREATED)
              {
                /* Remove the linker created SHT_GROUP sections.  */
                bfd_section_list_remove (abfd, sec);
                abfd->section_count--;
              }
             else 
              {
                if (section_number == SHN_LORESERVE)
                  section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
                d->this_idx = section_number++;
              }
           }
       }
    }

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      d = elf_section_data (sec);

      if (d->this_hdr.sh_type != SHT_GROUP)
       {
         if (section_number == SHN_LORESERVE)
           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
         d->this_idx = section_number++;
       }
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
      if ((sec->flags & SEC_RELOC) == 0)
       d->rel_idx = 0;
      else
       {
         if (section_number == SHN_LORESERVE)
           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
         d->rel_idx = section_number++;
         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
       }

      if (d->rel_hdr2)
       {
         if (section_number == SHN_LORESERVE)
           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
         d->rel_idx2 = section_number++;
         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
       }
      else
       d->rel_idx2 = 0;
    }

  if (section_number == SHN_LORESERVE)
    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
  t->shstrtab_section = section_number++;
  _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
  elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;

  if (bfd_get_symcount (abfd) > 0)
    {
      if (section_number == SHN_LORESERVE)
       section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
      t->symtab_section = section_number++;
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
      if (section_number > SHN_LORESERVE - 2)
       {
         if (section_number == SHN_LORESERVE)
           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
         t->symtab_shndx_section = section_number++;
         t->symtab_shndx_hdr.sh_name
           = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
                                            ".symtab_shndx", FALSE);
         if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
           return FALSE;
       }
      if (section_number == SHN_LORESERVE)
       section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
      t->strtab_section = section_number++;
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
    }

  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
  t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));

  elf_numsections (abfd) = section_number;
  elf_elfheader (abfd)->e_shnum = section_number;
  if (section_number > SHN_LORESERVE)
    elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;

  /* Set up the list of section header pointers, in agreement with the
     indices.  */
  i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *));
  if (i_shdrp == NULL)
    return FALSE;

  i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
  if (i_shdrp[0] == NULL)
    {
      bfd_release (abfd, i_shdrp);
      return FALSE;
    }

  elf_elfsections (abfd) = i_shdrp;

  i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
  if (bfd_get_symcount (abfd) > 0)
    {
      i_shdrp[t->symtab_section] = &t->symtab_hdr;
      if (elf_numsections (abfd) > SHN_LORESERVE)
       {
         i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
         t->symtab_shndx_hdr.sh_link = t->symtab_section;
       }
      i_shdrp[t->strtab_section] = &t->strtab_hdr;
      t->symtab_hdr.sh_link = t->strtab_section;
    }

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      struct bfd_elf_section_data *d = elf_section_data (sec);
      asection *s;
      const char *name;

      i_shdrp[d->this_idx] = &d->this_hdr;
      if (d->rel_idx != 0)
       i_shdrp[d->rel_idx] = &d->rel_hdr;
      if (d->rel_idx2 != 0)
       i_shdrp[d->rel_idx2] = d->rel_hdr2;

      /* Fill in the sh_link and sh_info fields while we're at it.  */

      /* sh_link of a reloc section is the section index of the symbol
        table.  sh_info is the section index of the section to which
        the relocation entries apply.  */
      if (d->rel_idx != 0)
       {
         d->rel_hdr.sh_link = t->symtab_section;
         d->rel_hdr.sh_info = d->this_idx;
       }
      if (d->rel_idx2 != 0)
       {
         d->rel_hdr2->sh_link = t->symtab_section;
         d->rel_hdr2->sh_info = d->this_idx;
       }

      /* We need to set up sh_link for SHF_LINK_ORDER.  */
      if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
       {
         s = elf_linked_to_section (sec);
         if (s)
           {
             /* elf_linked_to_section points to the input section.  */
             if (link_info != NULL)
              {
                /* Check discarded linkonce section.  */
                if (elf_discarded_section (s))
                  {
                    asection *kept;
                    (*_bfd_error_handler)
                     (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
                      abfd, d->this_hdr.bfd_section,
                      s, s->owner);
                    /* Point to the kept section if it has the same
                      size as the discarded one.  */
                    kept = _bfd_elf_check_kept_section (s, link_info);
                    if (kept == NULL)
                     {
                       bfd_set_error (bfd_error_bad_value);
                       return FALSE;
                     }
                    s = kept;
                  }

                s = s->output_section;
                BFD_ASSERT (s != NULL);
              }
             else
              {
                /* Handle objcopy. */
                if (s->output_section == NULL)
                  {
                    (*_bfd_error_handler)
                     (_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"),
                      abfd, d->this_hdr.bfd_section, s, s->owner);
                    bfd_set_error (bfd_error_bad_value);
                    return FALSE;
                  }
                s = s->output_section;
              }
             d->this_hdr.sh_link = elf_section_data (s)->this_idx;
           }
         else
           {
             /* PR 290:
               The Intel C compiler generates SHT_IA_64_UNWIND with
               SHF_LINK_ORDER.  But it doesn't set the sh_link or
               sh_info fields.  Hence we could get the situation
                where s is NULL.  */
             const struct elf_backend_data *bed
              = get_elf_backend_data (abfd);
             if (bed->link_order_error_handler)
              bed->link_order_error_handler
                (_("%B: warning: sh_link not set for section `%A'"),
                 abfd, sec);
           }
       }

      switch (d->this_hdr.sh_type)
       {
       case SHT_REL:
       case SHT_RELA:
         /* A reloc section which we are treating as a normal BFD
            section.  sh_link is the section index of the symbol
            table.  sh_info is the section index of the section to
            which the relocation entries apply.  We assume that an
            allocated reloc section uses the dynamic symbol table.
            FIXME: How can we be sure?  */
         s = bfd_get_section_by_name (abfd, ".dynsym");
         if (s != NULL)
           d->this_hdr.sh_link = elf_section_data (s)->this_idx;

         /* We look up the section the relocs apply to by name.  */
         name = sec->name;
         if (d->this_hdr.sh_type == SHT_REL)
           name += 4;
         else
           name += 5;
         s = bfd_get_section_by_name (abfd, name);
         if (s != NULL)
           d->this_hdr.sh_info = elf_section_data (s)->this_idx;
         break;

       case SHT_STRTAB:
         /* We assume that a section named .stab*str is a stabs
            string section.  We look for a section with the same name
            but without the trailing ``str'', and set its sh_link
            field to point to this section.  */
         if (CONST_STRNEQ (sec->name, ".stab")
             && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
           {
             size_t len;
             char *alc;

             len = strlen (sec->name);
             alc = bfd_malloc (len - 2);
             if (alc == NULL)
              return FALSE;
             memcpy (alc, sec->name, len - 3);
             alc[len - 3] = '\0';
             s = bfd_get_section_by_name (abfd, alc);
             free (alc);
             if (s != NULL)
              {
                elf_section_data (s)->this_hdr.sh_link = d->this_idx;

                /* This is a .stab section.  */
                if (elf_section_data (s)->this_hdr.sh_entsize == 0)
                  elf_section_data (s)->this_hdr.sh_entsize
                    = 4 + 2 * bfd_get_arch_size (abfd) / 8;
              }
           }
         break;

       case SHT_DYNAMIC:
       case SHT_DYNSYM:
       case SHT_GNU_verneed:
       case SHT_GNU_verdef:
         /* sh_link is the section header index of the string table
            used for the dynamic entries, or the symbol table, or the
            version strings.  */
         s = bfd_get_section_by_name (abfd, ".dynstr");
         if (s != NULL)
           d->this_hdr.sh_link = elf_section_data (s)->this_idx;
         break;

       case SHT_GNU_LIBLIST:
         /* sh_link is the section header index of the prelink library
            list 
            used for the dynamic entries, or the symbol table, or the
            version strings.  */
         s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC)
                                        ? ".dynstr" : ".gnu.libstr");
         if (s != NULL)
           d->this_hdr.sh_link = elf_section_data (s)->this_idx;
         break;

       case SHT_HASH:
       case SHT_GNU_HASH:
       case SHT_GNU_versym:
         /* sh_link is the section header index of the symbol table
            this hash table or version table is for.  */
         s = bfd_get_section_by_name (abfd, ".dynsym");
         if (s != NULL)
           d->this_hdr.sh_link = elf_section_data (s)->this_idx;
         break;

       case SHT_GROUP:
         d->this_hdr.sh_link = t->symtab_section;
       }
    }

  for (secn = 1; secn < section_number; ++secn)
    if (i_shdrp[secn] == NULL)
      i_shdrp[secn] = i_shdrp[0];
    else
      i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
                                                 i_shdrp[secn]->sh_name);
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd* bfd_elf_bfd_from_remote_memory ( bfd templ,
bfd_vma  ehdr_vma,
bfd_vma loadbasep,
int(*)(bfd_vma, bfd_byte *, int target_read_memory 
)
struct elf_internal_shdr* bfd_elf_find_section ( bfd abfd,
char *  name 
) [read]

Definition at line 979 of file elf.c.

{
  Elf_Internal_Shdr **i_shdrp;
  char *shstrtab;
  unsigned int max;
  unsigned int i;

  i_shdrp = elf_elfsections (abfd);
  if (i_shdrp != NULL)
    {
      shstrtab = bfd_elf_get_str_section (abfd,
                                     elf_elfheader (abfd)->e_shstrndx);
      if (shstrtab != NULL)
       {
         max = elf_numsections (abfd);
         for (i = 1; i < max; i++)
           if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
             return i_shdrp[i];
       }
    }
  return 0;
}

Here is the call graph for this function:

bfd_reloc_status_type bfd_elf_generic_reloc ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent reloc_entry,
asymbol symbol,
void *data  ATTRIBUTE_UNUSED,
asection input_section,
bfd output_bfd,
char **error_message  ATTRIBUTE_UNUSED 
)

Definition at line 1019 of file elf.c.

{
  if (output_bfd != NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (! reloc_entry->howto->partial_inplace
         || reloc_entry->addend == 0))
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  return bfd_reloc_continue;
}

Definition at line 1723 of file elf.c.

{
  asection *s;
  bfd_byte *dynbuf = NULL;
  int elfsec;
  unsigned long shlink;
  bfd_byte *extdyn, *extdynend;
  size_t extdynsize;
  void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);

  *pneeded = NULL;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
      || bfd_get_format (abfd) != bfd_object)
    return TRUE;

  s = bfd_get_section_by_name (abfd, ".dynamic");
  if (s == NULL || s->size == 0)
    return TRUE;

  if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
    goto error_return;

  elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
  if (elfsec == -1)
    goto error_return;

  shlink = elf_elfsections (abfd)[elfsec]->sh_link;

  extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
  swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;

  extdyn = dynbuf;
  extdynend = extdyn + s->size;
  for (; extdyn < extdynend; extdyn += extdynsize)
    {
      Elf_Internal_Dyn dyn;

      (*swap_dyn_in) (abfd, extdyn, &dyn);

      if (dyn.d_tag == DT_NULL)
       break;

      if (dyn.d_tag == DT_NEEDED)
       {
         const char *string;
         struct bfd_link_needed_list *l;
         unsigned int tagv = dyn.d_un.d_val;
         bfd_size_type amt;

         string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
         if (string == NULL)
           goto error_return;

         amt = sizeof *l;
         l = bfd_alloc (abfd, amt);
         if (l == NULL)
           goto error_return;

         l->by = abfd;
         l->name = string;
         l->next = *pneeded;
         *pneeded = l;
       }
    }

  free (dynbuf);

  return TRUE;

 error_return:
  if (dynbuf != NULL)
    free (dynbuf);
  return FALSE;
}

Here is the call graph for this function:

const char* bfd_elf_get_dt_soname ( bfd abfd)

Definition at line 1711 of file elf.c.

{
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
      && bfd_get_format (abfd) == bfd_object)
    return elf_dt_name (abfd);
  return NULL;
}

Here is the caller graph for this function:

Definition at line 1663 of file elf.c.

{
  int lib_class;
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
      && bfd_get_format (abfd) == bfd_object)
    lib_class = elf_dyn_lib_class (abfd);
  else
    lib_class = 0;
  return lib_class;
}
Elf_Internal_Sym* bfd_elf_get_elf_syms ( bfd ibfd,
Elf_Internal_Shdr symtab_hdr,
size_t  symcount,
size_t  symoffset,
Elf_Internal_Sym *  intsym_buf,
void *  extsym_buf,
Elf_External_Sym_Shndx extshndx_buf 
)

Definition at line 322 of file elf.c.

{
  Elf_Internal_Shdr *shndx_hdr;
  void *alloc_ext;
  const bfd_byte *esym;
  Elf_External_Sym_Shndx *alloc_extshndx;
  Elf_External_Sym_Shndx *shndx;
  Elf_Internal_Sym *isym;
  Elf_Internal_Sym *isymend;
  const struct elf_backend_data *bed;
  size_t extsym_size;
  bfd_size_type amt;
  file_ptr pos;

  if (symcount == 0)
    return intsym_buf;

  /* Normal syms might have section extension entries.  */
  shndx_hdr = NULL;
  if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
    shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;

  /* Read the symbols.  */
  alloc_ext = NULL;
  alloc_extshndx = NULL;
  bed = get_elf_backend_data (ibfd);
  extsym_size = bed->s->sizeof_sym;
  amt = symcount * extsym_size;
  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
  if (extsym_buf == NULL)
    {
      alloc_ext = bfd_malloc2 (symcount, extsym_size);
      extsym_buf = alloc_ext;
    }
  if (extsym_buf == NULL
      || bfd_seek (ibfd, pos, SEEK_SET) != 0
      || bfd_bread (extsym_buf, amt, ibfd) != amt)
    {
      intsym_buf = NULL;
      goto out;
    }

  if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
    extshndx_buf = NULL;
  else
    {
      amt = symcount * sizeof (Elf_External_Sym_Shndx);
      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
      if (extshndx_buf == NULL)
       {
         alloc_extshndx = bfd_malloc2 (symcount,
                                   sizeof (Elf_External_Sym_Shndx));
         extshndx_buf = alloc_extshndx;
       }
      if (extshndx_buf == NULL
         || bfd_seek (ibfd, pos, SEEK_SET) != 0
         || bfd_bread (extshndx_buf, amt, ibfd) != amt)
       {
         intsym_buf = NULL;
         goto out;
       }
    }

  if (intsym_buf == NULL)
    {
      intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
      if (intsym_buf == NULL)
       goto out;
    }

  /* Convert the symbols to internal form.  */
  isymend = intsym_buf + symcount;
  for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
       isym < isymend;
       esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
    if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
      {
       symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
       (*_bfd_error_handler) (_("%B symbol number %lu references "
                             "nonexistent SHT_SYMTAB_SHNDX section"),
                            ibfd, (unsigned long) symoffset);
       intsym_buf = NULL;
       goto out;
      }

 out:
  if (alloc_ext != NULL)
    free (alloc_ext);
  if (alloc_extshndx != NULL)
    free (alloc_extshndx);

  return intsym_buf;
}

Here is the call graph for this function:

struct bfd_link_needed_list* bfd_elf_get_needed_list ( bfd *abfd  ATTRIBUTE_UNUSED,
struct bfd_link_info info 
) [read]

Definition at line 1686 of file elf.c.

{
  if (! is_elf_hash_table (info->hash))
    return NULL;
  return elf_hash_table (info)->needed;
}
struct bfd_link_needed_list* bfd_elf_get_runpath_list ( bfd *abfd  ATTRIBUTE_UNUSED,
struct bfd_link_info info 
) [read]

Definition at line 1698 of file elf.c.

{
  if (! is_elf_hash_table (info->hash))
    return NULL;
  return elf_hash_table (info)->runpath;
}
char* bfd_elf_get_str_section ( bfd abfd,
unsigned int  shindex 
)

Definition at line 247 of file elf.c.

{
  Elf_Internal_Shdr **i_shdrp;
  bfd_byte *shstrtab = NULL;
  file_ptr offset;
  bfd_size_type shstrtabsize;

  i_shdrp = elf_elfsections (abfd);
  if (i_shdrp == 0 || i_shdrp[shindex] == 0)
    return NULL;

  shstrtab = i_shdrp[shindex]->contents;
  if (shstrtab == NULL)
    {
      /* No cached one, attempt to read, and cache what we read.  */
      offset = i_shdrp[shindex]->sh_offset;
      shstrtabsize = i_shdrp[shindex]->sh_size;

      /* Allocate and clear an extra byte at the end, to prevent crashes
        in case the string table is not terminated.  */
      if (shstrtabsize + 1 == 0
         || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL
         || bfd_seek (abfd, offset, SEEK_SET) != 0)
       shstrtab = NULL;
      else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
       {
         if (bfd_get_error () != bfd_error_system_call)
           bfd_set_error (bfd_error_file_truncated);
         shstrtab = NULL;
       }
      else
       shstrtab[shstrtabsize] = '\0';
      i_shdrp[shindex]->contents = shstrtab;
    }
  return (char *) shstrtab;
}

Here is the call graph for this function:

unsigned long bfd_elf_gnu_hash ( const char *  namearg)

Definition at line 213 of file elf.c.

{
  const unsigned char *name = (const unsigned char *) namearg;
  unsigned long h = 5381;
  unsigned char ch;

  while ((ch = *name++) != '\0')
    h = (h << 5) + h + ch;
  return h & 0xffffffff;
}

Here is the caller graph for this function:

unsigned long bfd_elf_hash ( const char *  namearg)

Definition at line 188 of file elf.c.

{
  const unsigned char *name = (const unsigned char *) namearg;
  unsigned long h = 0;
  unsigned long g;
  int ch;

  while ((ch = *name++) != '\0')
    {
      h = (h << 4) + ch;
      if ((g = (h & 0xf0000000)) != 0)
       {
         h ^= g >> 24;
         /* The ELF ABI says `h &= ~g', but this is equivalent in
            this case and on some machines one insn instead of two.  */
         h ^= g;
       }
    }
  return h & 0xffffffff;
}

Here is the caller graph for this function:

bfd_boolean bfd_elf_is_group_section ( bfd *abfd  ATTRIBUTE_UNUSED,
const asection sec 
)

Definition at line 761 of file elf.c.

{
  return elf_next_in_group (sec) != NULL;
}

Definition at line 8906 of file elf.c.

{
  bfd *bfd1, *bfd2;
  const struct elf_backend_data *bed1, *bed2;
  Elf_Internal_Shdr *hdr1, *hdr2;
  bfd_size_type symcount1, symcount2;
  Elf_Internal_Sym *isymbuf1, *isymbuf2;
  struct elf_symbuf_head *ssymbuf1, *ssymbuf2;
  Elf_Internal_Sym *isym, *isymend;
  struct elf_symbol *symtable1 = NULL, *symtable2 = NULL;
  bfd_size_type count1, count2, i;
  int shndx1, shndx2;
  bfd_boolean result;

  bfd1 = sec1->owner;
  bfd2 = sec2->owner;

  /* If both are .gnu.linkonce sections, they have to have the same
     section name.  */
  if (CONST_STRNEQ (sec1->name, ".gnu.linkonce")
      && CONST_STRNEQ (sec2->name, ".gnu.linkonce"))
    return strcmp (sec1->name + sizeof ".gnu.linkonce",
                 sec2->name + sizeof ".gnu.linkonce") == 0;

  /* Both sections have to be in ELF.  */
  if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour
      || bfd_get_flavour (bfd2) != bfd_target_elf_flavour)
    return FALSE;

  if (elf_section_type (sec1) != elf_section_type (sec2))
    return FALSE;

  if ((elf_section_flags (sec1) & SHF_GROUP) != 0
      && (elf_section_flags (sec2) & SHF_GROUP) != 0)
    {
      /* If both are members of section groups, they have to have the
        same group name.  */
      if (strcmp (elf_group_name (sec1), elf_group_name (sec2)) != 0)
       return FALSE;
    }

  shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1);
  shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2);
  if (shndx1 == -1 || shndx2 == -1)
    return FALSE;

  bed1 = get_elf_backend_data (bfd1);
  bed2 = get_elf_backend_data (bfd2);
  hdr1 = &elf_tdata (bfd1)->symtab_hdr;
  symcount1 = hdr1->sh_size / bed1->s->sizeof_sym;
  hdr2 = &elf_tdata (bfd2)->symtab_hdr;
  symcount2 = hdr2->sh_size / bed2->s->sizeof_sym;

  if (symcount1 == 0 || symcount2 == 0)
    return FALSE;

  result = FALSE;
  isymbuf1 = NULL;
  isymbuf2 = NULL;
  ssymbuf1 = elf_tdata (bfd1)->symbuf;
  ssymbuf2 = elf_tdata (bfd2)->symbuf;

  if (ssymbuf1 == NULL)
    {
      isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0,
                                   NULL, NULL, NULL);
      if (isymbuf1 == NULL)
       goto done;

      if (!info->reduce_memory_overheads)
       elf_tdata (bfd1)->symbuf = ssymbuf1
         = elf_create_symbuf (symcount1, isymbuf1);
    }

  if (ssymbuf1 == NULL || ssymbuf2 == NULL)
    {
      isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0,
                                   NULL, NULL, NULL);
      if (isymbuf2 == NULL)
       goto done;

      if (ssymbuf1 != NULL && !info->reduce_memory_overheads)
       elf_tdata (bfd2)->symbuf = ssymbuf2
         = elf_create_symbuf (symcount2, isymbuf2);
    }

  if (ssymbuf1 != NULL && ssymbuf2 != NULL)
    {
      /* Optimized faster version.  */
      bfd_size_type lo, hi, mid;
      struct elf_symbol *symp;
      struct elf_symbuf_symbol *ssym, *ssymend;

      lo = 0;
      hi = ssymbuf1->count;
      ssymbuf1++;
      count1 = 0;
      while (lo < hi)
       {
         mid = (lo + hi) / 2;
         if ((unsigned int) shndx1 < ssymbuf1[mid].st_shndx)
           hi = mid;
         else if ((unsigned int) shndx1 > ssymbuf1[mid].st_shndx)
           lo = mid + 1;
         else
           {
             count1 = ssymbuf1[mid].count;
             ssymbuf1 += mid;
             break;
           }
       }

      lo = 0;
      hi = ssymbuf2->count;
      ssymbuf2++;
      count2 = 0;
      while (lo < hi)
       {
         mid = (lo + hi) / 2;
         if ((unsigned int) shndx2 < ssymbuf2[mid].st_shndx)
           hi = mid;
         else if ((unsigned int) shndx2 > ssymbuf2[mid].st_shndx)
           lo = mid + 1;
         else
           {
             count2 = ssymbuf2[mid].count;
             ssymbuf2 += mid;
             break;
           }
       }

      if (count1 == 0 || count2 == 0 || count1 != count2)
       goto done;

      symtable1 = bfd_malloc (count1 * sizeof (struct elf_symbol));
      symtable2 = bfd_malloc (count2 * sizeof (struct elf_symbol));
      if (symtable1 == NULL || symtable2 == NULL)
       goto done;

      symp = symtable1;
      for (ssym = ssymbuf1->ssym, ssymend = ssym + count1;
          ssym < ssymend; ssym++, symp++)
       {
         symp->u.ssym = ssym;
         symp->name = bfd_elf_string_from_elf_section (bfd1,
                                                 hdr1->sh_link,
                                                 ssym->st_name);
       }

      symp = symtable2;
      for (ssym = ssymbuf2->ssym, ssymend = ssym + count2;
          ssym < ssymend; ssym++, symp++)
       {
         symp->u.ssym = ssym;
         symp->name = bfd_elf_string_from_elf_section (bfd2,
                                                 hdr2->sh_link,
                                                 ssym->st_name);
       }

      /* Sort symbol by name.  */
      qsort (symtable1, count1, sizeof (struct elf_symbol),
            elf_sym_name_compare);
      qsort (symtable2, count1, sizeof (struct elf_symbol),
            elf_sym_name_compare);

      for (i = 0; i < count1; i++)
       /* Two symbols must have the same binding, type and name.  */
       if (symtable1 [i].u.ssym->st_info != symtable2 [i].u.ssym->st_info
           || symtable1 [i].u.ssym->st_other != symtable2 [i].u.ssym->st_other
           || strcmp (symtable1 [i].name, symtable2 [i].name) != 0)
         goto done;

      result = TRUE;
      goto done;
    }

  symtable1 = bfd_malloc (symcount1 * sizeof (struct elf_symbol));
  symtable2 = bfd_malloc (symcount2 * sizeof (struct elf_symbol));
  if (symtable1 == NULL || symtable2 == NULL)
    goto done;

  /* Count definitions in the section.  */
  count1 = 0;
  for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++)
    if (isym->st_shndx == (unsigned int) shndx1)
      symtable1[count1++].u.isym = isym;

  count2 = 0;
  for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++)
    if (isym->st_shndx == (unsigned int) shndx2)
      symtable2[count2++].u.isym = isym;

  if (count1 == 0 || count2 == 0 || count1 != count2)
    goto done;

  for (i = 0; i < count1; i++)
    symtable1[i].name
      = bfd_elf_string_from_elf_section (bfd1, hdr1->sh_link,
                                    symtable1[i].u.isym->st_name);

  for (i = 0; i < count2; i++)
    symtable2[i].name
      = bfd_elf_string_from_elf_section (bfd2, hdr2->sh_link,
                                    symtable2[i].u.isym->st_name);

  /* Sort symbol by name.  */
  qsort (symtable1, count1, sizeof (struct elf_symbol),
        elf_sym_name_compare);
  qsort (symtable2, count1, sizeof (struct elf_symbol),
        elf_sym_name_compare);

  for (i = 0; i < count1; i++)
    /* Two symbols must have the same binding, type and name.  */
    if (symtable1 [i].u.isym->st_info != symtable2 [i].u.isym->st_info
       || symtable1 [i].u.isym->st_other != symtable2 [i].u.isym->st_other
       || strcmp (symtable1 [i].name, symtable2 [i].name) != 0)
      goto done;

  result = TRUE;

done:
  if (symtable1)
    free (symtable1);
  if (symtable2)
    free (symtable2);
  if (isymbuf1)
    free (isymbuf1);
  if (isymbuf2)
    free (isymbuf2);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 240 of file elf.c.

{
  /* I think this can be done just like an object file.  */
  return bfd_elf_mkobject (abfd);
}

Here is the call graph for this function:

Definition at line 225 of file elf.c.

{
  if (abfd->tdata.any == NULL)
    {
      abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
      if (abfd->tdata.any == NULL)
       return FALSE;
    }

  elf_tdata (abfd)->program_header_size = (bfd_size_type) -1;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void bfd_elf_print_symbol ( bfd abfd,
void *  filep,
asymbol symbol,
bfd_print_symbol_type  how 
)

Definition at line 1369 of file elf.c.

{
  FILE *file = filep;
  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      break;
    case bfd_print_symbol_more:
      fprintf (file, "elf ");
      bfd_fprintf_vma (abfd, file, symbol->value);
      fprintf (file, " %lx", (long) symbol->flags);
      break;
    case bfd_print_symbol_all:
      {
       const char *section_name;
       const char *name = NULL;
       const struct elf_backend_data *bed;
       unsigned char st_other;
       bfd_vma val;

       section_name = symbol->section ? symbol->section->name : "(*none*)";

       bed = get_elf_backend_data (abfd);
       if (bed->elf_backend_print_symbol_all)
         name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);

       if (name == NULL)
         {
           name = symbol->name;
           bfd_print_symbol_vandf (abfd, file, symbol);
         }

       fprintf (file, " %s\t", section_name);
       /* Print the "other" value for a symbol.  For common symbols,
          we've already printed the size; now print the alignment.
          For other symbols, we have no specified alignment, and
          we've printed the address; now print the size.  */
       if (bfd_is_com_section (symbol->section))
         val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
       else
         val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
       bfd_fprintf_vma (abfd, file, val);

       /* If we have version information, print it.  */
       if (elf_tdata (abfd)->dynversym_section != 0
           && (elf_tdata (abfd)->dynverdef_section != 0
              || elf_tdata (abfd)->dynverref_section != 0))
         {
           unsigned int vernum;
           const char *version_string;

           vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION;

           if (vernum == 0)
             version_string = "";
           else if (vernum == 1)
             version_string = "Base";
           else if (vernum <= elf_tdata (abfd)->cverdefs)
             version_string =
              elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
           else
             {
              Elf_Internal_Verneed *t;

              version_string = "";
              for (t = elf_tdata (abfd)->verref;
                   t != NULL;
                   t = t->vn_nextref)
                {
                  Elf_Internal_Vernaux *a;

                  for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
                    {
                     if (a->vna_other == vernum)
                       {
                         version_string = a->vna_nodename;
                         break;
                       }
                    }
                }
             }

           if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0)
             fprintf (file, "  %-11s", version_string);
           else
             {
              int i;

              fprintf (file, " (%s)", version_string);
              for (i = 10 - strlen (version_string); i > 0; --i)
                putc (' ', file);
             }
         }

       /* If the st_other field is not zero, print it.  */
       st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;

       switch (st_other)
         {
         case 0: break;
         case STV_INTERNAL:  fprintf (file, " .internal");  break;
         case STV_HIDDEN:    fprintf (file, " .hidden");    break;
         case STV_PROTECTED: fprintf (file, " .protected"); break;
         default:
           /* Some other non-defined flags are also present, so print
              everything hex.  */
           fprintf (file, " 0x%02x", (unsigned int) st_other);
         }

       fprintf (file, " %s", name);
      }
      break;
    }
}

Here is the call graph for this function:

void bfd_elf_set_dt_needed_name ( bfd abfd,
const char *  name 
)

Definition at line 1655 of file elf.c.

void bfd_elf_set_dyn_lib_class ( bfd abfd,
enum dynamic_lib_link_class  lib_class 
)

Definition at line 1675 of file elf.c.

{
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
      && bfd_get_format (abfd) == bfd_object)
    elf_dyn_lib_class (abfd) = lib_class;
}
void bfd_elf_set_group_contents ( bfd abfd,
asection sec,
void *  failedptrarg 
)

Definition at line 2918 of file elf.c.

{
  bfd_boolean *failedptr = failedptrarg;
  unsigned long symindx;
  asection *elt, *first;
  unsigned char *loc;
  bfd_boolean gas;

  /* Ignore linker created group section.  See elfNN_ia64_object_p in
     elfxx-ia64.c.  */
  if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
      || *failedptr)
    return;

  symindx = 0;
  if (elf_group_id (sec) != NULL)
    symindx = elf_group_id (sec)->udata.i;

  if (symindx == 0)
    {
      /* If called from the assembler, swap_out_syms will have set up
        elf_section_syms;  If called for "ld -r", use target_index.  */
      if (elf_section_syms (abfd) != NULL)
       symindx = elf_section_syms (abfd)[sec->index]->udata.i;
      else
       symindx = sec->target_index;
    }
  elf_section_data (sec)->this_hdr.sh_info = symindx;

  /* The contents won't be allocated for "ld -r" or objcopy.  */
  gas = TRUE;
  if (sec->contents == NULL)
    {
      gas = FALSE;
      sec->contents = bfd_alloc (abfd, sec->size);

      /* Arrange for the section to be written out.  */
      elf_section_data (sec)->this_hdr.contents = sec->contents;
      if (sec->contents == NULL)
       {
         *failedptr = TRUE;
         return;
       }
    }

  loc = sec->contents + sec->size;

  /* Get the pointer to the first section in the group that gas
     squirreled away here.  objcopy arranges for this to be set to the
     start of the input section group.  */
  first = elt = elf_next_in_group (sec);

  /* First element is a flag word.  Rest of section is elf section
     indices for all the sections of the group.  Write them backwards
     just to keep the group in the same order as given in .section
     directives, not that it matters.  */
  while (elt != NULL)
    {
      asection *s;
      unsigned int idx;

      loc -= 4;
      s = elt;
      if (!gas)
       s = s->output_section;
      idx = 0;
      if (s != NULL)
       idx = elf_section_data (s)->this_idx;
      H_PUT_32 (abfd, idx, loc);
      elt = elf_next_in_group (elt);
      if (elt == first)
       break;
    }

  if ((loc -= 4) != sec->contents)
    abort ();

  H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* bfd_elf_string_from_elf_section ( bfd abfd,
unsigned int  shindex,
unsigned int  strindex 
)

Definition at line 285 of file elf.c.

{
  Elf_Internal_Shdr *hdr;

  if (strindex == 0)
    return "";

  hdr = elf_elfsections (abfd)[shindex];

  if (hdr->contents == NULL
      && bfd_elf_get_str_section (abfd, shindex) == NULL)
    return NULL;

  if (strindex >= hdr->sh_size)
    {
      unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
      (*_bfd_error_handler)
       (_("%B: invalid string offset %u >= %lu for section `%s'"),
        abfd, strindex, (unsigned long) hdr->sh_size,
        (shindex == shstrndx && strindex == hdr->sh_name
         ? ".shstrtab"
         : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
      return "";
    }

  return ((char *) hdr->contents) + strindex;
}

Here is the call graph for this function:

const char* bfd_elf_sym_name ( bfd abfd,
Elf_Internal_Shdr symtab_hdr,
Elf_Internal_Sym *  isym,
asection sym_sec 
)

Definition at line 424 of file elf.c.

{
  const char *name;
  unsigned int iname = isym->st_name;
  unsigned int shindex = symtab_hdr->sh_link;

  if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
      /* Check for a bogus st_shndx to avoid crashing.  */
      && isym->st_shndx < elf_numsections (abfd)
      && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE))
    {
      iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
      shindex = elf_elfheader (abfd)->e_shstrndx;
    }

  name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
  if (name == NULL)
    name = "(null)";
  else if (sym_sec && *name == '\0')
    name = bfd_section_name (abfd, sym_sec);

  return name;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 8511 of file elf.c.

{
  if (abfd->xvec->flavour != bfd_target_elf_flavour)
    {
      bfd_set_error (bfd_error_wrong_format);
      return -1;
    }

  return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
}

Here is the call graph for this function:

int bfd_get_elf_phdrs ( bfd abfd,
void *  phdrs 
)

Definition at line 8531 of file elf.c.

{
  int num_phdrs;

  if (abfd->xvec->flavour != bfd_target_elf_flavour)
    {
      bfd_set_error (bfd_error_wrong_format);
      return -1;
    }

  num_phdrs = elf_elfheader (abfd)->e_phnum;
  memcpy (phdrs, elf_tdata (abfd)->phdr,
         num_phdrs * sizeof (Elf_Internal_Phdr));

  return num_phdrs;
}

Here is the call graph for this function:

Definition at line 2290 of file elf.c.

{
  if (index >= elf_numsections (abfd))
    return NULL;
  return elf_elfsections (abfd)[index]->bfd_section;
}
bfd_boolean bfd_section_from_phdr ( bfd abfd,
Elf_Internal_Phdr *  hdr,
int  index 
)

Definition at line 2650 of file elf.c.

{
  const struct elf_backend_data *bed;

  switch (hdr->p_type)
    {
    case PT_NULL:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "null");

    case PT_LOAD:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "load");

    case PT_DYNAMIC:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "dynamic");

    case PT_INTERP:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "interp");

    case PT_NOTE:
      if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
       return FALSE;
      if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
       return FALSE;
      return TRUE;

    case PT_SHLIB:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "shlib");

    case PT_PHDR:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr");

    case PT_GNU_EH_FRAME:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
                                         "eh_frame_hdr");

    case PT_GNU_STACK:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack");

    case PT_GNU_RELRO:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro");

    default:
      /* Check for any processor-specific program segment types.  */
      bed = get_elf_backend_data (abfd);
      return bed->elf_backend_section_from_phdr (abfd, hdr, index, "proc");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

asection* bfd_section_from_r_symndx ( bfd abfd,
struct sym_sec_cache cache,
asection sec,
unsigned long  r_symndx 
)

Definition at line 2249 of file elf.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  unsigned char esym[sizeof (Elf64_External_Sym)];
  Elf_External_Sym_Shndx eshndx;
  Elf_Internal_Sym isym;
  unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;

  if (cache->abfd == abfd && cache->indx[ent] == r_symndx)
    return cache->sec[ent];

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
                         &isym, esym, &eshndx) == NULL)
    return NULL;

  if (cache->abfd != abfd)
    {
      memset (cache->indx, -1, sizeof (cache->indx));
      cache->abfd = abfd;
    }
  cache->indx[ent] = r_symndx;
  cache->sec[ent] = sec;
  if ((isym.st_shndx != SHN_UNDEF && isym.st_shndx < SHN_LORESERVE)
      || isym.st_shndx > SHN_HIRESERVE)
    {
      asection *s;
      s = bfd_section_from_elf_index (abfd, isym.st_shndx);
      if (s != NULL)
       cache->sec[ent] = s;
    }
  return cache->sec[ent];
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean bfd_section_from_shdr ( bfd abfd,
unsigned int  shindex 
)

Definition at line 1828 of file elf.c.

{
  Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
  Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const char *name;

  name = bfd_elf_string_from_elf_section (abfd,
                                     elf_elfheader (abfd)->e_shstrndx,
                                     hdr->sh_name);
  if (name == NULL)
    return FALSE;

  switch (hdr->sh_type)
    {
    case SHT_NULL:
      /* Inactive section. Throw it away.  */
      return TRUE;

    case SHT_PROGBITS:      /* Normal section with contents.  */
    case SHT_NOBITS: /* .bss section.  */
    case SHT_HASH:   /* .hash section.  */
    case SHT_NOTE:   /* .note section.  */
    case SHT_INIT_ARRAY:    /* .init_array section.  */
    case SHT_FINI_ARRAY:    /* .fini_array section.  */
    case SHT_PREINIT_ARRAY: /* .preinit_array section.  */
    case SHT_GNU_LIBLIST:   /* .gnu.liblist section.  */
    case SHT_GNU_HASH:             /* .gnu.hash section.  */
      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);

    case SHT_DYNAMIC:       /* Dynamic linking information.  */
      if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
       return FALSE;
      if (hdr->sh_link > elf_numsections (abfd)
         || elf_elfsections (abfd)[hdr->sh_link] == NULL)
       return FALSE;
      if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
       {
         Elf_Internal_Shdr *dynsymhdr;

         /* The shared libraries distributed with hpux11 have a bogus
            sh_link field for the ".dynamic" section.  Find the
            string table for the ".dynsym" section instead.  */
         if (elf_dynsymtab (abfd) != 0)
           {
             dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
             hdr->sh_link = dynsymhdr->sh_link;
           }
         else
           {
             unsigned int i, num_sec;

             num_sec = elf_numsections (abfd);
             for (i = 1; i < num_sec; i++)
              {
                dynsymhdr = elf_elfsections (abfd)[i];
                if (dynsymhdr->sh_type == SHT_DYNSYM)
                  {
                    hdr->sh_link = dynsymhdr->sh_link;
                    break;
                  }
              }
           }
       }
      break;

    case SHT_SYMTAB:        /* A symbol table */
      if (elf_onesymtab (abfd) == shindex)
       return TRUE;

      if (hdr->sh_entsize != bed->s->sizeof_sym)
       return FALSE;
      BFD_ASSERT (elf_onesymtab (abfd) == 0);
      elf_onesymtab (abfd) = shindex;
      elf_tdata (abfd)->symtab_hdr = *hdr;
      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
      abfd->flags |= HAS_SYMS;

      /* Sometimes a shared object will map in the symbol table.  If
         SHF_ALLOC is set, and this is a shared object, then we also
         treat this section as a BFD section.  We can not base the
         decision purely on SHF_ALLOC, because that flag is sometimes
         set in a relocatable object file, which would confuse the
         linker.  */
      if ((hdr->sh_flags & SHF_ALLOC) != 0
         && (abfd->flags & DYNAMIC) != 0
         && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
                                          shindex))
       return FALSE;

      /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
        can't read symbols without that section loaded as well.  It
        is most likely specified by the next section header.  */
      if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
       {
         unsigned int i, num_sec;

         num_sec = elf_numsections (abfd);
         for (i = shindex + 1; i < num_sec; i++)
           {
             Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
             if (hdr2->sh_type == SHT_SYMTAB_SHNDX
                && hdr2->sh_link == shindex)
              break;
           }
         if (i == num_sec)
           for (i = 1; i < shindex; i++)
             {
              Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
              if (hdr2->sh_type == SHT_SYMTAB_SHNDX
                  && hdr2->sh_link == shindex)
                break;
             }
         if (i != shindex)
           return bfd_section_from_shdr (abfd, i);
       }
      return TRUE;

    case SHT_DYNSYM:        /* A dynamic symbol table */
      if (elf_dynsymtab (abfd) == shindex)
       return TRUE;

      if (hdr->sh_entsize != bed->s->sizeof_sym)
       return FALSE;
      BFD_ASSERT (elf_dynsymtab (abfd) == 0);
      elf_dynsymtab (abfd) = shindex;
      elf_tdata (abfd)->dynsymtab_hdr = *hdr;
      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
      abfd->flags |= HAS_SYMS;

      /* Besides being a symbol table, we also treat this as a regular
        section, so that objcopy can handle it.  */
      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);

    case SHT_SYMTAB_SHNDX:  /* Symbol section indices when >64k sections */
      if (elf_symtab_shndx (abfd) == shindex)
       return TRUE;

      BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
      elf_symtab_shndx (abfd) = shindex;
      elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
      elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
      return TRUE;

    case SHT_STRTAB:        /* A string table */
      if (hdr->bfd_section != NULL)
       return TRUE;
      if (ehdr->e_shstrndx == shindex)
       {
         elf_tdata (abfd)->shstrtab_hdr = *hdr;
         elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
         return TRUE;
       }
      if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
       {
       symtab_strtab:
         elf_tdata (abfd)->strtab_hdr = *hdr;
         elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
         return TRUE;
       }
      if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
       {
       dynsymtab_strtab:
         elf_tdata (abfd)->dynstrtab_hdr = *hdr;
         hdr = &elf_tdata (abfd)->dynstrtab_hdr;
         elf_elfsections (abfd)[shindex] = hdr;
         /* We also treat this as a regular section, so that objcopy
            can handle it.  */
         return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
                                            shindex);
       }

      /* If the string table isn't one of the above, then treat it as a
        regular section.  We need to scan all the headers to be sure,
        just in case this strtab section appeared before the above.  */
      if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
       {
         unsigned int i, num_sec;

         num_sec = elf_numsections (abfd);
         for (i = 1; i < num_sec; i++)
           {
             Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
             if (hdr2->sh_link == shindex)
              {
                /* Prevent endless recursion on broken objects.  */
                if (i == shindex)
                  return FALSE;
                if (! bfd_section_from_shdr (abfd, i))
                  return FALSE;
                if (elf_onesymtab (abfd) == i)
                  goto symtab_strtab;
                if (elf_dynsymtab (abfd) == i)
                  goto dynsymtab_strtab;
              }
           }
       }
      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);

    case SHT_REL:
    case SHT_RELA:
      /* *These* do a lot of work -- but build no sections!  */
      {
       asection *target_sect;
       Elf_Internal_Shdr *hdr2;
       unsigned int num_sec = elf_numsections (abfd);

       if (hdr->sh_entsize
           != (bfd_size_type) (hdr->sh_type == SHT_REL
                            ? bed->s->sizeof_rel : bed->s->sizeof_rela))
         return FALSE;

       /* Check for a bogus link to avoid crashing.  */
       if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
           || hdr->sh_link >= num_sec)
         {
           ((*_bfd_error_handler)
            (_("%B: invalid link %lu for reloc section %s (index %u)"),
             abfd, hdr->sh_link, name, shindex));
           return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
                                              shindex);
         }

       /* For some incomprehensible reason Oracle distributes
          libraries for Solaris in which some of the objects have
          bogus sh_link fields.  It would be nice if we could just
          reject them, but, unfortunately, some people need to use
          them.  We scan through the section headers; if we find only
          one suitable symbol table, we clobber the sh_link to point
          to it.  I hope this doesn't break anything.  */
       if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
           && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
         {
           unsigned int scan;
           int found;

           found = 0;
           for (scan = 1; scan < num_sec; scan++)
             {
              if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
                  || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
                {
                  if (found != 0)
                    {
                     found = 0;
                     break;
                    }
                  found = scan;
                }
             }
           if (found != 0)
             hdr->sh_link = found;
         }

       /* Get the symbol table.  */
       if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
            || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
           && ! bfd_section_from_shdr (abfd, hdr->sh_link))
         return FALSE;

       /* If this reloc section does not use the main symbol table we
          don't treat it as a reloc section.  BFD can't adequately
          represent such a section, so at least for now, we don't
          try.  We just present it as a normal section.  We also
          can't use it as a reloc section if it points to the null
          section, an invalid section, or another reloc section.  */
       if (hdr->sh_link != elf_onesymtab (abfd)
           || hdr->sh_info == SHN_UNDEF
           || (hdr->sh_info >= SHN_LORESERVE && hdr->