Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
elf32-bfin.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/bfin.h"
#include "elf/dwarf2.h"
#include "hashtab.h"
#include "elf32-target.h"

Go to the source code of this file.

Classes

struct  bfin_reloc_map
struct  bfinfdpic_relocs_info
struct  _bfinfdpic_dynamic_got_info
struct  _bfinfdpic_dynamic_got_plt_info
struct  _bfinfdpic_dynamic_got_plt_info::_bfinfdpic_dynamic_got_alloc_data
struct  bfin_link_hash_entry
struct  bfin_pcrel_relocs_copied
union  bfinfdpic_relocs_info.d

Defines

#define DOIT(x)   x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
#define BFIN_RELOC_MIN   0
#define BFIN_RELOC_MAX   0x21
#define BFIN_GNUEXT_RELOC_MIN   0x40
#define BFIN_GNUEXT_RELOC_MAX   0x43
#define BFIN_ARELOC_MIN   0xE0
#define BFIN_ARELOC_MAX   0xF3
#define IS_FDPIC(bfd)   ((bfd)->xvec == &bfd_elf32_bfinfdpic_vec)
#define bfinfdpic_hash_table(info)   ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash))
#define bfinfdpic_got_section(info)   (bfinfdpic_hash_table (info)->sgot)
#define bfinfdpic_gotrel_section(info)   (bfinfdpic_hash_table (info)->sgotrel)
#define bfinfdpic_gotfixup_section(info)   (bfinfdpic_hash_table (info)->sgotfixup)
#define bfinfdpic_plt_section(info)   (bfinfdpic_hash_table (info)->splt)
#define bfinfdpic_pltrel_section(info)   (bfinfdpic_hash_table (info)->spltrel)
#define bfinfdpic_relocs_info(info)   (bfinfdpic_hash_table (info)->relocs_info)
#define bfinfdpic_got_initial_offset(info)   (bfinfdpic_hash_table (info)->got0)
#define bfinfdpic_plt_initial_offset(info)   (bfinfdpic_hash_table (info)->plt0)
#define BFINFDPIC_SYM_LOCAL(INFO, H)
#define BFINFDPIC_FUNCDESC_LOCAL(INFO, H)   ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
#define LZPLT_RESOLVER_EXTRA   10
#define LZPLT_NORMAL_SIZE   6
#define LZPLT_ENTRIES   1362
#define BFINFDPIC_LZPLT_BLOCK_SIZE   ((bfd_vma) LZPLT_NORMAL_SIZE * LZPLT_ENTRIES + LZPLT_RESOLVER_EXTRA)
#define BFINFDPIC_LZPLT_RESOLV_LOC   (LZPLT_NORMAL_SIZE * LZPLT_ENTRIES / 2)
#define ELF_DYNAMIC_INTERPRETER   "/lib/ld.so.1"
#define DEFAULT_STACK_SIZE   0x20000
#define bfin_hash_entry(ent)   ((struct bfin_link_hash_entry *) (ent))
#define add_dynamic_entry(TAG, VAL)   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
#define TARGET_LITTLE_SYM   bfd_elf32_bfin_vec
#define TARGET_LITTLE_NAME   "elf32-bfin"
#define ELF_ARCH   bfd_arch_bfin
#define ELF_MACHINE_CODE   EM_BLACKFIN
#define ELF_MAXPAGESIZE   0x1000
#define elf_symbol_leading_char   '_'
#define bfd_elf32_bfd_reloc_type_lookup   bfin_bfd_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup   bfin_bfd_reloc_name_lookup
#define elf_info_to_howto   bfin_info_to_howto
#define elf_info_to_howto_rel   0
#define elf_backend_object_p   elf32_bfin_object_p
#define bfd_elf32_bfd_is_local_label_name   bfin_is_local_label_name
#define bfin_hash_table(p)   ((struct bfin_link_hash_table *) (p)->hash)
#define elf_backend_create_dynamic_sections   _bfd_elf_create_dynamic_sections
#define bfd_elf32_bfd_link_hash_table_create   bfin_link_hash_table_create
#define bfd_elf32_bfd_final_link   bfd_elf_gc_common_final_link
#define elf_backend_check_relocs   bfin_check_relocs
#define elf_backend_adjust_dynamic_symbol   bfin_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections   bfin_size_dynamic_sections
#define elf_backend_relocate_section   bfin_relocate_section
#define elf_backend_finish_dynamic_symbol   bfin_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections   bfin_finish_dynamic_sections
#define elf_backend_gc_mark_hook   bfin_gc_mark_hook
#define elf_backend_gc_sweep_hook   bfin_gc_sweep_hook
#define bfd_elf32_bfd_merge_private_bfd_data   elf32_bfin_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags   elf32_bfin_set_private_flags
#define bfd_elf32_bfd_print_private_bfd_data   elf32_bfin_print_private_bfd_data
#define elf_backend_reloc_type_class   elf32_bfin_reloc_type_class
#define elf_backend_can_gc_sections   1
#define elf_backend_can_refcount   1
#define elf_backend_want_got_plt   0
#define elf_backend_plt_readonly   1
#define elf_backend_want_plt_sym   0
#define elf_backend_got_header_size   12
#define elf_backend_rela_normal   1
#define TARGET_LITTLE_SYM   bfd_elf32_bfinfdpic_vec
#define TARGET_LITTLE_NAME   "elf32-bfinfdpic"
#define elf32_bed   elf32_bfinfdpic_bed
#define elf_backend_got_header_size   0
#define elf_backend_relocate_section   bfinfdpic_relocate_section
#define elf_backend_check_relocs   bfinfdpic_check_relocs
#define bfd_elf32_bfd_link_hash_table_create   bfinfdpic_elf_link_hash_table_create
#define elf_backend_always_size_sections   elf32_bfinfdpic_always_size_sections
#define elf_backend_modify_program_headers   elf32_bfinfdpic_modify_program_headers
#define bfd_elf32_bfd_copy_private_bfd_data   elf32_bfinfdpic_copy_private_bfd_data
#define elf_backend_create_dynamic_sections   elf32_bfinfdpic_create_dynamic_sections
#define elf_backend_adjust_dynamic_symbol   elf32_bfinfdpic_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections   elf32_bfinfdpic_size_dynamic_sections
#define elf_backend_finish_dynamic_symbol   elf32_bfinfdpic_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections   elf32_bfinfdpic_finish_dynamic_sections
#define elf_backend_can_make_relative_eh_frame   bfinfdpic_elf_use_relative_eh_frame
#define elf_backend_can_make_lsda_relative_eh_frame   bfinfdpic_elf_use_relative_eh_frame
#define elf_backend_encode_eh_address   bfinfdpic_elf_encode_eh_address
#define elf_backend_may_use_rel_p   1
#define elf_backend_may_use_rela_p   1
#define elf_backend_default_use_rela_p   1
#define elf_backend_omit_section_dynsym   _bfinfdpic_link_omit_section_dynsym

Functions

static bfd_reloc_status_type bfin_pltpc_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry ATTRIBUTE_UNUSED, asymbol *symbol ATTRIBUTE_UNUSED, PTR data ATTRIBUTE_UNUSED, asection *input_section ATTRIBUTE_UNUSED, bfd *output_bfd ATTRIBUTE_UNUSED, char **error_message ATTRIBUTE_UNUSED)
static bfd_reloc_status_type bfin_pcrel24_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, PTR data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
static bfd_reloc_status_type bfin_imm16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, PTR data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
static bfd_reloc_status_type bfin_byte4_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, PTR data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
static bfd_reloc_status_type bfin_bfd_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, PTR data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
static void bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, Elf_Internal_Rela *dst)
static reloc_howto_type * bfin_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
static reloc_howto_type * bfin_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
static reloc_howto_type * bfin_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type)
static bfd_boolean bfin_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *label)
static struct bfd_link_hash_tablebfinfdpic_elf_link_hash_table_create (bfd *abfd)
static hashval_t bfinfdpic_relocs_info_hash (const void *entry_)
static int bfinfdpic_relocs_info_eq (const void *entry1, const void *entry2)
static struct
bfinfdpic_relocs_info
bfinfdpic_relocs_info_find (struct htab *ht, bfd *abfd, const struct bfinfdpic_relocs_info *entry, enum insert_option insert)
static struct
bfinfdpic_relocs_info
bfinfdpic_relocs_info_for_global (struct htab *ht, bfd *abfd, struct elf_link_hash_entry *h, bfd_vma addend, enum insert_option insert)
static struct
bfinfdpic_relocs_info
bfinfdpic_relocs_info_for_local (struct htab *ht, bfd *abfd, long symndx, bfd_vma addend, enum insert_option insert)
static void bfinfdpic_pic_merge_early_relocs_info (struct bfinfdpic_relocs_info *e2, struct bfinfdpic_relocs_info const *e1)
static bfd_vma _bfinfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset, int reloc_type, long dynindx, bfd_vma addend, struct bfinfdpic_relocs_info *entry)
static bfd_vma _bfinfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset, struct bfinfdpic_relocs_info *entry)
static unsigned _bfinfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
static bfd_boolean _bfinfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
static bfd_boolean _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry, bfd *output_bfd, struct bfd_link_info *info, asection *sec, Elf_Internal_Sym *sym, bfd_vma addend)
static bfd_boolean bfin_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)
static enum elf_reloc_type_class elf32_bfin_reloc_type_class (const Elf_Internal_Rela *rela)
static bfd_boolean bfinfdpic_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms, asection **local_sections)
static bfd_boolean bfin_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms, asection **local_sections)
static asectionbfin_gc_mark_hook (asection *sec, struct bfd_link_info *info, Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
static bfd_boolean bfin_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)
static bfd_boolean _bfinfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *p ATTRIBUTE_UNUSED)
static bfd_boolean _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
static bfd_boolean elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
static int _bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
static bfd_signed_vma _bfinfdpic_compute_got_alloc_data (struct _bfinfdpic_dynamic_got_alloc_data *gad, bfd_signed_vma fdcur, bfd_signed_vma odd, bfd_signed_vma cur, bfd_vma got, bfd_vma fd, bfd_vma fdplt, bfd_vma wrap)
static bfd_signed_vma _bfinfdpic_get_got_entry (struct _bfinfdpic_dynamic_got_alloc_data *gad)
static bfd_signed_vma _bfinfdpic_get_fd_entry (struct _bfinfdpic_dynamic_got_alloc_data *gad)
static int _bfinfdpic_assign_got_entries (void **entryp, void *info_)
static int _bfinfdpic_assign_plt_entries (void **entryp, void *info_)
static int _bfinfdpic_resolve_final_relocs_info (void **entryp, void *p)
static bfd_boolean elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
static bfd_boolean elf32_bfinfdpic_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
static bfd_boolean elf32_bfinfdpic_modify_program_headers (bfd *output_bfd, struct bfd_link_info *info)
static bfd_boolean elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
static bfd_boolean elf32_bfinfdpic_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
static bfd_boolean elf32_bfinfdpic_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
static bfd_boolean bfinfdpic_elf_use_relative_eh_frame (bfd *input_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *eh_frame_section ATTRIBUTE_UNUSED)
static bfd_byte bfinfdpic_elf_encode_eh_address (bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset, asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded)
static bfd_boolean bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)
static bfd_boolean elf32_bfin_object_p (bfd *abfd)
static bfd_boolean elf32_bfin_set_private_flags (bfd *abfd, flagword flags)
static bfd_boolean bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
static bfd_boolean elf32_bfinfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
static bfd_boolean elf32_bfin_print_private_bfd_data (bfd *abfd, PTR ptr)
static bfd_boolean elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
static struct bfd_hash_entrybfin_link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string)
static struct bfd_link_hash_tablebfin_link_hash_table_create (bfd *abfd)
static bfd_boolean bfin_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
static bfd_boolean bfin_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
static bfd_boolean bfin_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
static bfd_boolean bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
static bfd_boolean bfin_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
bfd_boolean
bfd_bfin_elf32_create_embedded_relocs 
PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **))
bfd_boolean bfd_bfin_elf32_create_embedded_relocs (bfd *abfd, struct bfd_link_info *info, asection *datasec, asection *relsec, char **errmsg)

Variables

static reloc_howto_type bfin_howto_table []
static reloc_howto_type bfin_gnuext_howto_table []
static struct bfin_reloc_map []
const bfd_target bfd_elf32_bfinfdpic_vec

Class Documentation

struct bfin_reloc_map

Definition at line 993 of file elf32-bfin.c.

Class Members
bfd_reloc_code_real_type bfd_reloc_val
unsigned int bfin_reloc_val
struct bfinfdpic_elf_link_hash_table

Definition at line 1140 of file elf32-bfin.c.

Collaboration diagram for bfinfdpic_elf_link_hash_table:
Class Members
bfd_vma got0
bfd_vma plt0
struct htab * relocs_info
asection * sgot
asection * sgotfixup
asection * sgotrel
asection * splt
asection * spltrel
struct bfinfdpic_relocs_info

Definition at line 1221 of file elf32-bfin.c.

Class Members
bfd_vma addend
unsigned call:1
union bfinfdpic_relocs_info d
unsigned done:1
unsigned dynrelocs
unsigned fd:1
bfd_signed_vma fd_entry
unsigned fdgoff17m4:1
unsigned fdgoffhilo:1
unsigned fdgot17m4:1
bfd_signed_vma fdgot_entry
unsigned fdgothilo:1
unsigned fixups
unsigned got17m4:1
bfd_signed_vma got_entry
unsigned gothilo:1
unsigned gotoff:1
unsigned lazyplt:1
bfd_vma lzplt_entry
unsigned plt:1
bfd_vma plt_entry
unsigned privfd:1
unsigned relocs32
unsigned relocsfd
unsigned relocsfdv
unsigned sym:1
long symndx
struct _bfinfdpic_dynamic_got_info

Definition at line 3462 of file elf32-bfin.c.

Collaboration diagram for _bfinfdpic_dynamic_got_info:
Class Members
bfd_vma fd17m4
bfd_vma fdhilo
bfd_vma fdplt
unsigned long fixups
bfd_vma got17m4
bfd_vma gothilo
struct bfd_link_info * info
bfd_vma lzplt
unsigned long relocs
struct _bfinfdpic_dynamic_got_plt_info

Definition at line 3579 of file elf32-bfin.c.

Collaboration diagram for _bfinfdpic_dynamic_got_plt_info:
Class Members
struct
_bfinfdpic_dynamic_got_alloc_data
got17m4
struct
_bfinfdpic_dynamic_got_alloc_data
gothilo
struct _bfinfdpic_dynamic_got_plt_info::_bfinfdpic_dynamic_got_alloc_data

Definition at line 3598 of file elf32-bfin.c.

Class Members
bfd_signed_vma cur
bfd_signed_vma fdcur
bfd_vma fdplt
bfd_signed_vma max
bfd_signed_vma min
bfd_signed_vma odd
struct bfin_link_hash_entry

Definition at line 4880 of file elf32-bfin.c.

Collaboration diagram for bfin_link_hash_entry:
Class Members
struct bfin_pcrel_relocs_copied * pcrel_relocs_copied
struct bfin_link_hash_table

Definition at line 4890 of file elf32-bfin.c.

struct bfin_pcrel_relocs_copied

Definition at line 5166 of file elf32-bfin.c.

Collaboration diagram for bfin_pcrel_relocs_copied:
Class Members
bfd_size_type count
struct bfin_pcrel_relocs_copied * next
asection * section
union bfinfdpic_relocs_info.d

Definition at line 1226 of file elf32-bfin.c.

Class Members
bfd * abfd
struct elf_link_hash_entry * h

Define Documentation

#define add_dynamic_entry (   TAG,
  VAL 
)    _bfd_elf_add_dynamic_entry (info, TAG, VAL)

Definition at line 5577 of file elf32-bfin.c.

Definition at line 5519 of file elf32-bfin.c.

Definition at line 5508 of file elf32-bfin.c.

Definition at line 5568 of file elf32-bfin.c.

Definition at line 5568 of file elf32-bfin.c.

Definition at line 5533 of file elf32-bfin.c.

Definition at line 5537 of file elf32-bfin.c.

Definition at line 5502 of file elf32-bfin.c.

Definition at line 5501 of file elf32-bfin.c.

Definition at line 5535 of file elf32-bfin.c.

#define BFIN_ARELOC_MAX   0xF3

Definition at line 419 of file elf32-bfin.c.

#define BFIN_ARELOC_MIN   0xE0

Definition at line 418 of file elf32-bfin.c.

#define BFIN_GNUEXT_RELOC_MAX   0x43

Definition at line 417 of file elf32-bfin.c.

#define BFIN_GNUEXT_RELOC_MIN   0x40

Definition at line 416 of file elf32-bfin.c.

#define bfin_hash_entry (   ent)    ((struct bfin_link_hash_entry *) (ent))

Definition at line 4898 of file elf32-bfin.c.

#define bfin_hash_table (   p)    ((struct bfin_link_hash_table *) (p)->hash)

Definition at line 5510 of file elf32-bfin.c.

#define BFIN_RELOC_MAX   0x21

Definition at line 415 of file elf32-bfin.c.

#define BFIN_RELOC_MIN   0

Definition at line 414 of file elf32-bfin.c.

#define BFINFDPIC_FUNCDESC_LOCAL (   INFO,
  H 
)    ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)

Definition at line 1215 of file elf32-bfin.c.

Definition at line 1181 of file elf32-bfin.c.

#define bfinfdpic_got_section (   info)    (bfinfdpic_hash_table (info)->sgot)

Definition at line 1169 of file elf32-bfin.c.

#define bfinfdpic_gotfixup_section (   info)    (bfinfdpic_hash_table (info)->sgotfixup)

Definition at line 1173 of file elf32-bfin.c.

#define bfinfdpic_gotrel_section (   info)    (bfinfdpic_hash_table (info)->sgotrel)

Definition at line 1171 of file elf32-bfin.c.

#define bfinfdpic_hash_table (   info)    ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash))

Definition at line 1166 of file elf32-bfin.c.

Definition at line 1425 of file elf32-bfin.c.

Definition at line 1426 of file elf32-bfin.c.

Definition at line 1183 of file elf32-bfin.c.

#define bfinfdpic_plt_section (   info)    (bfinfdpic_hash_table (info)->splt)

Definition at line 1175 of file elf32-bfin.c.

#define bfinfdpic_pltrel_section (   info)    (bfinfdpic_hash_table (info)->spltrel)

Definition at line 1177 of file elf32-bfin.c.

#define bfinfdpic_relocs_info (   info)    (bfinfdpic_hash_table (info)->relocs_info)

Definition at line 1179 of file elf32-bfin.c.

#define BFINFDPIC_SYM_LOCAL (   INFO,
  H 
)
Value:
(_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
   || ! elf_hash_table (INFO)->dynamic_sections_created)

Definition at line 1212 of file elf32-bfin.c.

#define DEFAULT_STACK_SIZE   0x20000

Definition at line 3458 of file elf32-bfin.c.

#define DOIT (   x)    x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
#define elf32_bed   elf32_bfinfdpic_bed

Definition at line 5555 of file elf32-bfin.c.

#define ELF_ARCH   bfd_arch_bfin

Definition at line 5496 of file elf32-bfin.c.

Definition at line 5584 of file elf32-bfin.c.

Definition at line 5584 of file elf32-bfin.c.

Definition at line 5571 of file elf32-bfin.c.

Definition at line 5540 of file elf32-bfin.c.

Definition at line 5600 of file elf32-bfin.c.

Definition at line 5597 of file elf32-bfin.c.

#define elf_backend_can_refcount   1

Definition at line 5541 of file elf32-bfin.c.

Definition at line 5565 of file elf32-bfin.c.

Definition at line 5565 of file elf32-bfin.c.

Definition at line 5581 of file elf32-bfin.c.

Definition at line 5581 of file elf32-bfin.c.

Definition at line 5612 of file elf32-bfin.c.

Definition at line 5603 of file elf32-bfin.c.

Definition at line 5593 of file elf32-bfin.c.

Definition at line 5593 of file elf32-bfin.c.

Definition at line 5590 of file elf32-bfin.c.

Definition at line 5590 of file elf32-bfin.c.

Definition at line 5531 of file elf32-bfin.c.

Definition at line 5532 of file elf32-bfin.c.

#define elf_backend_got_header_size   12

Definition at line 5560 of file elf32-bfin.c.

Definition at line 5560 of file elf32-bfin.c.

#define elf_backend_may_use_rel_p   1

Definition at line 5607 of file elf32-bfin.c.

Definition at line 5609 of file elf32-bfin.c.

Definition at line 5574 of file elf32-bfin.c.

Definition at line 5506 of file elf32-bfin.c.

Definition at line 5615 of file elf32-bfin.c.

#define elf_backend_plt_readonly   1

Definition at line 5543 of file elf32-bfin.c.

#define elf_backend_rela_normal   1

Definition at line 5546 of file elf32-bfin.c.

Definition at line 5539 of file elf32-bfin.c.

Definition at line 5563 of file elf32-bfin.c.

Definition at line 5563 of file elf32-bfin.c.

Definition at line 5587 of file elf32-bfin.c.

Definition at line 5587 of file elf32-bfin.c.

#define elf_backend_want_got_plt   0

Definition at line 5542 of file elf32-bfin.c.

#define elf_backend_want_plt_sym   0

Definition at line 5544 of file elf32-bfin.c.

#define ELF_DYNAMIC_INTERPRETER   "/lib/ld.so.1"

Definition at line 3456 of file elf32-bfin.c.

Definition at line 5504 of file elf32-bfin.c.

#define elf_info_to_howto_rel   0

Definition at line 5505 of file elf32-bfin.c.

Definition at line 5497 of file elf32-bfin.c.

#define ELF_MAXPAGESIZE   0x1000

Definition at line 5498 of file elf32-bfin.c.

#define elf_symbol_leading_char   '_'

Definition at line 5499 of file elf32-bfin.c.

#define IS_FDPIC (   bfd)    ((bfd)->xvec == &bfd_elf32_bfinfdpic_vec)

Definition at line 1136 of file elf32-bfin.c.

#define LZPLT_ENTRIES   1362

Definition at line 1423 of file elf32-bfin.c.

#define LZPLT_NORMAL_SIZE   6

Definition at line 1422 of file elf32-bfin.c.

#define LZPLT_RESOLVER_EXTRA   10

Definition at line 1421 of file elf32-bfin.c.

#define TARGET_LITTLE_NAME   "elf32-bfin"

Definition at line 5553 of file elf32-bfin.c.

#define TARGET_LITTLE_NAME   "elf32-bfinfdpic"

Definition at line 5553 of file elf32-bfin.c.

Definition at line 5551 of file elf32-bfin.c.

Definition at line 5551 of file elf32-bfin.c.


Function Documentation

static bfd_boolean _bfin_create_got_section ( bfd abfd,
struct bfd_link_info info 
) [static]

Definition at line 3247 of file elf32-bfin.c.

{
  flagword flags, pltflags;
  asection *s;
  struct elf_link_hash_entry *h;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  int ptralign;
  int offset;

  /* This function may be called more than once.  */
  s = bfd_get_section_by_name (abfd, ".got");
  if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
    return TRUE;

  /* Machine specific: although pointers are 32-bits wide, we want the
     GOT to be aligned to a 64-bit boundary, such that function
     descriptors in it can be accessed with 64-bit loads and
     stores.  */
  ptralign = 3;

  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
          | SEC_LINKER_CREATED);
  pltflags = flags;

  s = bfd_make_section_with_flags (abfd, ".got", flags);
  if (s == NULL
      || !bfd_set_section_alignment (abfd, s, ptralign))
    return FALSE;

  if (bed->want_got_plt)
    {
      s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
      if (s == NULL
         || !bfd_set_section_alignment (abfd, s, ptralign))
       return FALSE;
    }

  if (bed->want_got_sym)
    {
      /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
        (or .got.plt) section.  We don't do this in the linker script
        because we don't want to define the symbol if we are not creating
        a global offset table.  */
      h = _bfd_elf_define_linkage_sym (abfd, info, s, "__GLOBAL_OFFSET_TABLE_");
      elf_hash_table (info)->hgot = h;
      if (h == NULL)
       return FALSE;

      /* Machine-specific: we want the symbol for executables as
        well.  */
      if (! bfd_elf_link_record_dynamic_symbol (info, h))
       return FALSE;
    }

  /* The first bit of the global offset table is the header.  */
  s->size += bed->got_header_size;

  /* This is the machine-specific part.  Create and initialize section
     data for the got.  */
  if (IS_FDPIC (abfd))
    {
      bfinfdpic_got_section (info) = s;
      bfinfdpic_relocs_info (info) = htab_try_create (1,
                                                bfinfdpic_relocs_info_hash,
                                                bfinfdpic_relocs_info_eq,
                                                (htab_del) NULL);
      if (! bfinfdpic_relocs_info (info))
       return FALSE;

      s = bfd_make_section_with_flags (abfd, ".rel.got",
                                   (flags | SEC_READONLY));
      if (s == NULL
         || ! bfd_set_section_alignment (abfd, s, 2))
       return FALSE;

      bfinfdpic_gotrel_section (info) = s;

      /* Machine-specific.  */
      s = bfd_make_section_with_flags (abfd, ".rofixup",
                                   (flags | SEC_READONLY));
      if (s == NULL
         || ! bfd_set_section_alignment (abfd, s, 2))
       return FALSE;

      bfinfdpic_gotfixup_section (info) = s;
      offset = -2048;
      flags = BSF_GLOBAL;
    }
  else
    {
      offset = 2048;
      flags = BSF_GLOBAL | BSF_WEAK;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_vma _bfinfdpic_add_dyn_reloc ( bfd output_bfd,
asection sreloc,
bfd_vma  offset,
int  reloc_type,
long  dynindx,
bfd_vma  addend,
struct bfinfdpic_relocs_info entry 
) [inline, static]

Definition at line 1431 of file elf32-bfin.c.

{
  Elf_Internal_Rela outrel;
  bfd_vma reloc_offset;

  outrel.r_offset = offset;
  outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
  outrel.r_addend = addend;

  reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
  BFD_ASSERT (reloc_offset < sreloc->size);
  bfd_elf32_swap_reloc_out (output_bfd, &outrel,
                         sreloc->contents + reloc_offset);
  sreloc->reloc_count++;

  /* If the entry's index is zero, this relocation was probably to a
     linkonce section that got discarded.  We reserved a dynamic
     relocation, but it was for another entry than the one we got at
     the time of emitting the relocation.  Unfortunately there's no
     simple way for us to catch this situation, since the relocation
     is cleared right before calling relocate_section, at which point
     we no longer know what the relocation used to point to.  */
  if (entry->symndx)
    {
      BFD_ASSERT (entry->dynrelocs > 0);
      entry->dynrelocs--;
    }

  return reloc_offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_vma _bfinfdpic_add_rofixup ( bfd output_bfd,
asection rofixup,
bfd_vma  offset,
struct bfinfdpic_relocs_info entry 
) [static]

Definition at line 1467 of file elf32-bfin.c.

{
  bfd_vma fixup_offset;

  if (rofixup->flags & SEC_EXCLUDE)
    return -1;

  fixup_offset = rofixup->reloc_count * 4;
  if (rofixup->contents)
    {
      BFD_ASSERT (fixup_offset < rofixup->size);
      bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
    }
  rofixup->reloc_count++;

  if (entry && entry->symndx)
    {
      /* See discussion about symndx == 0 in _bfinfdpic_add_dyn_reloc
        above.  */
      BFD_ASSERT (entry->fixups > 0);
      entry->fixups--;
    }

  return fixup_offset;
}

Here is the caller graph for this function:

static int _bfinfdpic_assign_got_entries ( void **  entryp,
void *  info_ 
) [static]

Definition at line 3773 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info *entry = *entryp;
  struct _bfinfdpic_dynamic_got_plt_info *dinfo = info_;

  if (entry->got17m4)
    entry->got_entry = _bfinfdpic_get_got_entry (&dinfo->got17m4);
  else if (entry->gothilo)
    entry->got_entry = _bfinfdpic_get_got_entry (&dinfo->gothilo);

  if (entry->fdgot17m4)
    entry->fdgot_entry = _bfinfdpic_get_got_entry (&dinfo->got17m4);
  else if (entry->fdgothilo)
    entry->fdgot_entry = _bfinfdpic_get_got_entry (&dinfo->gothilo);

  if (entry->fdgoff17m4)
    entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
  else if (entry->plt && dinfo->got17m4.fdplt)
    {
      dinfo->got17m4.fdplt -= 8;
      entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
    }
  else if (entry->plt)
    {
      dinfo->gothilo.fdplt -= 8;
      entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
    }
  else if (entry->privfd)
    entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int _bfinfdpic_assign_plt_entries ( void **  entryp,
void *  info_ 
) [static]

Definition at line 3811 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info *entry = *entryp;
  struct _bfinfdpic_dynamic_got_plt_info *dinfo = info_;

  /* If this symbol requires a local function descriptor, allocate
     one.  */
  if (entry->privfd && entry->fd_entry == 0)
    {
      if (dinfo->got17m4.fdplt)
       {
         entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
         dinfo->got17m4.fdplt -= 8;
       }
      else
       {
         BFD_ASSERT (dinfo->gothilo.fdplt);
         entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
         dinfo->gothilo.fdplt -= 8;
       }
    }

  if (entry->plt)
    {
      int size;

      /* We use the section's raw size to mark the location of the
        next PLT entry.  */
      entry->plt_entry = bfinfdpic_plt_section (dinfo->g.info)->size;

      /* Figure out the length of this PLT entry based on the
        addressing mode we need to reach the function descriptor.  */
      BFD_ASSERT (entry->fd_entry);
      if (entry->fd_entry >= -(1 << (18 - 1))
         && entry->fd_entry + 4 < (1 << (18 - 1)))
       size = 10;
      else
       size = 16;

      bfinfdpic_plt_section (dinfo->g.info)->size += size;
    }

  if (entry->lazyplt)
    {
      entry->lzplt_entry = dinfo->g.lzplt;
      dinfo->g.lzplt += LZPLT_NORMAL_SIZE;
      /* If this entry is the one that gets the resolver stub, account
        for the additional instruction.  */
      if (entry->lzplt_entry % BFINFDPIC_LZPLT_BLOCK_SIZE
         == BFINFDPIC_LZPLT_RESOLV_LOC)
       dinfo->g.lzplt += LZPLT_RESOLVER_EXTRA;
    }

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_signed_vma _bfinfdpic_compute_got_alloc_data ( struct _bfinfdpic_dynamic_got_alloc_data *  gad,
bfd_signed_vma  fdcur,
bfd_signed_vma  odd,
bfd_signed_vma  cur,
bfd_vma  got,
bfd_vma  fd,
bfd_vma  fdplt,
bfd_vma  wrap 
) [inline, static]

Definition at line 3616 of file elf32-bfin.c.

{
  bfd_signed_vma wrapmin = -wrap;

  /* Start at the given initial points.  */
  gad->fdcur = fdcur;
  gad->cur = cur;

  /* If we had an incoming odd word and we have any got entries that
     are going to use it, consume it, otherwise leave gad->odd at
     zero.  We might force gad->odd to zero and return the incoming
     odd such that it is used by the next range, but then GOT entries
     might appear to be out of order and we wouldn't be able to
     shorten the GOT by one word if it turns out to end with an
     unpaired GOT entry.  */
  if (odd && got)
    {
      gad->odd = odd;
      got -= 4;
      odd = 0;
    }
  else
    gad->odd = 0;

  /* If we're left with an unpaired GOT entry, compute its location
     such that we can return it.  Otherwise, if got doesn't require an
     odd number of words here, either odd was already zero in the
     block above, or it was set to zero because got was non-zero, or
     got was already zero.  In the latter case, we want the value of
     odd to carry over to the return statement, so we don't want to
     reset odd unless the condition below is true.  */
  if (got & 4)
    {
      odd = cur + got;
      got += 4;
    }

  /* Compute the tentative boundaries of this range.  */
  gad->max = cur + got;
  gad->min = fdcur - fd;
  gad->fdplt = 0;

  /* If function descriptors took too much space, wrap some of them
     around.  */
  if (gad->min < wrapmin)
    {
      gad->max += wrapmin - gad->min;
      gad->min = wrapmin;
    }
  /* If there is space left and we have function descriptors
     referenced in PLT entries that could take advantage of shorter
     offsets, place them here.  */
  else if (fdplt && gad->min > wrapmin)
    {
      bfd_vma fds;
      if ((bfd_vma) (gad->min - wrapmin) < fdplt)
       fds = gad->min - wrapmin;
      else
       fds = fdplt;

      fdplt -= fds;
      gad->min -= fds;
      gad->fdplt += fds;
    }

  /* If GOT entries took too much space, wrap some of them around.
     This may well cause gad->min to become lower than wrapmin.  This
     will cause a relocation overflow later on, so we don't have to
     report it here . */
  if ((bfd_vma) gad->max > wrap)
    {
      gad->min -= gad->max - wrap;
      gad->max = wrap;
    }
  /* If there is more space left, try to place some more function
     descriptors for PLT entries.  */
  else if (fdplt && (bfd_vma) gad->max < wrap)
    {
      bfd_vma fds;
      if ((bfd_vma) (wrap - gad->max) < fdplt)
       fds = wrap - gad->max;
      else
       fds = fdplt;

      fdplt -= fds;
      gad->max += fds;
      gad->fdplt += fds;
    }

  /* If odd was initially computed as an offset past the wrap point,
     wrap it around.  */
  if (odd > gad->max)
    odd = gad->min + odd - gad->max;

  /* _bfinfdpic_get_got_entry() below will always wrap gad->cur if needed
     before returning, so do it here too.  This guarantees that,
     should cur and fdcur meet at the wrap point, they'll both be
     equal to min.  */
  if (gad->cur == gad->max)
    gad->cur = gad->min;

  return odd;
}

Here is the caller graph for this function:

static int _bfinfdpic_count_got_plt_entries ( void **  entryp,
void *  dinfo_ 
) [static]

Definition at line 3490 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info *entry = *entryp;
  struct _bfinfdpic_dynamic_got_info *dinfo = dinfo_;
  unsigned relocs = 0, fixups = 0;

  /* Allocate space for a GOT entry pointing to the symbol.  */
  if (entry->got17m4)
    dinfo->got17m4 += 4;
  else if (entry->gothilo)
    dinfo->gothilo += 4;
  else
    entry->relocs32--;
  entry->relocs32++;

  /* Allocate space for a GOT entry pointing to the function
     descriptor.  */
  if (entry->fdgot17m4)
    dinfo->got17m4 += 4;
  else if (entry->fdgothilo)
    dinfo->gothilo += 4;
  else
    entry->relocsfd--;
  entry->relocsfd++;

  /* Decide whether we need a PLT entry, a function descriptor in the
     GOT, and a lazy PLT entry for this symbol.  */
  entry->plt = entry->call
    && entry->symndx == -1 && ! BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
    && elf_hash_table (dinfo->info)->dynamic_sections_created;
  entry->privfd = entry->plt
    || entry->fdgoff17m4 || entry->fdgoffhilo
    || ((entry->fd || entry->fdgot17m4 || entry->fdgothilo)
       && (entry->symndx != -1
           || BFINFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
  entry->lazyplt = entry->privfd
    && entry->symndx == -1 && ! BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
    && ! (dinfo->info->flags & DF_BIND_NOW)
    && elf_hash_table (dinfo->info)->dynamic_sections_created;

  /* Allocate space for a function descriptor.  */
  if (entry->fdgoff17m4)
    dinfo->fd17m4 += 8;
  else if (entry->privfd && entry->plt)
    dinfo->fdplt += 8;
  else if (entry->privfd)
    dinfo->fdhilo += 8;
  else
    entry->relocsfdv--;
  entry->relocsfdv++;

  if (entry->lazyplt)
    dinfo->lzplt += LZPLT_NORMAL_SIZE;

  if (!dinfo->info->executable || dinfo->info->pie)
    relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
  else
    {
      if (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
       {
         if (entry->symndx != -1
             || entry->d.h->root.type != bfd_link_hash_undefweak)
           fixups += entry->relocs32 + 2 * entry->relocsfdv;
       }
      else
       relocs += entry->relocs32 + entry->relocsfdv;

      if (entry->symndx != -1
         || BFINFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
       {
         if (entry->symndx != -1
             || entry->d.h->root.type != bfd_link_hash_undefweak)
           fixups += entry->relocsfd;
       }
      else
       relocs += entry->relocsfd;
    }

  entry->dynrelocs += relocs;
  entry->fixups += fixups;
  dinfo->relocs += relocs;
  dinfo->fixups += fixups;

  return 1;
}

Here is the caller graph for this function:

static bfd_boolean _bfinfdpic_emit_got_relocs_plt_entries ( struct bfinfdpic_relocs_info entry,
bfd output_bfd,
struct bfd_link_info info,
asection sec,
Elf_Internal_Sym *  sym,
bfd_vma  addend 
) [inline, static]

Definition at line 1534 of file elf32-bfin.c.

{
  bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
  int dynindx = -1;

  if (entry->done)
    return TRUE;
  entry->done = 1;

  if (entry->got_entry || entry->fdgot_entry || entry->fd_entry)
    {
      /* If the symbol is dynamic, consider it for dynamic
        relocations, otherwise decay to section + offset.  */
      if (entry->symndx == -1 && entry->d.h->dynindx != -1)
       dynindx = entry->d.h->dynindx;
      else
       {
         if (sec->output_section
             && ! bfd_is_abs_section (sec->output_section)
             && ! bfd_is_und_section (sec->output_section))
           dynindx = elf_section_data (sec->output_section)->dynindx;
         else
           dynindx = 0;
       }
    }

  /* Generate relocation for GOT entry pointing to the symbol.  */
  if (entry->got_entry)
    {
      int idx = dynindx;
      bfd_vma ad = addend;

      /* If the symbol is dynamic but binds locally, use
        section+offset.  */
      if (sec && (entry->symndx != -1
                || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
       {
         if (entry->symndx == -1)
           ad += entry->d.h->root.u.def.value;
         else
           ad += sym->st_value;
         ad += sec->output_offset;
         if (sec->output_section && elf_section_data (sec->output_section))
           idx = elf_section_data (sec->output_section)->dynindx;
         else
           idx = 0;
       }

      /* If we're linking an executable at a fixed address, we can
        omit the dynamic relocation as long as the symbol is local to
        this module.  */
      if (info->executable && !info->pie
         && (entry->symndx != -1
             || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
       {
         if (sec)
           ad += sec->output_section->vma;
         if (entry->symndx != -1
             || entry->d.h->root.type != bfd_link_hash_undefweak)
           _bfinfdpic_add_rofixup (output_bfd,
                               bfinfdpic_gotfixup_section (info),
                               bfinfdpic_got_section (info)->output_section
                               ->vma
                               + bfinfdpic_got_section (info)->output_offset
                               + bfinfdpic_got_initial_offset (info)
                               + entry->got_entry, entry);
       }
      else
       _bfinfdpic_add_dyn_reloc (output_bfd, bfinfdpic_gotrel_section (info),
                             _bfd_elf_section_offset
                             (output_bfd, info,
                              bfinfdpic_got_section (info),
                              bfinfdpic_got_initial_offset (info)
                              + entry->got_entry)
                             + bfinfdpic_got_section (info)
                             ->output_section->vma
                             + bfinfdpic_got_section (info)->output_offset,
                             R_byte4_data, idx, ad, entry);

      bfd_put_32 (output_bfd, ad,
                bfinfdpic_got_section (info)->contents
                + bfinfdpic_got_initial_offset (info)
                + entry->got_entry);
    }

  /* Generate relocation for GOT entry pointing to a canonical
     function descriptor.  */
  if (entry->fdgot_entry)
    {
      int reloc, idx;
      bfd_vma ad = 0;

      if (! (entry->symndx == -1
            && entry->d.h->root.type == bfd_link_hash_undefweak
            && BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
       {
         /* If the symbol is dynamic and there may be dynamic symbol
            resolution because we are, or are linked with, a shared
            library, emit a FUNCDESC relocation such that the dynamic
            linker will allocate the function descriptor.  If the
            symbol needs a non-local function descriptor but binds
            locally (e.g., its visibility is protected, emit a
            dynamic relocation decayed to section+offset.  */
         if (entry->symndx == -1
             && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
             && BFINFDPIC_SYM_LOCAL (info, entry->d.h)
             && !(info->executable && !info->pie))
           {
             reloc = R_BFIN_FUNCDESC;
             idx = elf_section_data (entry->d.h->root.u.def.section
                                  ->output_section)->dynindx;
             ad = entry->d.h->root.u.def.section->output_offset
              + entry->d.h->root.u.def.value;
           }
         else if (entry->symndx == -1
                 && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
           {
             reloc = R_BFIN_FUNCDESC;
             idx = dynindx;
             ad = addend;
             if (ad)
              return FALSE;
           }
         else
           {
             /* Otherwise, we know we have a private function descriptor,
               so reference it directly.  */
             if (elf_hash_table (info)->dynamic_sections_created)
              BFD_ASSERT (entry->privfd);
             reloc = R_byte4_data;
             idx = elf_section_data (bfinfdpic_got_section (info)
                                  ->output_section)->dynindx;
             ad = bfinfdpic_got_section (info)->output_offset
              + bfinfdpic_got_initial_offset (info) + entry->fd_entry;
           }

         /* If there is room for dynamic symbol resolution, emit the
            dynamic relocation.  However, if we're linking an
            executable at a fixed location, we won't have emitted a
            dynamic symbol entry for the got section, so idx will be
            zero, which means we can and should compute the address
            of the private descriptor ourselves.  */
         if (info->executable && !info->pie
             && (entry->symndx != -1
                || BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
           {
             ad += bfinfdpic_got_section (info)->output_section->vma;
             _bfinfdpic_add_rofixup (output_bfd,
                                 bfinfdpic_gotfixup_section (info),
                                 bfinfdpic_got_section (info)
                                 ->output_section->vma
                                 + bfinfdpic_got_section (info)
                                 ->output_offset
                                 + bfinfdpic_got_initial_offset (info)
                                 + entry->fdgot_entry, entry);
           }
         else
           _bfinfdpic_add_dyn_reloc (output_bfd,
                                 bfinfdpic_gotrel_section (info),
                                 _bfd_elf_section_offset
                                 (output_bfd, info,
                                  bfinfdpic_got_section (info),
                                  bfinfdpic_got_initial_offset (info)
                                  + entry->fdgot_entry)
                                 + bfinfdpic_got_section (info)
                                 ->output_section->vma
                                 + bfinfdpic_got_section (info)
                                 ->output_offset,
                                 reloc, idx, ad, entry);
       }

      bfd_put_32 (output_bfd, ad,
                bfinfdpic_got_section (info)->contents
                + bfinfdpic_got_initial_offset (info)
                + entry->fdgot_entry);
    }

  /* Generate relocation to fill in a private function descriptor in
     the GOT.  */
  if (entry->fd_entry)
    {
      int idx = dynindx;
      bfd_vma ad = addend;
      bfd_vma ofst;
      long lowword, highword;

      /* If the symbol is dynamic but binds locally, use
        section+offset.  */
      if (sec && (entry->symndx != -1
                || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
       {
         if (entry->symndx == -1)
           ad += entry->d.h->root.u.def.value;
         else
           ad += sym->st_value;
         ad += sec->output_offset;
         if (sec->output_section && elf_section_data (sec->output_section))
           idx = elf_section_data (sec->output_section)->dynindx;
         else
           idx = 0;
       }

      /* If we're linking an executable at a fixed address, we can
        omit the dynamic relocation as long as the symbol is local to
        this module.  */
      if (info->executable && !info->pie
         && (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
       {
         if (sec)
           ad += sec->output_section->vma;
         ofst = 0;
         if (entry->symndx != -1
             || entry->d.h->root.type != bfd_link_hash_undefweak)
           {
             _bfinfdpic_add_rofixup (output_bfd,
                                 bfinfdpic_gotfixup_section (info),
                                 bfinfdpic_got_section (info)
                                 ->output_section->vma
                                 + bfinfdpic_got_section (info)
                                 ->output_offset
                                 + bfinfdpic_got_initial_offset (info)
                                 + entry->fd_entry, entry);
             _bfinfdpic_add_rofixup (output_bfd,
                                 bfinfdpic_gotfixup_section (info),
                                 bfinfdpic_got_section (info)
                                 ->output_section->vma
                                 + bfinfdpic_got_section (info)
                                 ->output_offset
                                 + bfinfdpic_got_initial_offset (info)
                                 + entry->fd_entry + 4, entry);
           }
       }
      else
       {
         ofst
           = _bfinfdpic_add_dyn_reloc (output_bfd,
                                   entry->lazyplt
                                   ? bfinfdpic_pltrel_section (info)
                                   : bfinfdpic_gotrel_section (info),
                                   _bfd_elf_section_offset
                                   (output_bfd, info,
                                    bfinfdpic_got_section (info),
                                    bfinfdpic_got_initial_offset (info)
                                    + entry->fd_entry)
                                   + bfinfdpic_got_section (info)
                                   ->output_section->vma
                                   + bfinfdpic_got_section (info)
                                   ->output_offset,
                                   R_BFIN_FUNCDESC_VALUE, idx, ad, entry);
       }

      /* If we've omitted the dynamic relocation, just emit the fixed
        addresses of the symbol and of the local GOT base offset.  */
      if (info->executable && !info->pie && sec && sec->output_section)
       {
         lowword = ad;
         highword = bfinfdpic_got_section (info)->output_section->vma
           + bfinfdpic_got_section (info)->output_offset
           + bfinfdpic_got_initial_offset (info);
       }
      else if (entry->lazyplt)
       {
         if (ad)
           return FALSE;

         fd_lazy_rel_offset = ofst;

         /* A function descriptor used for lazy or local resolving is
            initialized such that its high word contains the output
            section index in which the PLT entries are located, and
            the low word contains the address of the lazy PLT entry
            entry point, that must be within the memory region
            assigned to that section.  */
         lowword = entry->lzplt_entry + 4
           + bfinfdpic_plt_section (info)->output_offset
           + bfinfdpic_plt_section (info)->output_section->vma;
         highword = _bfinfdpic_osec_to_segment
           (output_bfd, bfinfdpic_plt_section (info)->output_section);
       }
      else
       {
         /* A function descriptor for a local function gets the index
            of the section.  For a non-local function, it's
            disregarded.  */
         lowword = ad;
         if (entry->symndx == -1 && entry->d.h->dynindx != -1
             && entry->d.h->dynindx == idx)
           highword = 0;
         else
           highword = _bfinfdpic_osec_to_segment
             (output_bfd, sec->output_section);
       }

      bfd_put_32 (output_bfd, lowword,
                bfinfdpic_got_section (info)->contents
                + bfinfdpic_got_initial_offset (info)
                + entry->fd_entry);
      bfd_put_32 (output_bfd, highword,
                bfinfdpic_got_section (info)->contents
                + bfinfdpic_got_initial_offset (info)
                + entry->fd_entry + 4);
    }

  /* Generate code for the PLT entry.  */
  if (entry->plt_entry != (bfd_vma) -1)
    {
      bfd_byte *plt_code = bfinfdpic_plt_section (info)->contents
       + entry->plt_entry;

      BFD_ASSERT (entry->fd_entry);

      /* Figure out what kind of PLT entry we need, depending on the
        location of the function descriptor within the GOT.  */
      if (entry->fd_entry >= -(1 << (18 - 1))
         && entry->fd_entry + 4 < (1 << (18 - 1)))
       {
         /* P1 = [P3 + fd_entry]; P3 = [P3 + fd_entry + 4] */
         bfd_put_32 (output_bfd,
                    0xe519 | ((entry->fd_entry << 14) & 0xFFFF0000),
                    plt_code);
         bfd_put_32 (output_bfd,
                    0xe51b | (((entry->fd_entry + 4) << 14) & 0xFFFF0000),
                    plt_code + 4);
         plt_code += 8;
       }
      else
       {
         /* P1.L = fd_entry; P1.H = fd_entry;
            P3 = P3 + P1;
            P1 = [P3];
            P3 = [P3 + 4];  */
         bfd_put_32 (output_bfd,
                    0xe109 | (entry->fd_entry << 16),
                    plt_code);
         bfd_put_32 (output_bfd,
                    0xe149 | (entry->fd_entry & 0xFFFF0000),
                    plt_code + 4);
         bfd_put_16 (output_bfd, 0x5ad9, plt_code + 8);
         bfd_put_16 (output_bfd, 0x9159, plt_code + 10);
         bfd_put_16 (output_bfd, 0xac5b, plt_code + 12);
         plt_code += 14;
       }
      /* JUMP (P1) */
      bfd_put_16 (output_bfd, 0x0051, plt_code);
    }

  /* Generate code for the lazy PLT entry.  */
  if (entry->lzplt_entry != (bfd_vma) -1)
    {
      bfd_byte *lzplt_code = bfinfdpic_plt_section (info)->contents
       + entry->lzplt_entry;
      bfd_vma resolverStub_addr;

      bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
      lzplt_code += 4;

      resolverStub_addr = entry->lzplt_entry / BFINFDPIC_LZPLT_BLOCK_SIZE
       * BFINFDPIC_LZPLT_BLOCK_SIZE + BFINFDPIC_LZPLT_RESOLV_LOC;
      if (resolverStub_addr >= bfinfdpic_plt_initial_offset (info))
       resolverStub_addr = bfinfdpic_plt_initial_offset (info) - LZPLT_NORMAL_SIZE - LZPLT_RESOLVER_EXTRA;

      if (entry->lzplt_entry == resolverStub_addr)
       {
         /* This is a lazy PLT entry that includes a resolver call.
            P2 = [P3];
            R3 = [P3 + 4];
            JUMP (P2);  */
         bfd_put_32 (output_bfd,
                    0xa05b915a,
                    lzplt_code);
         bfd_put_16 (output_bfd, 0x0052, lzplt_code + 4);
       }
      else
       {
         /* JUMP.S  resolverStub */
         bfd_put_16 (output_bfd,
                    0x2000
                    | (((resolverStub_addr - entry->lzplt_entry)
                       / 2) & (((bfd_vma)1 << 12) - 1)),
                    lzplt_code);
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_signed_vma _bfinfdpic_get_fd_entry ( struct _bfinfdpic_dynamic_got_alloc_data *  gad) [inline, static]

Definition at line 3760 of file elf32-bfin.c.

{
  /* If we're at the bottom, wrap around, and only then allocate the
     next pair of words.  */
  if (gad->fdcur == gad->min)
    gad->fdcur = gad->max;
  return gad->fdcur -= 8;
}

Here is the caller graph for this function:

static bfd_signed_vma _bfinfdpic_get_got_entry ( struct _bfinfdpic_dynamic_got_alloc_data *  gad) [inline, static]

Definition at line 3731 of file elf32-bfin.c.

{
  bfd_signed_vma ret;

  if (gad->odd)
    {
      /* If there was an odd word left behind, use it.  */
      ret = gad->odd;
      gad->odd = 0;
    }
  else
    {
      /* Otherwise, use the word pointed to by cur, reserve the next
        as an odd word, and skip to the next pair of words, possibly
        wrapping around.  */
      ret = gad->cur;
      gad->odd = gad->cur + 4;
      gad->cur += 8;
      if (gad->cur == gad->max)
       gad->cur = gad->min;
    }

  return ret;
}

Here is the caller graph for this function:

static bfd_boolean _bfinfdpic_link_omit_section_dynsym ( bfd *output_bfd  ATTRIBUTE_UNUSED,
struct bfd_link_info *info  ATTRIBUTE_UNUSED,
asection *p  ATTRIBUTE_UNUSED 
) [static]

Definition at line 3221 of file elf32-bfin.c.

{
  switch (elf_section_data (p)->this_hdr.sh_type)
    {
    case SHT_PROGBITS:
    case SHT_NOBITS:
      /* If sh_type is yet undecided, assume it could be
        SHT_PROGBITS/SHT_NOBITS.  */
    case SHT_NULL:
      return FALSE;

      /* There shouldn't be section relative relocations
        against any other section.  */
    default:
      return TRUE;
    }
}

Here is the call graph for this function:

static bfd_boolean _bfinfdpic_osec_readonly_p ( bfd output_bfd,
asection osec 
) [inline, static]

Definition at line 1523 of file elf32-bfin.c.

{
  unsigned seg = _bfinfdpic_osec_to_segment (output_bfd, osec);

  return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned _bfinfdpic_osec_to_segment ( bfd output_bfd,
asection osec 
) [static]

Definition at line 1498 of file elf32-bfin.c.

{
  struct elf_segment_map *m;
  Elf_Internal_Phdr *p;

  /* Find the segment that contains the output_section.  */
  for (m = elf_tdata (output_bfd)->segment_map,
        p = elf_tdata (output_bfd)->phdr;
       m != NULL;
       m = m->next, p++)
    {
      int i;

      for (i = m->count - 1; i >= 0; i--)
       if (m->sections[i] == osec)
         break;

      if (i >= 0)
       break;
    }

  return p - elf_tdata (output_bfd)->phdr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int _bfinfdpic_resolve_final_relocs_info ( void **  entryp,
void *  p 
) [static]

Definition at line 3874 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info *entry = *entryp;
  htab_t *htab = p;

  if (entry->symndx == -1)
    {
      struct elf_link_hash_entry *h = entry->d.h;
      struct bfinfdpic_relocs_info *oentry;

      while (h->root.type == bfd_link_hash_indirect
            || h->root.type == bfd_link_hash_warning)
       h = (struct elf_link_hash_entry *)h->root.u.i.link;

      if (entry->d.h == h)
       return 1;

      oentry = bfinfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
                                          NO_INSERT);

      if (oentry)
       {
         /* Merge the two entries.  */
         bfinfdpic_pic_merge_early_relocs_info (oentry, entry);
         htab_clear_slot (*htab, entryp);
         return 1;
       }

      entry->d.h = h;

      /* If we can't find this entry with the new bfd hash, re-insert
        it, and get the traversal restarted.  */
      if (! htab_find (*htab, entry))
       {
         htab_clear_slot (*htab, entryp);
         entryp = htab_find_slot (*htab, entry, INSERT);
         if (! *entryp)
           *entryp = entry;
         /* Abort the traversal, since the whole table may have
            moved, and leave it up to the parent to restart the
            process.  */
         *(htab_t *)p = NULL;
         return 0;
       }
    }

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean bfd_bfin_elf32_create_embedded_relocs ( bfd abfd,
struct bfd_link_info info,
asection datasec,
asection relsec,
char **  errmsg 
)

Definition at line 5379 of file elf32-bfin.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Sym *isymbuf = NULL;
  Elf_Internal_Rela *internal_relocs = NULL;
  Elf_Internal_Rela *irel, *irelend;
  bfd_byte *p;
  bfd_size_type amt;

  BFD_ASSERT (! info->relocatable);

  *errmsg = NULL;

  if (datasec->reloc_count == 0)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;

  /* Get a copy of the native relocations.  */
  internal_relocs = (_bfd_elf_link_read_relocs
                   (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
                    info->keep_memory));
  if (internal_relocs == NULL)
    goto error_return;

  amt = (bfd_size_type) datasec->reloc_count * 12;
  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
  if (relsec->contents == NULL)
    goto error_return;

  p = relsec->contents;

  irelend = internal_relocs + datasec->reloc_count;
  for (irel = internal_relocs; irel < irelend; irel++, p += 12)
    {
      asection *targetsec;

      /* We are going to write a four byte longword into the runtime
       reloc section.  The longword will be the address in the data
       section which must be relocated.  It is followed by the name
       of the target section NUL-padded or truncated to 8
       characters.  */

      /* We can only relocate absolute longword relocs at run time.  */
      if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
       {
         *errmsg = _("unsupported reloc type");
         bfd_set_error (bfd_error_bad_value);
         goto error_return;
       }

      /* Get the target section referred to by the reloc.  */
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
       {
         /* A local symbol.  */
         Elf_Internal_Sym *isym;

         /* Read this BFD's local symbols if we haven't done so already.  */
         if (isymbuf == NULL)
           {
             isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
             if (isymbuf == NULL)
              isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
                                          symtab_hdr->sh_info, 0,
                                          NULL, NULL, NULL);
             if (isymbuf == NULL)
              goto error_return;
           }

         isym = isymbuf + ELF32_R_SYM (irel->r_info);
         targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
       }
      else
       {
         unsigned long indx;
         struct elf_link_hash_entry *h;

         /* An external symbol.  */
         indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
         h = elf_sym_hashes (abfd)[indx];
         BFD_ASSERT (h != NULL);
         if (h->root.type == bfd_link_hash_defined
             || h->root.type == bfd_link_hash_defweak)
           targetsec = h->root.u.def.section;
         else
           targetsec = NULL;
       }

      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
      memset (p + 4, 0, 8);
      if (targetsec != NULL)
       strncpy ((char *) p + 4, targetsec->output_section->name, 8);
    }

  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
    free (isymbuf);
  if (internal_relocs != NULL
      && elf_section_data (datasec)->relocs != internal_relocs)
    free (internal_relocs);
  return TRUE;

error_return:
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
    free (isymbuf);
  if (internal_relocs != NULL
      && elf_section_data (datasec)->relocs != internal_relocs)
    free (internal_relocs);
  return FALSE;
}

Here is the call graph for this function:

Definition at line 5061 of file elf32-bfin.c.

{
  bfd *dynobj;
  asection *s;
  unsigned int power_of_two;

  dynobj = elf_hash_table (info)->dynobj;

  /* Make sure we know what is going on here.  */
  BFD_ASSERT (dynobj != NULL
             && (h->needs_plt
                || h->u.weakdef != NULL
                || (h->def_dynamic && h->ref_regular && !h->def_regular)));

  /* If this is a function, put it in the procedure linkage table.  We
     will fill in the contents of the procedure linkage table later,
     when we know the address of the .got section.  */
  if (h->type == STT_FUNC || h->needs_plt)
    {
      BFD_ASSERT(0);
    }

  /* If this is a weak symbol, and there is a real definition, the
     processor independent code will have arranged for us to see the
     real definition first, and we can just use the same value.  */
  if (h->u.weakdef != NULL)
    {
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
                || h->u.weakdef->root.type == bfd_link_hash_defweak);
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
      return TRUE;
    }

  /* This is a reference to a symbol defined by a dynamic object which
     is not a function.  */

  /* If we are creating a shared library, we must presume that the
     only references to the symbol are via the global offset table.
     For such cases we need not do anything here; the relocations will
     be handled correctly by relocate_section.  */
  if (info->shared)
    return TRUE;

  /* We must allocate the symbol in our .dynbss section, which will
     become part of the .bss section of the executable.  There will be
     an entry for this symbol in the .dynsym section.  The dynamic
     object will contain position independent code, so all references
     from the dynamic object to this symbol will go through the global
     offset table.  The dynamic linker will use the .dynsym entry to
     determine the address it must put in the global offset table, so
     both the dynamic object and the regular object will refer to the
     same memory location for the variable.  */

  s = bfd_get_section_by_name (dynobj, ".dynbss");
  BFD_ASSERT (s != NULL);

  /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
     copy the initial value out of the dynamic object and into the
     runtime process image.  We need to remember the offset into the
     .rela.bss section we are going to use.  */
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
    {
      asection *srel;

      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
      BFD_ASSERT (srel != NULL);
      srel->size += sizeof (Elf32_External_Rela);
      h->needs_copy = 1;
    }

  /* We need to figure out the alignment required for this symbol.  I
     have no idea how ELF linkers handle this.  */
  power_of_two = bfd_log2 (h->size);
  if (power_of_two > 3)
    power_of_two = 3;

  /* Apply the required alignment.  */
  s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
  if (power_of_two > bfd_get_section_alignment (dynobj, s))
    {
      if (!bfd_set_section_alignment (dynobj, s, power_of_two))
       return FALSE;
    }

  /* Define the symbol as being at this point in the section.  */
  h->root.u.def.section = s;
  h->root.u.def.value = s->size;

  /* Increment the section size to make room for the symbol.  */
  s->size += h->size;

  return TRUE;
}

Here is the call graph for this function:

static bfd_reloc_status_type bfin_bfd_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
PTR  data,
asection input_section,
bfd output_bfd,
char **error_message  ATTRIBUTE_UNUSED 
) [static]

Definition at line 282 of file elf32-bfin.c.

{
  bfd_vma relocation;
  bfd_size_type addr = reloc_entry->address;
  bfd_vma output_base = 0;
  reloc_howto_type *howto = reloc_entry->howto;
  asection *output_section;
  bfd_boolean relocatable = (output_bfd != NULL);

  /* Is the address of the relocation really within the section?  */
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    return bfd_reloc_outofrange;

  if (bfd_is_und_section (symbol->section)
      && (symbol->flags & BSF_WEAK) == 0
      && !relocatable)
    return bfd_reloc_undefined;

  /* Get symbol value.  (Common symbols are special.)  */
  if (bfd_is_com_section (symbol->section))
    relocation = 0;
  else
    relocation = symbol->value;

  output_section = symbol->section->output_section;

  /* Convert input-section-relative symbol value to absolute.  */
  if (relocatable)
    output_base = 0;
  else
    output_base = output_section->vma;

  if (!relocatable || !strcmp (symbol->name, symbol->section->name))
    relocation += output_base + symbol->section->output_offset;

  if (!relocatable && !strcmp (symbol->name, symbol->section->name))
    {
      /* Add in supplied addend.  */
      relocation += reloc_entry->addend;
    }

  /* Here the variable relocation holds the final address of the
     symbol we are relocating against, plus any addend.  */

  if (howto->pc_relative == TRUE)
    {
      relocation -= input_section->output_section->vma + input_section->output_offset;

      if (howto->pcrel_offset == TRUE)
        relocation -= reloc_entry->address;
    }

  if (relocatable)
    {
      reloc_entry->address += input_section->output_offset;
      reloc_entry->addend += symbol->section->output_offset;
    }

  if (howto->complain_on_overflow != complain_overflow_dont)
    {
      bfd_reloc_status_type status;

      status = bfd_check_overflow (howto->complain_on_overflow,
                                  howto->bitsize,
                                  howto->rightshift,
                                  bfd_arch_bits_per_address(abfd),
                                  relocation);
      if (status != bfd_reloc_ok)
       return status;
    }

  /* If rightshift is 1 and the number odd, return error.  */
  if (howto->rightshift && (relocation & 0x01))
    {
      fprintf(stderr, "relocation should be even number\n");
      return bfd_reloc_overflow;
    }

  relocation >>= (bfd_vma) howto->rightshift;

  /* Shift everything up to where it's going to be used.  */

  relocation <<= (bfd_vma) howto->bitpos;

#define DOIT(x)                                                       \
  x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))

  /* handle 8 and 16 bit relocations here. */
  switch (howto->size)
    {
    case 0:
      {
        char x = bfd_get_8 (abfd, (char *) data + addr);
        DOIT (x);
        bfd_put_8 (abfd, x, (unsigned char *) data + addr);
      }
      break;

    case 1:
      {
        unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
        DOIT (x);
        bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
      }
      break;

    default:
      return bfd_reloc_other;
    }

  return bfd_reloc_ok;
}

Here is the call graph for this function:

static reloc_howto_type* bfin_bfd_reloc_name_lookup ( bfd *abfd  ATTRIBUTE_UNUSED,
const char *  r_name 
) [static]

Definition at line 1084 of file elf32-bfin.c.

{
  unsigned int i;

  for (i = 0;
       i < (sizeof (bfin_howto_table)
           / sizeof (bfin_howto_table[0]));
       i++)
    if (bfin_howto_table[i].name != NULL
       && strcasecmp (bfin_howto_table[i].name, r_name) == 0)
      return &bfin_howto_table[i];

  for (i = 0;
       i < (sizeof (bfin_gnuext_howto_table)
           / sizeof (bfin_gnuext_howto_table[0]));
       i++)
    if (bfin_gnuext_howto_table[i].name != NULL
       && strcasecmp (bfin_gnuext_howto_table[i].name, r_name) == 0)
      return &bfin_gnuext_howto_table[i];

  return NULL;
}

Here is the call graph for this function:

static reloc_howto_type* bfin_bfd_reloc_type_lookup ( bfd *abfd  ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type  code 
) [static]

Definition at line 1064 of file elf32-bfin.c.

{
  unsigned int i;
  unsigned int r_type = BFIN_RELOC_MIN;

  for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
    if (bfin_reloc_map[i].bfd_reloc_val == code)
      r_type = bfin_reloc_map[i].bfin_reloc_val;

  if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
    return &bfin_howto_table [r_type];

  else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
   return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];

  return (reloc_howto_type *) NULL;
}
static bfd_reloc_status_type bfin_byte4_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
PTR  data,
asection input_section,
bfd output_bfd,
char **error_message  ATTRIBUTE_UNUSED 
) [static]

Definition at line 216 of file elf32-bfin.c.

{
  bfd_vma relocation, x;
  bfd_size_type addr = reloc_entry->address;
  bfd_vma output_base = 0;
  asection *output_section;
  bfd_boolean relocatable = (output_bfd != NULL);

  /* Is the address of the relocation really within the section?  */
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    return bfd_reloc_outofrange;

  if (bfd_is_und_section (symbol->section)
      && (symbol->flags & BSF_WEAK) == 0
      && !relocatable)
    return bfd_reloc_undefined;

  output_section = symbol->section->output_section;
  relocation = symbol->value;
  /* Convert input-section-relative symbol value to absolute.  */
  if (relocatable)
    output_base = 0;
  else
    output_base = output_section->vma;

  if ((symbol->name
       && symbol->section->name
       && !strcmp (symbol->name, symbol->section->name))
      || !relocatable)
    {
      relocation += output_base + symbol->section->output_offset;
    }

  relocation += reloc_entry->addend;

  if (relocatable)
    {
      /* This output will be relocatable ... like ld -r. */
      reloc_entry->address += input_section->output_offset;
      reloc_entry->addend += symbol->section->output_offset;
    }
  else
    {
      reloc_entry->addend = 0;
    }

  /* Here the variable relocation holds the final address of the
     symbol we are relocating against, plus any addend.  */
  x = relocation & 0xFFFF0000;
  x >>=16;
  bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);

  x = relocation & 0x0000FFFF;
  bfd_put_16 (abfd, x, (unsigned char *) data + addr);
  return bfd_reloc_ok;
}

Here is the call graph for this function:

static bfd_boolean bfin_check_relocs ( bfd abfd,
struct bfd_link_info info,
asection sec,
const Elf_Internal_Rela relocs 
) [static]

Definition at line 1932 of file elf32-bfin.c.

{
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_signed_vma *local_got_refcounts;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  asection *sgot;
  asection *srelgot;
  asection *sreloc;
  if (info->relocatable)
    return TRUE;

  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  local_got_refcounts = elf_local_got_refcounts (abfd);

  sgot = NULL;
  srelgot = NULL;
  sreloc = NULL;

  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; rel++)
    {
      unsigned long r_symndx;
      struct elf_link_hash_entry *h;

      r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx < symtab_hdr->sh_info)
       h = NULL;
      else
       h = sym_hashes[r_symndx - symtab_hdr->sh_info];

      switch (ELF32_R_TYPE (rel->r_info))
       {
       /* This relocation describes the C++ object vtable hierarchy.
           Reconstruct it for later use during GC.  */
        case R_BFIN_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;

        /* This relocation describes which C++ vtable entries
           are actually used.  Record for later use during GC.  */
        case R_BFIN_GNU_VTENTRY:
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;

       case R_got:
         if (h != NULL
             && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
           break;
         /* Fall through.  */

         if (dynobj == NULL)
           {
             /* Create the .got section.  */
             elf_hash_table (info)->dynobj = dynobj = abfd;
             if (!_bfd_elf_create_got_section (dynobj, info))
              return FALSE;
           }

         if (sgot == NULL)
           {
             sgot = bfd_get_section_by_name (dynobj, ".got");
             BFD_ASSERT (sgot != NULL);
           }

         if (srelgot == NULL && (h != NULL || info->shared))
           {
             srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
             if (srelgot == NULL)
              {
                flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
                                | SEC_IN_MEMORY | SEC_LINKER_CREATED
                                | SEC_READONLY);
                srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
                                                  flags);
                if (srelgot == NULL
                    || !bfd_set_section_alignment (dynobj, srelgot, 2))
                  return FALSE;
              }
           }

         if (h != NULL)
           {
             if (h->got.refcount == 0)
              {
                /* Make sure this symbol is output as a dynamic symbol.  */
                if (h->dynindx == -1 && !h->forced_local)
                  {
                    if (!bfd_elf_link_record_dynamic_symbol (info, h))
                     return FALSE;
                  }

                /* Allocate space in the .got section.  */
                sgot->size += 4;
                /* Allocate relocation space.  */
                srelgot->size += sizeof (Elf32_External_Rela);
              }
             h->got.refcount++;
           }
         else
           {
             /* This is a global offset table entry for a local symbol.  */
             if (local_got_refcounts == NULL)
              {
                bfd_size_type size;

                size = symtab_hdr->sh_info;
                size *= sizeof (bfd_signed_vma);
                local_got_refcounts = ((bfd_signed_vma *)
                                    bfd_zalloc (abfd, size));
                if (local_got_refcounts == NULL)
                  return FALSE;
                elf_local_got_refcounts (abfd) = local_got_refcounts;
              }
             if (local_got_refcounts[r_symndx] == 0)
              {
                sgot->size += 4;
                if (info->shared)
                  {
                    /* If we are generating a shared object, we need to
                       output a R_68K_RELATIVE reloc so that the dynamic
                       linker can adjust this GOT entry.  */
                    srelgot->size += sizeof (Elf32_External_Rela);
                  }
              }
             local_got_refcounts[r_symndx]++;
           }
         break;

       default:
         break;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean bfin_discard_copies ( struct elf_link_hash_entry h,
PTR  inf 
) [static]

Definition at line 5190 of file elf32-bfin.c.

{
  struct bfd_link_info *info = (struct bfd_link_info *) inf;
  struct bfin_pcrel_relocs_copied *s;

  if (h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (!h->def_regular || (!info->symbolic && !h->forced_local))
    {
      if ((info->flags & DF_TEXTREL) == 0)
       {
         /* Look for relocations against read-only sections.  */
         for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
              s != NULL; s = s->next)
           if ((s->section->flags & SEC_READONLY) != 0)
             {
              info->flags |= DF_TEXTREL;
              break;
             }
       }

      return TRUE;
    }

  for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
       s != NULL; s = s->next)
    s->section->size -= s->count * sizeof (Elf32_External_Rela);

  return TRUE;
}

Here is the caller graph for this function:

static bfd_boolean bfin_elf_copy_private_bfd_data ( bfd ibfd,
bfd obfd 
) [static]

Definition at line 4717 of file elf32-bfin.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_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
  elf_flags_init (obfd) = TRUE;
  return TRUE;
}

Here is the caller graph for this function:

static bfd_boolean bfin_finish_dynamic_sections ( bfd *output_bfd  ATTRIBUTE_UNUSED,
struct bfd_link_info info 
) [static]

Definition at line 4951 of file elf32-bfin.c.

{
  bfd *dynobj;
  asection *sdyn;

  dynobj = elf_hash_table (info)->dynobj;

  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      Elf32_External_Dyn *dyncon, *dynconend;

      BFD_ASSERT (sdyn != NULL);

      dyncon = (Elf32_External_Dyn *) sdyn->contents;
      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
      for (; dyncon < dynconend; dyncon++)
       {
         Elf_Internal_Dyn dyn;

         bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);

       }

    }
  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean bfin_finish_dynamic_symbol ( bfd output_bfd,
struct bfd_link_info info,
struct elf_link_hash_entry h,
Elf_Internal_Sym *  sym 
) [static]

Definition at line 4985 of file elf32-bfin.c.

{
  bfd *dynobj;

  dynobj = elf_hash_table (info)->dynobj;

  if (h->got.offset != (bfd_vma) - 1)
    {
      asection *sgot;
      asection *srela;
      Elf_Internal_Rela rela;
      bfd_byte *loc;

      /* This symbol has an entry in the global offset table.
         Set it up.  */

      sgot = bfd_get_section_by_name (dynobj, ".got");
      srela = bfd_get_section_by_name (dynobj, ".rela.got");
      BFD_ASSERT (sgot != NULL && srela != NULL);

      rela.r_offset = (sgot->output_section->vma
                     + sgot->output_offset
                     + (h->got.offset & ~(bfd_vma) 1));

      /* If this is a -Bsymbolic link, and the symbol is defined
         locally, we just want to emit a RELATIVE reloc.  Likewise if
         the symbol was forced to be local because of a version file.
         The entry in the global offset table will already have been
         initialized in the relocate_section function.  */
      if (info->shared
         && (info->symbolic
             || h->dynindx == -1 || h->forced_local) && h->def_regular)
       {
         fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
         rela.r_info = ELF32_R_INFO (0, R_pcrel24);
         rela.r_addend = bfd_get_signed_32 (output_bfd,
                                        (sgot->contents
                                         +
                                         (h->got.
                                          offset & ~(bfd_vma) 1)));
       }
      else
       {
         bfd_put_32 (output_bfd, (bfd_vma) 0,
                    sgot->contents + (h->got.offset & ~(bfd_vma) 1));
         rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
         rela.r_addend = 0;
       }

      loc = srela->contents;
      loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
    }

  if (h->needs_copy)
    {
      BFD_ASSERT (0);
    }
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
  if (strcmp (h->root.root.string, "__DYNAMIC") == 0
      || h == elf_hash_table (info)->hgot)
    sym->st_shndx = SHN_ABS;

  return TRUE;
}

Here is the call graph for this function:

static asection* bfin_gc_mark_hook ( asection sec,
struct bfd_link_info info,
Elf_Internal_Rela rel,
struct elf_link_hash_entry h,
Elf_Internal_Sym *  sym 
) [static]

Definition at line 3128 of file elf32-bfin.c.

{
  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_BFIN_GNU_VTINHERIT:
      case R_BFIN_GNU_VTENTRY:
       return NULL;
      }

  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}

Here is the call graph for this function:

static bfd_boolean bfin_gc_sweep_hook ( bfd abfd,
struct bfd_link_info info,
asection sec,
const Elf_Internal_Rela relocs 
) [static]

Definition at line 3148 of file elf32-bfin.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_signed_vma *local_got_refcounts;
  const Elf_Internal_Rela *rel, *relend;
  bfd *dynobj;
  asection *sgot;
  asection *srelgot;

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj == NULL)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  local_got_refcounts = elf_local_got_refcounts (abfd);

  sgot = bfd_get_section_by_name (dynobj, ".got");
  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");

  relend = relocs + sec->reloc_count;
  for (rel = relocs; rel < relend; rel++)
    {
      unsigned long r_symndx;
      struct elf_link_hash_entry *h;

      switch (ELF32_R_TYPE (rel->r_info))
       {
       case R_got:
         r_symndx = ELF32_R_SYM (rel->r_info);
         if (r_symndx >= symtab_hdr->sh_info)
           {
             h = sym_hashes[r_symndx - symtab_hdr->sh_info];
             if (h->got.refcount > 0)
              {
                --h->got.refcount;
                if (h->got.refcount == 0)
                  {
                    /* We don't need the .got entry any more.  */
                    sgot->size -= 4;
                    srelgot->size -= sizeof (Elf32_External_Rela);
                  }
              }
           }
         else if (local_got_refcounts != NULL)
           {
             if (local_got_refcounts[r_symndx] > 0)
              {
                --local_got_refcounts[r_symndx];
                if (local_got_refcounts[r_symndx] == 0)
                  {
                    /* We don't need the .got entry any more.  */
                    sgot->size -= 4;
                    if (info->shared)
                     srelgot->size -= sizeof (Elf32_External_Rela);
                  }
              }
           }
         break;
       default:
         break;
       }
    }
  return TRUE;
}

Here is the call graph for this function:

static bfd_reloc_status_type bfin_imm16_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
PTR  data,
asection input_section,
bfd output_bfd,
char **error_message  ATTRIBUTE_UNUSED 
) [static]

Definition at line 144 of file elf32-bfin.c.

{
  bfd_vma relocation, x;
  bfd_size_type reloc_addr = reloc_entry->address;
  bfd_vma output_base = 0;
  reloc_howto_type *howto = reloc_entry->howto;
  asection *output_section;
  bfd_boolean relocatable = (output_bfd != NULL);

  /* Is the address of the relocation really within the section?  */
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    return bfd_reloc_outofrange;

  if (bfd_is_und_section (symbol->section)
      && (symbol->flags & BSF_WEAK) == 0
      && !relocatable)
    return bfd_reloc_undefined;

  output_section = symbol->section->output_section;
  relocation = symbol->value;

  /* Convert input-section-relative symbol value to absolute.  */
  if (relocatable)
    output_base = 0;
  else
    output_base = output_section->vma;

  if (!relocatable || !strcmp (symbol->name, symbol->section->name))
    relocation += output_base + symbol->section->output_offset;

  /* Add in supplied addend.  */
  relocation += reloc_entry->addend;

  if (relocatable)
    {
      reloc_entry->address += input_section->output_offset;
      reloc_entry->addend += symbol->section->output_offset;
    }
  else
    {
      reloc_entry->addend = 0;
    }

  if (howto->complain_on_overflow != complain_overflow_dont)
    {
      bfd_reloc_status_type flag;
      flag = bfd_check_overflow (howto->complain_on_overflow,
                             howto->bitsize,
                             howto->rightshift,
                             bfd_arch_bits_per_address(abfd),
                             relocation);
      if (flag != bfd_reloc_ok)
       return flag;
    }

  /* Here the variable relocation holds the final address of the
     symbol we are relocating against, plus any addend.  */

  relocation >>= (bfd_vma) howto->rightshift;
  x = relocation;
  bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
  return bfd_reloc_ok;
}

Here is the call graph for this function:

static void bfin_info_to_howto ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent cache_ptr,
Elf_Internal_Rela dst 
) [static]

Definition at line 1044 of file elf32-bfin.c.

{
  unsigned int r_type;

  r_type = ELF32_R_TYPE (dst->r_info);

  if (r_type <= BFIN_RELOC_MAX)
    cache_ptr->howto = &bfin_howto_table [r_type];

  else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
    cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];

  else
    cache_ptr->howto = (reloc_howto_type *) NULL;
}
static bfd_boolean bfin_is_local_label_name ( bfd *abfd  ATTRIBUTE_UNUSED,
const char *  label 
) [static]

Definition at line 1125 of file elf32-bfin.c.

{
  if (label[0] == 'L' && label[1] == '$' )
    return TRUE;

  return _bfd_elf_is_local_label_name (abfd, label);
}

Here is the call graph for this function:

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

Definition at line 4901 of file elf32-bfin.c.

{
  struct bfd_hash_entry *ret = entry;

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

  /* Call the allocation method of the superclass.  */
  ret = _bfd_elf_link_hash_newfunc (ret, table, string);
  if (ret != NULL)
    bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;

  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct bfd_link_hash_table* bfin_link_hash_table_create ( bfd abfd) [static, read]

Definition at line 4924 of file elf32-bfin.c.

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

  ret = bfd_zalloc (abfd, amt);
  if (ret == NULL)
    return NULL;

  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
                                  bfin_link_hash_newfunc,
                                  sizeof (struct elf_link_hash_entry)))
    {
      free (ret);
      return NULL;
    }

  ret->sym_sec.abfd = NULL;

  return &ret->root.root;
}

Here is the call graph for this function:

static bfd_reloc_status_type bfin_pcrel24_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
PTR  data,
asection input_section,
bfd output_bfd,
char **error_message  ATTRIBUTE_UNUSED 
) [static]

Definition at line 47 of file elf32-bfin.c.

{
  bfd_vma relocation;
  bfd_size_type addr = reloc_entry->address;
  bfd_vma output_base = 0;
  reloc_howto_type *howto = reloc_entry->howto;
  asection *output_section;
  bfd_boolean relocatable = (output_bfd != NULL);

  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    return bfd_reloc_outofrange;

  if (bfd_is_und_section (symbol->section)
      && (symbol->flags & BSF_WEAK) == 0
      && !relocatable)
    return bfd_reloc_undefined;

  if (bfd_is_com_section (symbol->section))
    relocation = 0;
  else
    relocation = symbol->value;

  output_section = symbol->section->output_section;

  if (relocatable)
    output_base = 0;
  else
    output_base = output_section->vma;

  if (!relocatable || !strcmp (symbol->name, symbol->section->name))
    relocation += output_base + symbol->section->output_offset;

  if (!relocatable && !strcmp (symbol->name, symbol->section->name))
    relocation += reloc_entry->addend;

  relocation -= input_section->output_section->vma + input_section->output_offset;
  relocation -= reloc_entry->address;

  if (howto->complain_on_overflow != complain_overflow_dont)
    {
      bfd_reloc_status_type status;
      status = bfd_check_overflow (howto->complain_on_overflow,
                               howto->bitsize,
                               howto->rightshift,
                               bfd_arch_bits_per_address(abfd),
                               relocation);
      if (status != bfd_reloc_ok)
       return status;
    }

  /* if rightshift is 1 and the number odd, return error.  */
  if (howto->rightshift && (relocation & 0x01))
    {
      fprintf(stderr, "relocation should be even number\n");
      return bfd_reloc_overflow;
    }

  relocation >>= (bfd_vma) howto->rightshift;
  /* Shift everything up to where it's going to be used.  */

  relocation <<= (bfd_vma) howto->bitpos;

  if (relocatable)
    {
      reloc_entry->address += input_section->output_offset;
      reloc_entry->addend += symbol->section->output_offset;
    }

  {
    short x;

    /* We are getting reloc_entry->address 2 byte off from
       the start of instruction. Assuming absolute postion
       of the reloc data. But, following code had been written assuming
       reloc address is starting at begining of instruction.
       To compensate that I have increased the value of
       relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */

    relocation += 1;
    x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
    x = (x & 0xff00) | ((relocation >> 16) & 0xff);
    bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);

    x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
    x = relocation & 0xFFFF;
    bfd_put_16 (abfd, x, (unsigned char *) data + addr );
  }
  return bfd_reloc_ok;
}

Here is the call graph for this function:

static bfd_reloc_status_type bfin_pltpc_reloc ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent *reloc_entry  ATTRIBUTE_UNUSED,
asymbol *symbol  ATTRIBUTE_UNUSED,
PTR data  ATTRIBUTE_UNUSED,
asection *input_section  ATTRIBUTE_UNUSED,
bfd *output_bfd  ATTRIBUTE_UNUSED,
char **error_message  ATTRIBUTE_UNUSED 
) [static]

Definition at line 32 of file elf32-bfin.c.

{
  bfd_reloc_status_type flag = bfd_reloc_ok;
  return flag;
}
static reloc_howto_type* bfin_reloc_type_lookup ( bfd *abfd  ATTRIBUTE_UNUSED,
unsigned int  r_type 
) [static]

Definition at line 1110 of file elf32-bfin.c.

{
  if (r_type <= BFIN_RELOC_MAX)
    return &bfin_howto_table [r_type];

  else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
   return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];

  return (reloc_howto_type *) NULL;
}

Here is the caller graph for this function:

static bfd_boolean bfin_relocate_section ( bfd output_bfd,
struct bfd_link_info info,
bfd input_bfd,
asection input_section,
bfd_byte contents,
Elf_Internal_Rela relocs,
Elf_Internal_Sym *  local_syms,
asection **  local_sections 
) [static]

Definition at line 2824 of file elf32-bfin.c.

{
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_vma *local_got_offsets;
  asection *sgot;
  asection *sreloc;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  int i = 0;

  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);
  local_got_offsets = elf_local_got_offsets (input_bfd);

  sgot = NULL;
  sreloc = NULL;

  rel = relocs;
  relend = relocs + input_section->reloc_count;
  for (; rel < relend; rel++, i++)
    {
      int r_type;
      reloc_howto_type *howto;
      unsigned long r_symndx;
      struct elf_link_hash_entry *h;
      Elf_Internal_Sym *sym;
      asection *sec;
      bfd_vma relocation = 0;
      bfd_boolean unresolved_reloc;
      bfd_reloc_status_type r;
      bfd_vma address;

      r_type = ELF32_R_TYPE (rel->r_info);
      if (r_type < 0 || r_type >= 243)
       {
         bfd_set_error (bfd_error_bad_value);
         return FALSE;
       }

      if (r_type == R_BFIN_GNU_VTENTRY
          || r_type == R_BFIN_GNU_VTINHERIT)
       continue;

      howto = bfin_reloc_type_lookup (input_bfd, r_type);
      if (howto == NULL)
       {
         bfd_set_error (bfd_error_bad_value);
         return FALSE;
       }
      r_symndx = ELF32_R_SYM (rel->r_info);

      h = NULL;
      sym = NULL;
      sec = NULL;
      unresolved_reloc = FALSE;

      if (r_symndx < symtab_hdr->sh_info)
       {
         sym = local_syms + r_symndx;
         sec = local_sections[r_symndx];
         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
       }
      else
       {
         bfd_boolean warned;

         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                               r_symndx, symtab_hdr, sym_hashes,
                               h, sec, relocation,
                               unresolved_reloc, warned);
       }

      if (sec != NULL && elf_discarded_section (sec))
       {
         /* For relocs against symbols from removed linkonce sections,
            or sections discarded by a linker script, we just want the
            section contents zeroed.  Avoid any special processing.  */
         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
         rel->r_info = 0;
         rel->r_addend = 0;
         continue;
       }

      if (info->relocatable)
       continue;

      address = rel->r_offset;

      /* Then, process normally.  */
      switch (r_type)
       {
       case R_BFIN_GNU_VTINHERIT:
       case R_BFIN_GNU_VTENTRY:
         return bfd_reloc_ok;

       case R_got:
         /* Relocation is to the address of the entry for this symbol
            in the global offset table.  */
         if (h != NULL
             && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
           goto do_default;
         /* Fall through.  */
         /* Relocation is the offset of the entry for this symbol in
            the global offset table.  */

         {
           bfd_vma off;

           if (sgot == NULL)
             {
              sgot = bfd_get_section_by_name (dynobj, ".got");
              BFD_ASSERT (sgot != NULL);
             }

           if (h != NULL)
             {
              bfd_boolean dyn;

              off = h->got.offset;
              BFD_ASSERT (off != (bfd_vma) - 1);
              dyn = elf_hash_table (info)->dynamic_sections_created;

              if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
                  || (info->shared
                     && (info->symbolic
                         || h->dynindx == -1
                         || h->forced_local)
                     && h->def_regular))
                {
                  /* This is actually a static link, or it is a
                     -Bsymbolic link and the symbol is defined
                     locally, or the symbol was forced to be local
                     because of a version file..  We must initialize
                     this entry in the global offset table.  Since
                     the offset must always be a multiple of 4, we
                     use the least significant bit to record whether
                     we have initialized it already.

                     When doing a dynamic link, we create a .rela.got
                     relocation entry to initialize the value.  This
                     is done in the finish_dynamic_symbol routine.  */
                  if ((off & 1) != 0)
                    off &= ~1;
                  else
                    {
                     bfd_put_32 (output_bfd, relocation,
                                sgot->contents + off);
                     h->got.offset |= 1;
                    }
                }
              else
                unresolved_reloc = FALSE;
             }
           else
             {
              BFD_ASSERT (local_got_offsets != NULL);
              off = local_got_offsets[r_symndx];
              BFD_ASSERT (off != (bfd_vma) - 1);

              /* The offset must always be a multiple of 4.  We use
                 the least significant bit to record whether we have
                 already generated the necessary reloc.  */
              if ((off & 1) != 0)
                off &= ~1;
              else
                {
                  bfd_put_32 (output_bfd, relocation, sgot->contents + off);

                  if (info->shared)
                    {
                     asection *s;
                     Elf_Internal_Rela outrel;
                     bfd_byte *loc;

                     s = bfd_get_section_by_name (dynobj, ".rela.got");
                     BFD_ASSERT (s != NULL);

                     outrel.r_offset = (sgot->output_section->vma
                                      + sgot->output_offset + off);
                     outrel.r_info =
                       ELF32_R_INFO (0, R_pcrel24);
                     outrel.r_addend = relocation;
                     loc = s->contents;
                     loc +=
                       s->reloc_count++ * sizeof (Elf32_External_Rela);
                     bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
                    }

                  local_got_offsets[r_symndx] |= 1;
                }
             }

           relocation = sgot->output_offset + off;
           rel->r_addend = 0;
            /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4.  */
            relocation /= 4;
         }
         goto do_default;

       case R_pcrel24:
       case R_pcrel24_jump_l:
         {
           bfd_vma x;

           relocation += rel->r_addend;

           /* Perform usual pc-relative correction.  */
           relocation -= input_section->output_section->vma + input_section->output_offset;
           relocation -= address;

           /* We are getting reloc_entry->address 2 byte off from
              the start of instruction. Assuming absolute postion
              of the reloc data. But, following code had been written assuming
              reloc address is starting at begining of instruction.
              To compensate that I have increased the value of
              relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */

           relocation += 2;
           address -= 2;

           relocation >>= 1;

           x = bfd_get_16 (input_bfd, contents + address);
           x = (x & 0xff00) | ((relocation >> 16) & 0xff);
           bfd_put_16 (input_bfd, x, contents + address);

           x = bfd_get_16 (input_bfd, contents + address + 2);
           x = relocation & 0xFFFF;
           bfd_put_16 (input_bfd, x, contents + address + 2);
           r = bfd_reloc_ok;
         }
         break;

       default:
       do_default:
         r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                   contents, address,
                                   relocation, rel->r_addend);

         break;
       }

      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
         because such sections are not SEC_ALLOC and thus ld.so will
         not process them.  */
      if (unresolved_reloc
         && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
       {
         (*_bfd_error_handler)
           (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
            input_bfd,
            input_section, (long) rel->r_offset, h->root.root.string);
         return FALSE;
       }

      if (r != bfd_reloc_ok)
       {
         const char *name;

         if (h != NULL)
           name = h->root.root.string;
         else
           {
             name = bfd_elf_string_from_elf_section (input_bfd,
                                                symtab_hdr->sh_link,
                                                sym->st_name);
             if (name == NULL)
              return FALSE;
             if (*name == '\0')
              name = bfd_section_name (input_bfd, sec);
           }

         if (r == bfd_reloc_overflow)
           {
             if (!(info->callbacks->reloc_overflow
                  (info, (h ? &h->root : NULL), name, howto->name,
                   (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
              return FALSE;
           }
         else
           {
             (*_bfd_error_handler)
              (_("%B(%A+0x%lx): reloc against `%s': error %d"),
               input_bfd, input_section,
               (long) rel->r_offset, name, (int) r);
             return FALSE;
           }
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean bfin_size_dynamic_sections ( bfd *output_bfd  ATTRIBUTE_UNUSED,
struct bfd_link_info info 
) [static]

Definition at line 5223 of file elf32-bfin.c.

{
  bfd *dynobj;
  asection *s;
  bfd_boolean relocs;

  dynobj = elf_hash_table (info)->dynobj;
  BFD_ASSERT (dynobj != NULL);

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Set the contents of the .interp section to the interpreter.  */
      if (info->executable)
       {
         s = bfd_get_section_by_name (dynobj, ".interp");
         BFD_ASSERT (s != NULL);
         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
         s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
       }
    }
  else
    {
      /* We may have created entries in the .rela.got section.
         However, if we are not creating the dynamic sections, we will
         not actually use these entries.  Reset the size of .rela.got,
         which will cause it to get stripped from the output file
         below.  */
      s = bfd_get_section_by_name (dynobj, ".rela.got");
      if (s != NULL)
       s->size = 0;
    }

  /* If this is a -Bsymbolic shared link, then we need to discard all
     PC relative relocs against symbols defined in a regular object.
     For the normal shared case we discard the PC relative relocs
     against symbols that have become local due to visibility changes.
     We allocated space for them in the check_relocs routine, but we
     will not fill them in in the relocate_section routine.  */
  if (info->shared)
    elf_link_hash_traverse (elf_hash_table (info),
                         bfin_discard_copies, (PTR) info);

  /* The check_relocs and adjust_dynamic_symbol entry points have
     determined the sizes of the various dynamic sections.  Allocate
     memory for them.  */
  relocs = FALSE;
  for (s = dynobj->sections; s != NULL; s = s->next)
    {
      const char *name;
      bfd_boolean strip;

      if ((s->flags & SEC_LINKER_CREATED) == 0)
       continue;

      /* It's OK to base decisions on the section name, because none
         of the dynobj section names depend upon the input files.  */
      name = bfd_get_section_name (dynobj, s);

      strip = FALSE;

       if (CONST_STRNEQ (name, ".rela"))
       {
         if (s->size == 0)
           {
             /* If we don't need this section, strip it from the
                output file.  This is mostly to handle .rela.bss and
                .rela.plt.  We must create both sections in
                create_dynamic_sections, because they must be created
                before the linker maps input sections to output
                sections.  The linker does that before
                adjust_dynamic_symbol is called, and it is that
                function which decides whether anything needs to go
                into these sections.  */
             strip = TRUE;
           }
         else
           {
             relocs = TRUE;

             /* We use the reloc_count field as a counter if we need
                to copy relocs into the output file.  */
             s->reloc_count = 0;
           }
       }
      else if (! CONST_STRNEQ (name, ".got"))
       {
         /* It's not one of our sections, so don't allocate space.  */
         continue;
       }

      if (strip)
       {
         s->flags |= SEC_EXCLUDE;
         continue;
       }

      /* Allocate memory for the section contents.  */
      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
         Unused entries should be reclaimed before the section's contents
         are written out, but at the moment this does not happen.  Thus in
         order to prevent writing out garbage, we initialise the section's
         contents to zero.  */
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
      if (s->contents == NULL && s->size != 0)
       return FALSE;
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add some entries to the .dynamic section.  We fill in the
         values later, in bfin_finish_dynamic_sections, but we
         must add the entries now so that we get the correct size for
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
#define add_dynamic_entry(TAG, VAL) \
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)

      if (!info->shared)
       {
         if (!add_dynamic_entry (DT_DEBUG, 0))
           return FALSE;
       }


      if (relocs)
       {
         if (!add_dynamic_entry (DT_RELA, 0)
             || !add_dynamic_entry (DT_RELASZ, 0)
             || !add_dynamic_entry (DT_RELAENT,
                                 sizeof (Elf32_External_Rela)))
           return FALSE;
       }

      if ((info->flags & DF_TEXTREL) != 0)
       {
         if (!add_dynamic_entry (DT_TEXTREL, 0))
           return FALSE;
       }
    }
#undef add_dynamic_entry

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean bfinfdpic_check_relocs ( bfd abfd,
struct bfd_link_info info,
asection sec,
const Elf_Internal_Rela relocs 
) [static]

Definition at line 4508 of file elf32-bfin.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  bfd *dynobj;
  struct bfinfdpic_relocs_info *picrel;

  if (info->relocatable)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
  if (!elf_bad_symtab (abfd))
    sym_hashes_end -= symtab_hdr->sh_info;

  dynobj = elf_hash_table (info)->dynobj;
  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; rel++)
    {
      struct elf_link_hash_entry *h;
      unsigned long r_symndx;

      r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
      else
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];

      switch (ELF32_R_TYPE (rel->r_info))
       {
       case R_BFIN_GOT17M4:
       case R_BFIN_GOTHI:
       case R_BFIN_GOTLO:
       case R_BFIN_FUNCDESC_GOT17M4:
       case R_BFIN_FUNCDESC_GOTHI:
       case R_BFIN_FUNCDESC_GOTLO:
       case R_BFIN_GOTOFF17M4:
       case R_BFIN_GOTOFFHI:
       case R_BFIN_GOTOFFLO:
       case R_BFIN_FUNCDESC_GOTOFF17M4:
       case R_BFIN_FUNCDESC_GOTOFFHI:
       case R_BFIN_FUNCDESC_GOTOFFLO:
       case R_BFIN_FUNCDESC:
       case R_BFIN_FUNCDESC_VALUE:
         if (! IS_FDPIC (abfd))
           goto bad_reloc;
         /* Fall through.  */
       case R_pcrel24:
       case R_pcrel24_jump_l:
       case R_byte4_data:
         if (IS_FDPIC (abfd) && ! dynobj)
           {
             elf_hash_table (info)->dynobj = dynobj = abfd;
             if (! _bfin_create_got_section (abfd, info))
              return FALSE;
           }
         if (! IS_FDPIC (abfd))
           {
             picrel = NULL;
             break;
           }
         if (h != NULL)
           {
             if (h->dynindx == -1)
              switch (ELF_ST_VISIBILITY (h->other))
                {
                case STV_INTERNAL:
                case STV_HIDDEN:
                  break;
                default:
                  bfd_elf_link_record_dynamic_symbol (info, h);
                  break;
                }
             picrel
              = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
                                             abfd, h,
                                             rel->r_addend, INSERT);
           }
         else
           picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
                                               (info), abfd, r_symndx,
                                               rel->r_addend, INSERT);
         if (! picrel)
           return FALSE;
         break;

       default:
         picrel = NULL;
         break;
       }

      switch (ELF32_R_TYPE (rel->r_info))
        {
       case R_pcrel24:
       case R_pcrel24_jump_l:
         if (IS_FDPIC (abfd))
           picrel->call = 1;
         break;

       case R_BFIN_FUNCDESC_VALUE:
         picrel->relocsfdv++;
         if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
           picrel->relocs32--;
         /* Fall through.  */

       case R_byte4_data:
         if (! IS_FDPIC (abfd))
           break;

         picrel->sym = 1;
         if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
           picrel->relocs32++;
         break;

       case R_BFIN_GOT17M4:
         picrel->got17m4 = 1;
         break;

       case R_BFIN_GOTHI:
       case R_BFIN_GOTLO:
         picrel->gothilo = 1;
         break;

       case R_BFIN_FUNCDESC_GOT17M4:
         picrel->fdgot17m4 = 1;
         break;

       case R_BFIN_FUNCDESC_GOTHI:
       case R_BFIN_FUNCDESC_GOTLO:
         picrel->fdgothilo = 1;
         break;

       case R_BFIN_GOTOFF17M4:
       case R_BFIN_GOTOFFHI:
       case R_BFIN_GOTOFFLO:
         picrel->gotoff = 1;
         break;

       case R_BFIN_FUNCDESC_GOTOFF17M4:
         picrel->fdgoff17m4 = 1;
         break;

       case R_BFIN_FUNCDESC_GOTOFFHI:
       case R_BFIN_FUNCDESC_GOTOFFLO:
         picrel->fdgoffhilo = 1;
         break;

       case R_BFIN_FUNCDESC:
         picrel->fd = 1;
         picrel->relocsfd++;
         break;

        /* This relocation describes the C++ object vtable hierarchy.
           Reconstruct it for later use during GC.  */
        case R_BFIN_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;

        /* This relocation describes which C++ vtable entries are actually
           used.  Record for later use during GC.  */
        case R_BFIN_GNU_VTENTRY:
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;

       case R_huimm16:
       case R_luimm16:
       case R_pcrel12_jump_s:
       case R_pcrel10:
         break;

       default:
       bad_reloc:
         (*_bfd_error_handler)
           (_("%B: unsupported relocation type %i"),
            abfd, ELF32_R_TYPE (rel->r_info));
         return FALSE;
        }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_byte bfinfdpic_elf_encode_eh_address ( bfd abfd,
struct bfd_link_info info,
asection osec,
bfd_vma  offset,
asection loc_sec,
bfd_vma  loc_offset,
bfd_vma encoded 
) [static]

Definition at line 4373 of file elf32-bfin.c.

{
  struct elf_link_hash_entry *h;

  h = elf_hash_table (info)->hgot;
  BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);

  if (! h || (_bfinfdpic_osec_to_segment (abfd, osec)
             == _bfinfdpic_osec_to_segment (abfd, loc_sec->output_section)))
    return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
                                   loc_sec, loc_offset, encoded);

  BFD_ASSERT (_bfinfdpic_osec_to_segment (abfd, osec)
             == (_bfinfdpic_osec_to_segment
                (abfd, h->root.u.def.section->output_section)));

  *encoded = osec->vma + offset
    - (h->root.u.def.value
       + h->root.u.def.section->output_section->vma
       + h->root.u.def.section->output_offset);

  return DW_EH_PE_datarel | DW_EH_PE_sdata4;
}

Here is the call graph for this function:

Definition at line 1189 of file elf32-bfin.c.

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

  ret = bfd_zalloc (abfd, amt);
  if (ret == NULL)
    return NULL;

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

  return &ret->elf.root;
}

Here is the call graph for this function:

static bfd_boolean bfinfdpic_elf_use_relative_eh_frame ( bfd *input_bfd  ATTRIBUTE_UNUSED,
struct bfd_link_info *info  ATTRIBUTE_UNUSED,
asection *eh_frame_section  ATTRIBUTE_UNUSED 
) [static]

Definition at line 4362 of file elf32-bfin.c.

{
  /* We can't use PC-relative encodings in FDPIC binaries, in general.  */
  return FALSE;
}

Definition at line 1401 of file elf32-bfin.c.

{
  e2->got17m4 |= e1->got17m4;
  e2->gothilo |= e1->gothilo;
  e2->fd |= e1->fd;
  e2->fdgot17m4 |= e1->fdgot17m4;
  e2->fdgothilo |= e1->fdgothilo;
  e2->fdgoff17m4 |= e1->fdgoff17m4;
  e2->fdgoffhilo |= e1->fdgoffhilo;
  e2->gotoff |= e1->gotoff;
  e2->call |= e1->call;
  e2->sym |= e1->sym;
}

Here is the caller graph for this function:

static bfd_boolean bfinfdpic_relocate_section ( bfd output_bfd,
struct bfd_link_info info,
bfd input_bfd,
asection input_section,
bfd_byte contents,
Elf_Internal_Rela relocs,
Elf_Internal_Sym *  local_syms,
asection **  local_sections 
) [static]

Definition at line 2119 of file elf32-bfin.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  unsigned isec_segment, got_segment, plt_segment,
    check_segment[2];
  int silence_segment_error = !(info->shared || info->pie);

  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);
  relend     = relocs + input_section->reloc_count;

  isec_segment = _bfinfdpic_osec_to_segment (output_bfd,
                                        input_section->output_section);
  if (IS_FDPIC (output_bfd) && bfinfdpic_got_section (info))
    got_segment = _bfinfdpic_osec_to_segment (output_bfd,
                                         bfinfdpic_got_section (info)
                                         ->output_section);
  else
    got_segment = -1;
  if (IS_FDPIC (output_bfd) && elf_hash_table (info)->dynamic_sections_created)
    plt_segment = _bfinfdpic_osec_to_segment (output_bfd,
                                         bfinfdpic_plt_section (info)
                                         ->output_section);
  else
    plt_segment = -1;

  for (rel = relocs; rel < relend; rel ++)
    {
      reloc_howto_type *howto;
      unsigned long r_symndx;
      Elf_Internal_Sym *sym;
      asection *sec;
      struct elf_link_hash_entry *h;
      bfd_vma relocation;
      bfd_reloc_status_type r;
      const char * name = NULL;
      int r_type;
      asection *osec;
      struct bfinfdpic_relocs_info *picrel;
      bfd_vma orig_addend = rel->r_addend;

      r_type = ELF32_R_TYPE (rel->r_info);

      if (r_type == R_BFIN_GNU_VTINHERIT
         || r_type == R_BFIN_GNU_VTENTRY)
       continue;

      r_symndx = ELF32_R_SYM (rel->r_info);
      howto = bfin_reloc_type_lookup (input_bfd, r_type);
      if (howto == NULL)
       {
         bfd_set_error (bfd_error_bad_value);
         return FALSE;
       }

      h      = NULL;
      sym    = NULL;
      sec    = NULL;

      if (r_symndx < symtab_hdr->sh_info)
       {
         sym = local_syms + r_symndx;
         osec = sec = local_sections [r_symndx];
         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);

         name = bfd_elf_string_from_elf_section
           (input_bfd, symtab_hdr->sh_link, sym->st_name);
         name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
       }
      else
       {
         bfd_boolean warned;
         bfd_boolean unresolved_reloc;

         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                               r_symndx, symtab_hdr, sym_hashes,
                               h, sec, relocation,
                               unresolved_reloc, warned);
         osec = sec;
       }

      if (sec != NULL && elf_discarded_section (sec))
       {
         /* For relocs against symbols from removed linkonce sections,
            or sections discarded by a linker script, we just want the
            section contents zeroed.  Avoid any special processing.  */
         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
         rel->r_info = 0;
         rel->r_addend = 0;
         continue;
       }

      if (info->relocatable)
       continue;

      if (h != NULL
         && (h->root.type == bfd_link_hash_defined
             || h->root.type == bfd_link_hash_defweak)
         && !BFINFDPIC_SYM_LOCAL (info, h))
       {
         osec = sec = NULL;
         relocation = 0;
       }

      switch (r_type)
       {
       case R_pcrel24:
       case R_pcrel24_jump_l:
       case R_byte4_data:
         if (! IS_FDPIC (output_bfd))
           goto non_fdpic;

       case R_BFIN_GOT17M4:
       case R_BFIN_GOTHI:
       case R_BFIN_GOTLO:
       case R_BFIN_FUNCDESC_GOT17M4:
       case R_BFIN_FUNCDESC_GOTHI:
       case R_BFIN_FUNCDESC_GOTLO:
       case R_BFIN_GOTOFF17M4:
       case R_BFIN_GOTOFFHI:
       case R_BFIN_GOTOFFLO:
       case R_BFIN_FUNCDESC_GOTOFF17M4:
       case R_BFIN_FUNCDESC_GOTOFFHI:
       case R_BFIN_FUNCDESC_GOTOFFLO:
       case R_BFIN_FUNCDESC:
       case R_BFIN_FUNCDESC_VALUE:
         if (h != NULL)
           picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info
                                                 (info), input_bfd, h,
                                                 orig_addend, INSERT);
         else
           /* In order to find the entry we created before, we must
              use the original addend, not the one that may have been
              modified by _bfd_elf_rela_local_sym().  */
           picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
                                                (info), input_bfd, r_symndx,
                                                orig_addend, INSERT);
         if (! picrel)
           return FALSE;

         if (!_bfinfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
                                                 osec, sym,
                                                 rel->r_addend))
           {
             (*_bfd_error_handler)
              (_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
               input_bfd, input_section, rel->r_offset, name);
             return FALSE;

           }

         break;

       default:
       non_fdpic:
         picrel = NULL;
         if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
           {
             info->callbacks->warning
              (info, _("relocation references symbol not defined in the module"),
               name, input_bfd, input_section, rel->r_offset);
             return FALSE;
           }
         break;
       }

      switch (r_type)
       {
       case R_pcrel24:
       case R_pcrel24_jump_l:
         check_segment[0] = isec_segment;
         if (! IS_FDPIC (output_bfd))
           check_segment[1] = isec_segment;
         else if (picrel->plt)
           {
             relocation = bfinfdpic_plt_section (info)->output_section->vma
              + bfinfdpic_plt_section (info)->output_offset
              + picrel->plt_entry;
             check_segment[1] = plt_segment;
           }
         /* We don't want to warn on calls to undefined weak symbols,
            as calls to them must be protected by non-NULL tests
            anyway, and unprotected calls would invoke undefined
            behavior.  */
         else if (picrel->symndx == -1
                 && picrel->d.h->root.type == bfd_link_hash_undefweak)
           check_segment[1] = check_segment[0];
         else
           check_segment[1] = sec
             ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
             : (unsigned)-1;
         break;

       case R_BFIN_GOT17M4:
       case R_BFIN_GOTHI:
       case R_BFIN_GOTLO:
         relocation = picrel->got_entry;
         check_segment[0] = check_segment[1] = got_segment;
         break;

       case R_BFIN_FUNCDESC_GOT17M4:
       case R_BFIN_FUNCDESC_GOTHI:
       case R_BFIN_FUNCDESC_GOTLO:
         relocation = picrel->fdgot_entry;
         check_segment[0] = check_segment[1] = got_segment;
         break;

       case R_BFIN_GOTOFFHI:
       case R_BFIN_GOTOFF17M4:
       case R_BFIN_GOTOFFLO:
         relocation -= bfinfdpic_got_section (info)->output_section->vma
           + bfinfdpic_got_section (info)->output_offset
           + bfinfdpic_got_initial_offset (info);
         check_segment[0] = got_segment;
         check_segment[1] = sec
           ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
           : (unsigned)-1;
         break;

       case R_BFIN_FUNCDESC_GOTOFF17M4:
       case R_BFIN_FUNCDESC_GOTOFFHI:
       case R_BFIN_FUNCDESC_GOTOFFLO:
         relocation = picrel->fd_entry;
         check_segment[0] = check_segment[1] = got_segment;
         break;

       case R_BFIN_FUNCDESC:
         {
           int dynindx;
           bfd_vma addend = rel->r_addend;

           if (! (h && h->root.type == bfd_link_hash_undefweak
                 && BFINFDPIC_SYM_LOCAL (info, h)))
             {
              /* If the symbol is dynamic and there may be dynamic
                 symbol resolution because we are or are linked with a
                 shared library, emit a FUNCDESC relocation such that
                 the dynamic linker will allocate the function
                 descriptor.  If the symbol needs a non-local function
                 descriptor but binds locally (e.g., its visibility is
                 protected, emit a dynamic relocation decayed to
                 section+offset.  */
              if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)
                  && BFINFDPIC_SYM_LOCAL (info, h)
                  && !(info->executable && !info->pie))
                {
                  dynindx = elf_section_data (h->root.u.def.section
                                          ->output_section)->dynindx;
                  addend += h->root.u.def.section->output_offset
                    + h->root.u.def.value;
                }
              else if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h))
                {
                  if (addend)
                    {
                     info->callbacks->warning
                       (info, _("R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"),
                        name, input_bfd, input_section, rel->r_offset);
                     return FALSE;
                    }
                  dynindx = h->dynindx;
                }
              else
                {
                  /* Otherwise, we know we have a private function
                     descriptor, so reference it directly.  */
                  BFD_ASSERT (picrel->privfd);
                  r_type = R_byte4_data;
                  dynindx = elf_section_data (bfinfdpic_got_section (info)
                                          ->output_section)->dynindx;
                  addend = bfinfdpic_got_section (info)->output_offset
                    + bfinfdpic_got_initial_offset (info)
                    + picrel->fd_entry;
                }

              /* If there is room for dynamic symbol resolution, emit
                 the dynamic relocation.  However, if we're linking an
                 executable at a fixed location, we won't have emitted a
                 dynamic symbol entry for the got section, so idx will
                 be zero, which means we can and should compute the
                 address of the private descriptor ourselves.  */
              if (info->executable && !info->pie
                  && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
                {
                  addend += bfinfdpic_got_section (info)->output_section->vma;
                  if ((bfd_get_section_flags (output_bfd,
                                          input_section->output_section)
                      & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                    {
                     if (_bfinfdpic_osec_readonly_p (output_bfd,
                                                 input_section
                                                 ->output_section))
                       {
                         info->callbacks->warning
                           (info,
                            _("cannot emit fixups in read-only section"),
                            name, input_bfd, input_section, rel->r_offset);
                         return FALSE;
                       }
                     _bfinfdpic_add_rofixup (output_bfd,
                                          bfinfdpic_gotfixup_section
                                          (info),
                                          _bfd_elf_section_offset
                                          (output_bfd, info,
                                          input_section, rel->r_offset)
                                          + input_section
                                          ->output_section->vma
                                          + input_section->output_offset,
                                          picrel);
                    }
                }
              else if ((bfd_get_section_flags (output_bfd,
                                           input_section->output_section)
                       & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                {
                  bfd_vma offset;

                  if (_bfinfdpic_osec_readonly_p (output_bfd,
                                             input_section
                                             ->output_section))
                    {
                     info->callbacks->warning
                       (info,
                        _("cannot emit dynamic relocations in read-only section"),
                        name, input_bfd, input_section, rel->r_offset);
                     return FALSE;
                    }
                  offset = _bfd_elf_section_offset (output_bfd, info,
                                                input_section, rel->r_offset);
                  /* Only output a reloc for a not deleted entry.  */
                  if (offset >= (bfd_vma) -2)
                    _bfinfdpic_add_dyn_reloc (output_bfd,
                                          bfinfdpic_gotrel_section (info),
                                          0,
                                          R_unused0,
                                          dynindx, addend, picrel);
                  else
                    _bfinfdpic_add_dyn_reloc (output_bfd,
                                          bfinfdpic_gotrel_section (info),
                                          offset + input_section
                                          ->output_section->vma
                                          + input_section->output_offset,
                                          r_type,
                                          dynindx, addend, picrel);
                }
              else
                addend += bfinfdpic_got_section (info)->output_section->vma;
             }

           /* We want the addend in-place because dynamic
              relocations are REL.  Setting relocation to it should
              arrange for it to be installed.  */
           relocation = addend - rel->r_addend;
         }
         check_segment[0] = check_segment[1] = got_segment;
         break;

       case R_byte4_data:
         if (! IS_FDPIC (output_bfd))
           {
             check_segment[0] = check_segment[1] = -1;
             break;
           }
         /* Fall through.  */
       case R_BFIN_FUNCDESC_VALUE:
         {
           int dynindx;
           bfd_vma addend = rel->r_addend;

           /* If the symbol is dynamic but binds locally, use
              section+offset.  */
           if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
             {
              if (addend && r_type == R_BFIN_FUNCDESC_VALUE)
                {
                  info->callbacks->warning
                    (info, _("R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"),
                     name, input_bfd, input_section, rel->r_offset);
                  return FALSE;
                }
              dynindx = h->dynindx;
             }
           else
             {
              if (h)
                addend += h->root.u.def.value;
              else
                addend += sym->st_value;
              if (osec)
                addend += osec->output_offset;
              if (osec && osec->output_section
                  && ! bfd_is_abs_section (osec->output_section)
                  && ! bfd_is_und_section (osec->output_section))
                dynindx = elf_section_data (osec->output_section)->dynindx;
              else
                dynindx = 0;
             }

           /* If we're linking an executable at a fixed address, we
              can omit the dynamic relocation as long as the symbol
              is defined in the current link unit (which is implied
              by its output section not being NULL).  */
           if (info->executable && !info->pie
              && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
             {
              if (osec)
                addend += osec->output_section->vma;
              if (IS_FDPIC (input_bfd)
                  && (bfd_get_section_flags (output_bfd,
                                          input_section->output_section)
                     & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                {
                  if (_bfinfdpic_osec_readonly_p (output_bfd,
                                             input_section
                                             ->output_section))
                    {
                     info->callbacks->warning
                       (info,
                        _("cannot emit fixups in read-only section"),
                        name, input_bfd, input_section, rel->r_offset);
                     return FALSE;
                    }
                  if (!h || h->root.type != bfd_link_hash_undefweak)
                    {
                     _bfinfdpic_add_rofixup (output_bfd,
                                          bfinfdpic_gotfixup_section
                                          (info),
                                          _bfd_elf_section_offset
                                          (output_bfd, info,
                                          input_section, rel->r_offset)
                                          + input_section
                                          ->output_section->vma
                                          + input_section->output_offset,
                                          picrel);
                     if (r_type == R_BFIN_FUNCDESC_VALUE)
                       _bfinfdpic_add_rofixup
                         (output_bfd,
                          bfinfdpic_gotfixup_section (info),
                          _bfd_elf_section_offset
                          (output_bfd, info,
                           input_section, rel->r_offset)
                          + input_section->output_section->vma
                          + input_section->output_offset + 4, picrel);
                    }
                }
             }
           else
             {
              if ((bfd_get_section_flags (output_bfd,
                                       input_section->output_section)
                   & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                {
                  if (_bfinfdpic_osec_readonly_p (output_bfd,
                                             input_section
                                             ->output_section))
                    {
                     info->callbacks->warning
                       (info,
                        _("cannot emit dynamic relocations in read-only section"),
                        name, input_bfd, input_section, rel->r_offset);
                     return FALSE;
                    }
                  _bfinfdpic_add_dyn_reloc (output_bfd,
                                         bfinfdpic_gotrel_section (info),
                                         _bfd_elf_section_offset
                                         (output_bfd, info,
                                          input_section, rel->r_offset)
                                         + input_section
                                         ->output_section->vma
                                         + input_section->output_offset,
                                         r_type, dynindx, addend, picrel);
                }
              else if (osec)
                addend += osec->output_section->vma;
              /* We want the addend in-place because dynamic
                 relocations are REL.  Setting relocation to it
                 should arrange for it to be installed.  */
              relocation = addend - rel->r_addend;
             }

           if (r_type == R_BFIN_FUNCDESC_VALUE)
             {
              /* If we've omitted the dynamic relocation, just emit
                 the fixed addresses of the symbol and of the local
                 GOT base offset.  */
              if (info->executable && !info->pie
                  && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
                bfd_put_32 (output_bfd,
                           bfinfdpic_got_section (info)->output_section->vma
                           + bfinfdpic_got_section (info)->output_offset
                           + bfinfdpic_got_initial_offset (info),
                           contents + rel->r_offset + 4);
              else
                /* A function descriptor used for lazy or local
                   resolving is initialized such that its high word
                   contains the output section index in which the
                   PLT entries are located, and the low word
                   contains the offset of the lazy PLT entry entry
                   point into that section.  */
                bfd_put_32 (output_bfd,
                           h && ! BFINFDPIC_SYM_LOCAL (info, h)
                           ? 0
                           : _bfinfdpic_osec_to_segment (output_bfd,
                                                     sec
                                                     ->output_section),
                           contents + rel->r_offset + 4);
             }
         }
         check_segment[0] = check_segment[1] = got_segment;
         break;

       default:
         check_segment[0] = isec_segment;
         check_segment[1] = sec
           ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
           : (unsigned)-1;
         break;
       }

      if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
       {
#if 1 /* If you take this out, remove the #error from fdpic-static-6.d
        in the ld testsuite.  */
         /* This helps catch problems in GCC while we can't do more
            than static linking.  The idea is to test whether the
            input file basename is crt0.o only once.  */
         if (silence_segment_error == 1)
           silence_segment_error =
             (strlen (input_bfd->filename) == 6
              && strcmp (input_bfd->filename, "crt0.o") == 0)
             || (strlen (input_bfd->filename) > 6
                && strcmp (input_bfd->filename
                          + strlen (input_bfd->filename) - 7,
                          "/crt0.o") == 0)
             ? -1 : 0;
#endif
         if (!silence_segment_error
             /* We don't want duplicate errors for undefined
               symbols.  */
             && !(picrel && picrel->symndx == -1
                 && picrel->d.h->root.type == bfd_link_hash_undefined))
           info->callbacks->warning
             (info,
              (info->shared || info->pie)
              ? _("relocations between different segments are not supported")
              : _("warning: relocation references a different segment"),
              name, input_bfd, input_section, rel->r_offset);
         if (!silence_segment_error && (info->shared || info->pie))
           return FALSE;
         elf_elfheader (output_bfd)->e_flags |= EF_BFIN_PIC;
       }

      switch (r_type)
       {
       case R_BFIN_GOTOFFHI:
         /* We need the addend to be applied before we shift the
            value right.  */
         relocation += rel->r_addend;
         /* Fall through.  */
       case R_BFIN_GOTHI:
       case R_BFIN_FUNCDESC_GOTHI:
       case R_BFIN_FUNCDESC_GOTOFFHI:
         relocation >>= 16;
         /* Fall through.  */

       case R_BFIN_GOTLO:
       case R_BFIN_FUNCDESC_GOTLO:
       case R_BFIN_GOTOFFLO:
       case R_BFIN_FUNCDESC_GOTOFFLO:
         relocation &= 0xffff;
         break;

       default:
         break;
       }

      switch (r_type)
       {
       case R_pcrel24:
       case R_pcrel24_jump_l:
         if (! IS_FDPIC (output_bfd) || ! picrel->plt)
           break;
         /* Fall through.  */

         /* When referencing a GOT entry, a function descriptor or a
            PLT, we don't want the addend to apply to the reference,
            but rather to the referenced symbol.  The actual entry
            will have already been created taking the addend into
            account, so cancel it out here.  */
       case R_BFIN_GOT17M4:
       case R_BFIN_GOTHI:
       case R_BFIN_GOTLO:
       case R_BFIN_FUNCDESC_GOT17M4:
       case R_BFIN_FUNCDESC_GOTHI:
       case R_BFIN_FUNCDESC_GOTLO:
       case R_BFIN_FUNCDESC_GOTOFF17M4:
       case R_BFIN_FUNCDESC_GOTOFFHI:
       case R_BFIN_FUNCDESC_GOTOFFLO:
         /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF17M4
            here, since we do want to apply the addend to the others.
            Note that we've applied the addend to GOTOFFHI before we
            shifted it right.  */
       case R_BFIN_GOTOFFHI:
         relocation -= rel->r_addend;
         break;

       default:
         break;
       }

      if (r_type == R_pcrel24
         || r_type == R_pcrel24_jump_l)
       {
         bfd_vma x;
         bfd_vma address = rel->r_offset;

         relocation += rel->r_addend;

         /* Perform usual pc-relative correction.  */
         relocation -= input_section->output_section->vma + input_section->output_offset;
         relocation -= address;

         /* We are getting reloc_entry->address 2 byte off from
            the start of instruction. Assuming absolute postion
            of the reloc data. But, following code had been written assuming
            reloc address is starting at begining of instruction.
            To compensate that I have increased the value of
            relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */

         relocation += 2;
         address -= 2;

         relocation >>= 1;

         x = bfd_get_16 (input_bfd, contents + address);
         x = (x & 0xff00) | ((relocation >> 16) & 0xff);
         bfd_put_16 (input_bfd, x, contents + address);

         x = bfd_get_16 (input_bfd, contents + address + 2);
         x = relocation & 0xFFFF;
         bfd_put_16 (input_bfd, x, contents + address + 2);
         r = bfd_reloc_ok;
       }
      else
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                  contents, rel->r_offset,
                                  relocation, rel->r_addend);

      if (r != bfd_reloc_ok)
       {
         const char * msg = (const char *) NULL;

         switch (r)
           {
           case bfd_reloc_overflow:
             r = info->callbacks->reloc_overflow
              (info, (h ? &h->root : NULL), name, howto->name,
               (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
             break;

           case bfd_reloc_undefined:
             r = info->callbacks->undefined_symbol
              (info, name, input_bfd, input_section, rel->r_offset, TRUE);
             break;

           case bfd_reloc_outofrange:
             msg = _("internal error: out of range error");
             break;

           case bfd_reloc_notsupported:
             msg = _("internal error: unsupported relocation error");
             break;

           case bfd_reloc_dangerous:
             msg = _("internal error: dangerous relocation");
             break;

           default:
             msg = _("internal error: unknown error");
             break;
           }

         if (msg)
           r = info->callbacks->warning
             (info, msg, name, input_bfd, input_section, rel->r_offset);

         if (! r)
           return FALSE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static int bfinfdpic_relocs_info_eq ( const void *  entry1,
const void *  entry2 
) [static]

Definition at line 1318 of file elf32-bfin.c.

{
  const struct bfinfdpic_relocs_info *e1 = entry1;
  const struct bfinfdpic_relocs_info *e2 = entry2;

  return e1->symndx == e2->symndx && e1->addend == e2->addend
    && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
}

Here is the caller graph for this function:

static struct bfinfdpic_relocs_info* bfinfdpic_relocs_info_find ( struct htab *  ht,
bfd abfd,
const struct bfinfdpic_relocs_info entry,
enum insert_option  insert 
) [static, read]

Definition at line 1331 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info **loc =
    (struct bfinfdpic_relocs_info **) htab_find_slot (ht, entry, insert);

  if (! loc)
    return NULL;

  if (*loc)
    return *loc;

  *loc = bfd_zalloc (abfd, sizeof (**loc));

  if (! *loc)
    return *loc;

  (*loc)->symndx = entry->symndx;
  (*loc)->d = entry->d;
  (*loc)->addend = entry->addend;
  (*loc)->plt_entry = (bfd_vma)-1;
  (*loc)->lzplt_entry = (bfd_vma)-1;

  return *loc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct bfinfdpic_relocs_info* bfinfdpic_relocs_info_for_global ( struct htab *  ht,
bfd abfd,
struct elf_link_hash_entry h,
bfd_vma  addend,
enum insert_option  insert 
) [static, read]

Definition at line 1363 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info entry;

  entry.symndx = -1;
  entry.d.h = h;
  entry.addend = addend;

  return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct bfinfdpic_relocs_info* bfinfdpic_relocs_info_for_local ( struct htab *  ht,
bfd abfd,
long  symndx,
bfd_vma  addend,
enum insert_option  insert 
) [static, read]

Definition at line 1382 of file elf32-bfin.c.

{
  struct bfinfdpic_relocs_info entry;

  entry.symndx = symndx;
  entry.d.abfd = abfd;
  entry.addend = addend;

  return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static hashval_t bfinfdpic_relocs_info_hash ( const void *  entry_) [static]

Definition at line 1306 of file elf32-bfin.c.

{
  const struct bfinfdpic_relocs_info *entry = entry_;

  return (entry->symndx == -1
         ? (long) entry->d.h->root.root.hash
         : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
}

Here is the caller graph for this function:

static bfd_boolean elf32_bfin_merge_private_bfd_data ( bfd ibfd,
bfd obfd 
) [static]

Definition at line 4808 of file elf32-bfin.c.

{
  flagword old_flags, old_partial;
  flagword new_flags, new_partial;
  bfd_boolean error = FALSE;

  new_flags = elf_elfheader (ibfd)->e_flags;
  old_flags = elf_elfheader (obfd)->e_flags;

  if (new_flags & EF_BFIN_FDPIC)
    new_flags &= ~EF_BFIN_PIC;

#ifdef DEBUG
  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
                      old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
                      bfd_get_filename (ibfd));
#endif

  if (!elf_flags_init (obfd))                    /* First call, no flags set.  */
    {
      elf_flags_init (obfd) = TRUE;
      old_flags = new_flags;
    }

  else if (new_flags == old_flags)        /* Compatible flags are ok.  */
    ;

  else                                    /* Possibly incompatible flags.  */
    {
      /* We don't have to do anything if the pic flags are the same, or the new
         module(s) were compiled with -mlibrary-pic.  */
      new_partial = (new_flags & EF_BFIN_PIC_FLAGS);
      old_partial = (old_flags & EF_BFIN_PIC_FLAGS);
      if (new_partial == old_partial)
       ;

      /* If we have mixtures of -fpic and -fPIC, or in both bits.  */
      else if (new_partial != 0 && old_partial != 0)
       old_flags |= new_partial;

      /* One module was compiled for pic and the other was not, see if we have
         had any relocations that are not pic-safe.  */
      else
       old_flags |= new_partial;

    }

  /* Update the old flags now with changes made above.  */
  elf_elfheader (obfd)->e_flags = old_flags;

  if (((new_flags & EF_BFIN_FDPIC) == 0)
      != (! IS_FDPIC (ibfd)))
    {
      error = TRUE;
      if (IS_FDPIC (obfd))
       (*_bfd_error_handler)
         (_("%s: cannot link non-fdpic object file into fdpic executable"),
          bfd_get_filename (ibfd));
      else
       (*_bfd_error_handler)
         (_("%s: cannot link fdpic object file into non-fdpic executable"),
          bfd_get_filename (ibfd));
    }

  if (error)
    bfd_set_error (bfd_error_bad_value);

  return !error;
}

Here is the call graph for this function:

static bfd_boolean elf32_bfin_object_p ( bfd abfd) [static]

Definition at line 4699 of file elf32-bfin.c.

{
  bfd_default_set_arch_mach (abfd, bfd_arch_bfin, 0);
  return (((elf_elfheader (abfd)->e_flags & EF_BFIN_FDPIC) != 0)
         == (IS_FDPIC (abfd)));
}

Here is the call graph for this function:

static bfd_boolean elf32_bfin_print_private_bfd_data ( bfd abfd,
PTR  ptr 
) [static]

Definition at line 4778 of file elf32-bfin.c.

{
  FILE *file = (FILE *) ptr;
  flagword flags;

  BFD_ASSERT (abfd != NULL && ptr != NULL);

  /* Print normal ELF private data.  */
  _bfd_elf_print_private_bfd_data (abfd, ptr);

  flags = elf_elfheader (abfd)->e_flags;

  /* xgettext:c-format */
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);

  if (flags & EF_BFIN_PIC)
    fprintf (file, " -fpic");

  if (flags & EF_BFIN_FDPIC)
    fprintf (file, " -mfdpic");

  fputc ('\n', file);

  return TRUE;
}

Here is the call graph for this function:

Definition at line 2079 of file elf32-bfin.c.

{
  switch ((int) ELF32_R_TYPE (rela->r_info))
    {
    default:
      return reloc_class_normal;
    }
}
static bfd_boolean elf32_bfin_set_private_flags ( bfd abfd,
flagword  flags 
) [static]

Definition at line 4707 of file elf32-bfin.c.

{
  elf_elfheader (abfd)->e_flags = flags;
  elf_flags_init (abfd) = TRUE;
  return TRUE;
}
static bfd_boolean elf32_bfinfdpic_adjust_dynamic_symbol ( struct bfd_link_info *info  ATTRIBUTE_UNUSED,
struct elf_link_hash_entry *h  ATTRIBUTE_UNUSED 
) [static]

Definition at line 4317 of file elf32-bfin.c.

{
  bfd * dynobj;

  dynobj = elf_hash_table (info)->dynobj;

  /* Make sure we know what is going on here.  */
  BFD_ASSERT (dynobj != NULL
             && (h->u.weakdef != NULL
                || (h->def_dynamic
                    && h->ref_regular
                    && !h->def_regular)));

  /* If this is a weak symbol, and there is a real definition, the
     processor independent code will have arranged for us to see the
     real definition first, and we can just use the same value.  */
  if (h->u.weakdef != NULL)
    {
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
                || h->u.weakdef->root.type == bfd_link_hash_defweak);
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
    }

  return TRUE;
}
static bfd_boolean elf32_bfinfdpic_always_size_sections ( bfd output_bfd,
struct bfd_link_info info 
) [static]

Definition at line 4142 of file elf32-bfin.c.

{
  if (!info->relocatable)
    {
      struct elf_link_hash_entry *h;

      /* Force a PT_GNU_STACK segment to be created.  */
      if (! elf_tdata (output_bfd)->stack_flags)
       elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;

      /* Define __stacksize if it's not defined yet.  */
      h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
                            FALSE, FALSE, FALSE);
      if (! h || h->root.type != bfd_link_hash_defined
         || h->type != STT_OBJECT
         || !h->def_regular)
       {
         struct bfd_link_hash_entry *bh = NULL;

         if (!(_bfd_generic_link_add_one_symbol
              (info, output_bfd, "__stacksize",
               BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
               (const char *) NULL, FALSE,
               get_elf_backend_data (output_bfd)->collect, &bh)))
           return FALSE;

         h = (struct elf_link_hash_entry *) bh;
         h->def_regular = 1;
         h->type = STT_OBJECT;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean elf32_bfinfdpic_copy_private_bfd_data ( bfd ibfd,
bfd obfd 
) [static]

Definition at line 4732 of file elf32-bfin.c.

{
  unsigned i;

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

  if (! bfin_elf_copy_private_bfd_data (ibfd, obfd))
    return FALSE;

  if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
      || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
    return TRUE;

  /* Copy the stack size.  */
  for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
    if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
      {
       Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];

       for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
         if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
           {
             memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));

             /* Rewrite the phdrs, since we're only called after they
               were first written.  */
             if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
                         ->s->sizeof_ehdr, SEEK_SET) != 0
                || get_elf_backend_data (obfd)->s
                ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
                                 elf_elfheader (obfd)->e_phnum) != 0)
              return FALSE;
             break;
           }

       break;
      }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 3348 of file elf32-bfin.c.

{
  /* This is mostly copied from
     elflink.c:_bfd_elf_create_dynamic_sections().  */
  flagword flags, pltflags;
  asection *s;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
     .rel[a].bss sections.  */

  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
          | SEC_LINKER_CREATED);

  pltflags = flags;
  pltflags |= SEC_CODE;
  if (bed->plt_not_loaded)
    pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
  if (bed->plt_readonly)
    pltflags |= SEC_READONLY;

  s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
  if (s == NULL
      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
    return FALSE;
  /* Blackfin-specific: remember it.  */
  bfinfdpic_plt_section (info) = s;

  if (bed->want_plt_sym)
    {
      /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
        .plt section.  */
      struct elf_link_hash_entry *h;
      struct bfd_link_hash_entry *bh = NULL;

      if (! (_bfd_generic_link_add_one_symbol
            (info, abfd, "__PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 0, NULL,
             FALSE, get_elf_backend_data (abfd)->collect, &bh)))
       return FALSE;
      h = (struct elf_link_hash_entry *) bh;
      h->def_regular = 1;
      h->type = STT_OBJECT;

      if (! info->executable
         && ! bfd_elf_link_record_dynamic_symbol (info, h))
       return FALSE;
    }

  /* Blackfin-specific: we want rel relocations for the plt.  */
  s = bfd_make_section_with_flags (abfd, ".rel.plt", flags | SEC_READONLY);
  if (s == NULL
      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
    return FALSE;
  /* Blackfin-specific: remember it.  */
  bfinfdpic_pltrel_section (info) = s;

  /* Blackfin-specific: we want to create the GOT in the Blackfin way.  */
  if (! _bfin_create_got_section (abfd, info))
    return FALSE;

  /* Blackfin-specific: make sure we created everything we wanted.  */
  BFD_ASSERT (bfinfdpic_got_section (info) && bfinfdpic_gotrel_section (info)
             /* && bfinfdpic_gotfixup_section (info) */
             && bfinfdpic_plt_section (info)
             && bfinfdpic_pltrel_section (info));

  if (bed->want_dynbss)
    {
      /* The .dynbss section is a place to put symbols which are defined
        by dynamic objects, are referenced by regular objects, and are
        not functions.  We must allocate space for them in the process
        image and use a R_*_COPY reloc to tell the dynamic linker to
        initialize them at run time.  The linker script puts the .dynbss
        section into the .bss section of the final image.  */
      s = bfd_make_section_with_flags (abfd, ".dynbss",
                                   SEC_ALLOC | SEC_LINKER_CREATED);
      if (s == NULL)
       return FALSE;

      /* The .rel[a].bss section holds copy relocs.  This section is not
     normally needed.  We need to create it here, though, so that the
     linker will map it to an output section.  We can't just create it
     only if we need it, because we will not know whether we need it
     until we have seen all the input files, and the first time the
     main linker code calls BFD after examining all the input files
     (size_dynamic_sections) the input sections have already been
     mapped to the output sections.  If the section turns out not to
     be needed, we can discard it later.  We will never need this
     section when generating a shared object, since they do not use
     copy relocs.  */
      if (! info->shared)
       {
         s = bfd_make_section_with_flags (abfd,
                                      (bed->default_use_rela_p
                                       ? ".rela.bss" : ".rel.bss"),
                                      flags | SEC_READONLY);
         if (s == NULL
             || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
           return FALSE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean elf32_bfinfdpic_finish_dynamic_sections ( bfd output_bfd,
struct bfd_link_info info 
) [static]

Definition at line 4224 of file elf32-bfin.c.

{
  bfd *dynobj;
  asection *sdyn;

  dynobj = elf_hash_table (info)->dynobj;

  if (bfinfdpic_got_section (info))
    {
      BFD_ASSERT (bfinfdpic_gotrel_section (info)->size
                == (bfinfdpic_gotrel_section (info)->reloc_count
                    * sizeof (Elf32_External_Rel)));

      if (bfinfdpic_gotfixup_section (info))
       {
         struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
         bfd_vma got_value = hgot->root.u.def.value
           + hgot->root.u.def.section->output_section->vma
           + hgot->root.u.def.section->output_offset;

         _bfinfdpic_add_rofixup (output_bfd, bfinfdpic_gotfixup_section (info),
                             got_value, 0);

         if (bfinfdpic_gotfixup_section (info)->size
             != (bfinfdpic_gotfixup_section (info)->reloc_count * 4))
           {
             (*_bfd_error_handler)
              ("LINKER BUG: .rofixup section size mismatch");
             return FALSE;
           }
       }
    }
  if (elf_hash_table (info)->dynamic_sections_created)
    {
      BFD_ASSERT (bfinfdpic_pltrel_section (info)->size
                == (bfinfdpic_pltrel_section (info)->reloc_count
                    * sizeof (Elf32_External_Rel)));
    }

  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      Elf32_External_Dyn * dyncon;
      Elf32_External_Dyn * dynconend;

      BFD_ASSERT (sdyn != NULL);

      dyncon = (Elf32_External_Dyn *) sdyn->contents;
      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);

      for (; dyncon < dynconend; dyncon++)
       {
         Elf_Internal_Dyn dyn;

         bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);

         switch (dyn.d_tag)
           {
           default:
             break;

           case DT_PLTGOT:
             dyn.d_un.d_ptr = bfinfdpic_got_section (info)->output_section->vma
              + bfinfdpic_got_section (info)->output_offset
              + bfinfdpic_got_initial_offset (info);
             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
             break;

           case DT_JMPREL:
             dyn.d_un.d_ptr = bfinfdpic_pltrel_section (info)
              ->output_section->vma
              + bfinfdpic_pltrel_section (info)->output_offset;
             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
             break;

           case DT_PLTRELSZ:
             dyn.d_un.d_val = bfinfdpic_pltrel_section (info)->size;
             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
             break;
           }
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean elf32_bfinfdpic_finish_dynamic_symbol ( bfd *output_bfd  ATTRIBUTE_UNUSED,
struct bfd_link_info *info  ATTRIBUTE_UNUSED,
struct elf_link_hash_entry *h  ATTRIBUTE_UNUSED,
Elf_Internal_Sym *sym  ATTRIBUTE_UNUSED 
) [static]

Definition at line 4349 of file elf32-bfin.c.

{
  return TRUE;
}
static bfd_boolean elf32_bfinfdpic_modify_program_headers ( bfd output_bfd,
struct bfd_link_info info 
) [static]

Definition at line 4179 of file elf32-bfin.c.

{
  struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
  struct elf_segment_map *m;
  Elf_Internal_Phdr *p;

  /* objcopy and strip preserve what's already there using
     elf32_bfinfdpic_copy_private_bfd_data ().  */
  if (! info)
    return TRUE;

  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
    if (m->p_type == PT_GNU_STACK)
      break;

  if (m)
    {
      struct elf_link_hash_entry *h;

      /* Obtain the pointer to the __stacksize symbol.  */
      h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
                            FALSE, FALSE, FALSE);
      if (h)
       {
         while (h->root.type == bfd_link_hash_indirect
               || h->root.type == bfd_link_hash_warning)
           h = (struct elf_link_hash_entry *) h->root.u.i.link;
         BFD_ASSERT (h->root.type == bfd_link_hash_defined);
       }

      /* Set the header p_memsz from the symbol value.  We
        intentionally ignore the symbol section.  */
      if (h && h->root.type == bfd_link_hash_defined)
       p->p_memsz = h->root.u.def.value;
      else
       p->p_memsz = DEFAULT_STACK_SIZE;

      p->p_align = 8;
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean elf32_bfinfdpic_size_dynamic_sections ( bfd output_bfd,
struct bfd_link_info info 
) [static]

Definition at line 3926 of file elf32-bfin.c.

{
  bfd *dynobj;
  asection *s;
  struct _bfinfdpic_dynamic_got_plt_info gpinfo;
  bfd_signed_vma odd;
  bfd_vma limit;

  dynobj = elf_hash_table (info)->dynobj;
  BFD_ASSERT (dynobj != NULL);

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Set the contents of the .interp section to the interpreter.  */
      if (info->executable)
       {
         s = bfd_get_section_by_name (dynobj, ".interp");
         BFD_ASSERT (s != NULL);
         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
         s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
       }
    }

  memset (&gpinfo, 0, sizeof (gpinfo));
  gpinfo.g.info = info;

  for (;;)
    {
      htab_t relocs = bfinfdpic_relocs_info (info);

      htab_traverse (relocs, _bfinfdpic_resolve_final_relocs_info, &relocs);

      if (relocs == bfinfdpic_relocs_info (info))
       break;
    }

  htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_count_got_plt_entries,
               &gpinfo.g);

  odd = 12;
  /* Compute the total size taken by entries in the 18-bit range,
     to tell how many PLT function descriptors we can bring into it
     without causing it to overflow.  */
  limit = odd + gpinfo.g.got17m4 + gpinfo.g.fd17m4;
  if (limit < (bfd_vma)1 << 18)
    limit = ((bfd_vma)1 << 18) - limit;
  else
    limit = 0;
  if (gpinfo.g.fdplt < limit)
    limit = gpinfo.g.fdplt;

  /* Determine the ranges of GOT offsets that we can use for each
     range of addressing modes.  */
  odd = _bfinfdpic_compute_got_alloc_data (&gpinfo.got17m4,
                                     0,
                                     odd,
                                     16,
                                     gpinfo.g.got17m4,
                                     gpinfo.g.fd17m4,
                                     limit,
                                     (bfd_vma)1 << (18-1));
  odd = _bfinfdpic_compute_got_alloc_data (&gpinfo.gothilo,
                                     gpinfo.got17m4.min,
                                     odd,
                                     gpinfo.got17m4.max,
                                     gpinfo.g.gothilo,
                                     gpinfo.g.fdhilo,
                                     gpinfo.g.fdplt - gpinfo.got17m4.fdplt,
                                     (bfd_vma)1 << (32-1));

  /* Now assign (most) GOT offsets.  */
  htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_got_entries,
               &gpinfo);

  bfinfdpic_got_section (info)->size = gpinfo.gothilo.max
    - gpinfo.gothilo.min
    /* If an odd word is the last word of the GOT, we don't need this
       word to be part of the GOT.  */
    - (odd + 4 == gpinfo.gothilo.max ? 4 : 0);
  if (bfinfdpic_got_section (info)->size == 0)
    bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
  else if (bfinfdpic_got_section (info)->size == 12
          && ! elf_hash_table (info)->dynamic_sections_created)
    {
      bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
      bfinfdpic_got_section (info)->size = 0;
    }
  else
    {
      bfinfdpic_got_section (info)->contents =
       (bfd_byte *) bfd_zalloc (dynobj,
                             bfinfdpic_got_section (info)->size);
      if (bfinfdpic_got_section (info)->contents == NULL)
       return FALSE;
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    /* Subtract the number of lzplt entries, since those will generate
       relocations in the pltrel section.  */
    bfinfdpic_gotrel_section (info)->size =
      (gpinfo.g.relocs - gpinfo.g.lzplt / LZPLT_NORMAL_SIZE)
      * get_elf_backend_data (output_bfd)->s->sizeof_rel;
  else
    BFD_ASSERT (gpinfo.g.relocs == 0);
  if (bfinfdpic_gotrel_section (info)->size == 0)
    bfinfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
  else
    {
      bfinfdpic_gotrel_section (info)->contents =
       (bfd_byte *) bfd_zalloc (dynobj,
                             bfinfdpic_gotrel_section (info)->size);
      if (bfinfdpic_gotrel_section (info)->contents == NULL)
       return FALSE;
    }

  bfinfdpic_gotfixup_section (info)->size = (gpinfo.g.fixups + 1) * 4;
  if (bfinfdpic_gotfixup_section (info)->size == 0)
    bfinfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
  else
    {
      bfinfdpic_gotfixup_section (info)->contents =
       (bfd_byte *) bfd_zalloc (dynobj,
                             bfinfdpic_gotfixup_section (info)->size);
      if (bfinfdpic_gotfixup_section (info)->contents == NULL)
       return FALSE;
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfinfdpic_pltrel_section (info)->size =
       gpinfo.g.lzplt / LZPLT_NORMAL_SIZE * get_elf_backend_data (output_bfd)->s->sizeof_rel;
      if (bfinfdpic_pltrel_section (info)->size == 0)
       bfinfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
      else
       {
         bfinfdpic_pltrel_section (info)->contents =
           (bfd_byte *) bfd_zalloc (dynobj,
                                 bfinfdpic_pltrel_section (info)->size);
         if (bfinfdpic_pltrel_section (info)->contents == NULL)
           return FALSE;
       }
    }

  /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
     such that there's room for the additional instruction needed to
     call the resolver.  Since _bfinfdpic_assign_got_entries didn't
     account for them, our block size is 4 bytes smaller than the real
     block size.  */
  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfinfdpic_plt_section (info)->size = gpinfo.g.lzplt
       + ((gpinfo.g.lzplt + (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) - LZPLT_NORMAL_SIZE)
          / (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) * LZPLT_RESOLVER_EXTRA);
    }

  /* Reset it, such that _bfinfdpic_assign_plt_entries() can use it to
     actually assign lazy PLT entries addresses.  */
  gpinfo.g.lzplt = 0;

  /* Save information that we're going to need to generate GOT and PLT
     entries.  */
  bfinfdpic_got_initial_offset (info) = -gpinfo.gothilo.min;

  if (get_elf_backend_data (output_bfd)->want_got_sym)
    elf_hash_table (info)->hgot->root.u.def.value
      += bfinfdpic_got_initial_offset (info);

  if (elf_hash_table (info)->dynamic_sections_created)
    bfinfdpic_plt_initial_offset (info) =
      bfinfdpic_plt_section (info)->size;

  htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_plt_entries,
               &gpinfo);

  /* Allocate the PLT section contents only after
     _bfinfdpic_assign_plt_entries has a chance to add the size of the
     non-lazy PLT entries.  */
  if (elf_hash_table (info)->dynamic_sections_created)
    {
      if (bfinfdpic_plt_section (info)->size == 0)
       bfinfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
      else
       {
         bfinfdpic_plt_section (info)->contents =
           (bfd_byte *) bfd_zalloc (dynobj,
                                 bfinfdpic_plt_section (info)->size);
         if (bfinfdpic_plt_section (info)->contents == NULL)
           return FALSE;
       }
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      if (bfinfdpic_got_section (info)->size)
       if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
         return FALSE;

      if (bfinfdpic_pltrel_section (info)->size)
       if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
           || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
           || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
         return FALSE;

      if (bfinfdpic_gotrel_section (info)->size)
       if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
           || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
           || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
                                       sizeof (Elf32_External_Rel)))
         return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:


Variable Documentation

reloc_howto_type bfin_gnuext_howto_table[] [static]

Definition at line 932 of file elf32-bfin.c.

reloc_howto_type bfin_howto_table[] [static]

Definition at line 421 of file elf32-bfin.c.

struct bfin_reloc_map[] [static]

Definition at line 999 of file elf32-bfin.c.