Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Functions | Variables
elfxx-mips.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libiberty.h"
#include "elf-bfd.h"
#include "elfxx-mips.h"
#include "elf/mips.h"
#include "elf-vxworks.h"
#include "coff/sym.h"
#include "coff/symconst.h"
#include "coff/ecoff.h"
#include "coff/mips.h"
#include "hashtab.h"

Go to the source code of this file.

Classes

struct  mips_got_entry
struct  mips_got_info
struct  mips_elf_bfd2got_hash
struct  mips_elf_got_per_bfd_arg
struct  mips_elf_set_global_got_offset_arg
struct  mips_elf_count_tls_arg
struct  _mips_elf_section_data
struct  mips_elf_hash_sort_data
struct  mips_elf_link_hash_entry
struct  extsym_info
struct  Elf32_compact_rel
struct  Elf32_External_compact_rel
struct  Elf32_crinfo
struct  Elf32_crinfo2
struct  Elf32_External_crinfo
struct  Elf32_External_crinfo2
struct  runtime_pdr
struct  mips_hi16
struct  mips_elf_find_line
struct  mips_mach_extension
union  mips_got_entry.d
union  _mips_elf_section_data.u

Defines

#define mips_elf_section_data(sec)   ((struct _mips_elf_section_data *) elf_section_data (sec))
#define GOT_NORMAL   0
#define GOT_TLS_GD   1
#define GOT_TLS_LDM   2
#define GOT_TLS_IE   4
#define GOT_TLS_OFFSET_DONE   0x40
#define GOT_TLS_DONE   0x80
#define TLS_RELOC_P(r_type)
#define CRINFO_CTYPE   (0x1)
#define CRINFO_CTYPE_SH   (31)
#define CRINFO_RTYPE   (0xf)
#define CRINFO_RTYPE_SH   (27)
#define CRINFO_DIST2TO   (0xff)
#define CRINFO_DIST2TO_SH   (19)
#define CRINFO_RELVADDR   (0x7ffff)
#define CRINFO_RELVADDR_SH   (0)
#define CRF_MIPS_LONG   1
#define CRF_MIPS_SHORT   0
#define CRT_MIPS_REL32   0xa
#define CRT_MIPS_WORD   0xb
#define CRT_MIPS_GPHI_LO   0xc
#define CRT_MIPS_JMPAD   0xd
#define mips_elf_set_cr_format(x, format)   ((x).ctype = (format))
#define mips_elf_set_cr_type(x, type)   ((x).rtype = (type))
#define mips_elf_set_cr_dist2to(x, v)   ((x).dist2to = (v))
#define mips_elf_set_cr_relvaddr(x, d)   ((x).relvaddr = (d)<<2)
#define cbRPDR   sizeof (RPDR)
#define rpdNil   ((pRPDR) 0)
#define ABI_N32_P(abfd)   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
#define ABI_64_P(abfd)   (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
#define NEWABI_P(abfd)   (ABI_N32_P (abfd) || ABI_64_P (abfd))
#define IRIX_COMPAT(abfd)   (get_elf_backend_data (abfd)->elf_backend_mips_irix_compat (abfd))
#define SGI_COMPAT(abfd)   (IRIX_COMPAT (abfd) != ict_none)
#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd)   (NEWABI_P (abfd) ? ".MIPS.options" : ".options")
#define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME)   (strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)
#define MIPS_ELF_READONLY_SECTION(sec)
#define MIPS_ELF_STUB_SECTION_NAME(abfd)   ".MIPS.stubs"
#define MIPS_ELF_REL_SIZE(abfd)   (get_elf_backend_data (abfd)->s->sizeof_rel)
#define MIPS_ELF_RELA_SIZE(abfd)   (get_elf_backend_data (abfd)->s->sizeof_rela)
#define MIPS_ELF_DYN_SIZE(abfd)   (get_elf_backend_data (abfd)->s->sizeof_dyn)
#define MIPS_ELF_GOT_SIZE(abfd)   (get_elf_backend_data (abfd)->s->arch_size / 8)
#define MIPS_ELF_SYM_SIZE(abfd)   (get_elf_backend_data (abfd)->s->sizeof_sym)
#define MIPS_ELF_LOG_FILE_ALIGN(abfd)   (get_elf_backend_data (abfd)->s->log_file_align)
#define MIPS_ELF_GET_WORD(abfd, ptr)   (ABI_64_P (abfd) ? bfd_get_64 (abfd, ptr) : bfd_get_32 (abfd, ptr))
#define MIPS_ELF_PUT_WORD(abfd, val, ptr)
#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)   _bfd_elf_add_dynamic_entry (info, tag, val)
#define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela)   (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
#define MIPS_RELOC_RELA_P(abfd, sec, rel_idx)
#define MIPS_ELF_REL_DYN_NAME(INFO)   (mips_elf_hash_table (INFO)->is_vxworks ? ".rela.dyn" : ".rel.dyn")
#define MINUS_ONE   (((bfd_vma)0) - 1)
#define MINUS_TWO   (((bfd_vma)0) - 2)
#define MIPS_RESERVED_GOTNO(INFO)   (mips_elf_hash_table (INFO)->is_vxworks ? 3 : 2)
#define ELF_MIPS_GP_OFFSET(INFO)   (mips_elf_hash_table (INFO)->is_vxworks ? 0x0 : 0x7ff0)
#define MIPS_ELF_GOT_MAX_SIZE(INFO)   (ELF_MIPS_GP_OFFSET (INFO) + 0x7fff)
#define STUB_LW(abfd)
#define STUB_MOVE(abfd)
#define STUB_LUI(VAL)   (0x3c180000 + (VAL)) /* lui t8,VAL */
#define STUB_JALR   0x0320f809 /* jalr t9,ra */
#define STUB_ORI(VAL)   (0x37180000 + (VAL)) /* ori t8,t8,VAL */
#define STUB_LI16U(VAL)   (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned */
#define STUB_LI16S(abfd, VAL)
#define MIPS_FUNCTION_STUB_NORMAL_SIZE   16
#define MIPS_FUNCTION_STUB_BIG_SIZE   20
#define ELF_DYNAMIC_INTERPRETER(abfd)
#define MNAME(bfd, pre, pos)   CONCAT4 (pre,32,_,pos)
#define ELF_R_SYM(bfd, i)   (ELF32_R_SYM (i))
#define ELF_R_TYPE(bfd, i)   (ELF32_R_TYPE (i))
#define ELF_R_INFO(bfd, s, t)   (ELF32_R_INFO (s, t))
#define FN_STUB   ".mips16.fn."
#define CALL_STUB   ".mips16.call."
#define CALL_FP_STUB   ".mips16.call.fp."
#define FN_STUB_P(name)   CONST_STRNEQ (name, FN_STUB)
#define CALL_STUB_P(name)   CONST_STRNEQ (name, CALL_STUB)
#define CALL_FP_STUB_P(name)   CONST_STRNEQ (name, CALL_FP_STUB)
#define mips_elf_link_hash_lookup(table, string, create, copy, follow)
#define mips_elf_link_hash_traverse(table, func, info)
#define mips_elf_hash_table(p)   ((struct mips_elf_link_hash_table *) ((p)->hash))
#define TP_OFFSET   0x7000
#define DTP_OFFSET   0x8000
#define READ(ptr, offset, count, size, type)
#define PDR_SIZE   32

Typedefs

typedef struct runtime_pdr RPDR
typedef struct runtime_pdrpRPDR

Functions

static struct mips_got_entrymips_elf_create_local_got_entry (bfd *, struct bfd_link_info *, bfd *, struct mips_got_info *, asection *, asection *, bfd_vma, unsigned long, struct mips_elf_link_hash_entry *, int)
static bfd_boolean mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *, void *)
static bfd_vma mips_elf_high (bfd_vma)
static bfd_boolean mips16_stub_section_p (bfd *, asection *)
static bfd_boolean mips_elf_create_dynamic_relocation (bfd *, struct bfd_link_info *, const Elf_Internal_Rela *, struct mips_elf_link_hash_entry *, asection *, bfd_vma, bfd_vma *, asection *)
static hashval_t mips_elf_got_entry_hash (const void *)
static bfd_vma mips_elf_adjust_gp (bfd *, struct mips_got_info *, bfd *)
static struct mips_got_infomips_elf_got_for_ibfd (struct mips_got_info *, bfd *)
static bfd_vma dtprel_base (struct bfd_link_info *info)
static bfd_vma tprel_base (struct bfd_link_info *info)
static struct bfd_hash_entrymips_elf_link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string)
bfd_boolean _bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
bfd_boolean _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section, struct ecoff_debug_info *debug)
static void ecoff_swap_rpdr_out (bfd *abfd, const RPDR *in, struct rpdr_ext *ex)
static bfd_boolean mips_elf_create_procedure_table (void *handle, bfd *abfd, struct bfd_link_info *info, asection *s, struct ecoff_debug_info *debug)
static bfd_boolean mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h, void *data ATTRIBUTE_UNUSED)
void _bfd_mips16_elf_reloc_unshuffle (bfd *abfd, int r_type, bfd_boolean jal_shuffle, bfd_byte *data)
void _bfd_mips16_elf_reloc_shuffle (bfd *abfd, int r_type, bfd_boolean jal_shuffle, bfd_byte *data)
bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, asection *input_section, bfd_boolean relocatable, void *data, bfd_vma gp)
bfd_reloc_status_type _bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, asymbol *symbol ATTRIBUTE_UNUSED, void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
bfd_reloc_status_type _bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data, asection *input_section, bfd *output_bfd, char **error_message)
bfd_reloc_status_type _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data, asection *input_section, bfd *output_bfd, char **error_message)
bfd_reloc_status_type _bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, asymbol *symbol, void *data ATTRIBUTE_UNUSED, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
static void bfd_mips_elf32_swap_gptab_in (bfd *abfd, const Elf32_External_gptab *ex, Elf32_gptab *in)
static void bfd_mips_elf32_swap_gptab_out (bfd *abfd, const Elf32_gptab *in, Elf32_External_gptab *ex)
static void bfd_elf32_swap_compact_rel_out (bfd *abfd, const Elf32_compact_rel *in, Elf32_External_compact_rel *ex)
static void bfd_elf32_swap_crinfo_out (bfd *abfd, const Elf32_crinfo *in, Elf32_External_crinfo *ex)
void bfd_mips_elf32_swap_reginfo_in (bfd *abfd, const Elf32_External_RegInfo *ex, Elf32_RegInfo *in)
void bfd_mips_elf32_swap_reginfo_out (bfd *abfd, const Elf32_RegInfo *in, Elf32_External_RegInfo *ex)
void bfd_mips_elf64_swap_reginfo_in (bfd *abfd, const Elf64_External_RegInfo *ex, Elf64_Internal_RegInfo *in)
void bfd_mips_elf64_swap_reginfo_out (bfd *abfd, const Elf64_Internal_RegInfo *in, Elf64_External_RegInfo *ex)
void bfd_mips_elf_swap_options_in (bfd *abfd, const Elf_External_Options *ex, Elf_Internal_Options *in)
void bfd_mips_elf_swap_options_out (bfd *abfd, const Elf_Internal_Options *in, Elf_External_Options *ex)
static int sort_dynamic_relocs (const void *arg1, const void *arg2)
static int sort_dynamic_relocs_64 (const void *arg1 ATTRIBUTE_UNUSED, const void *arg2 ATTRIBUTE_UNUSED)
static bfd_boolean mips_elf_output_extsym (struct mips_elf_link_hash_entry *h, void *data)
static int gptab_compare (const void *p1, const void *p2)
static INLINE hashval_t mips_elf_hash_bfd_vma (bfd_vma addr)
static int mips_elf_got_entry_eq (const void *entry1, const void *entry2)
static hashval_t mips_elf_multi_got_entry_hash (const void *entry_)
static int mips_elf_multi_got_entry_eq (const void *entry1, const void *entry2)
static asectionmips_elf_rel_dyn_section (struct bfd_link_info *info, bfd_boolean create_p)
static asectionmips_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
static struct mips_got_infomips_elf_got_info (bfd *abfd, asection **sgotp)
static int mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type, struct elf_link_hash_entry *h)
static int mips_elf_count_local_tls_relocs (void **arg1, void *arg2)
static int mips_elf_count_global_tls_entries (void *arg1, void *arg2)
static int mips_elf_count_global_tls_relocs (void *arg1, void *arg2)
static void mips_elf_output_dynamic_relocation (bfd *output_bfd, asection *sreloc, unsigned long indx, int r_type, bfd_vma offset)
static void mips_elf_initialize_tls_slots (bfd *abfd, bfd_vma got_offset, unsigned char *tls_type_p, struct bfd_link_info *info, struct mips_elf_link_hash_entry *h, bfd_vma value)
static bfd_vma mips_tls_got_index (bfd *abfd, bfd_vma got_index, unsigned char *tls_type, int r_type, struct bfd_link_info *info, struct mips_elf_link_hash_entry *h, bfd_vma symbol)
static bfd_vma mips_elf_gotplt_index (struct bfd_link_info *info, struct elf_link_hash_entry *h)
static bfd_vma mips_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, asection *input_section, bfd_vma value, unsigned long r_symndx, struct mips_elf_link_hash_entry *h, int r_type)
static bfd_vma mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h, int r_type, struct bfd_link_info *info)
static bfd_vma mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, asection *input_section, bfd_vma value, bfd_vma *offsetp)
static bfd_vma mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, asection *input_section, bfd_vma value, bfd_boolean external)
static bfd_vma mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd, bfd *input_bfd, bfd_vma index)
static bfd_boolean mips_elf_sort_hash_table (struct bfd_link_info *info, unsigned long max_local)
static bfd_boolean mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h, bfd *abfd, struct bfd_link_info *info, struct mips_got_info *g, unsigned char tls_flag)
static bfd_boolean mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend, struct mips_got_info *g, unsigned char tls_flag)
static hashval_t mips_elf_bfd2got_entry_hash (const void *entry_)
static int mips_elf_bfd2got_entry_eq (const void *entry1, const void *entry2)
static int mips_elf_make_got_per_bfd (void **entryp, void *p)
static int mips_elf_merge_gots (void **bfd2got_, void *p)
static int mips_elf_initialize_tls_index (void **entryp, void *p)
static int mips_elf_set_global_got_offset (void **entryp, void *p)
static int mips_elf_set_no_stub (void **entryp, void *p ATTRIBUTE_UNUSED)
static int mips_elf_resolve_final_got_entry (void **entryp, void *p)
static void mips_elf_resolve_final_got_entries (struct mips_got_info *g)
static bfd_boolean mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info, struct mips_got_info *g, asection *got, bfd_size_type pages)
static const Elf_Internal_Relamips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type, const Elf_Internal_Rela *relocation, const Elf_Internal_Rela *relend)
static bfd_boolean mips_elf_local_relocation_p (bfd *input_bfd, const Elf_Internal_Rela *relocation, asection **local_sections, bfd_boolean check_forced)
bfd_vma _bfd_mips_elf_sign_extend (bfd_vma value, int bits)
static bfd_boolean mips_elf_overflow_p (bfd_vma value, int bits)
static bfd_vma mips_elf_higher (bfd_vma value ATTRIBUTE_UNUSED)
static bfd_vma mips_elf_highest (bfd_vma value ATTRIBUTE_UNUSED)
static bfd_boolean mips_elf_create_compact_rel_section (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
static bfd_boolean mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info, bfd_boolean maybe_exclude)
static bfd_boolean is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
static bfd_reloc_status_type mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, asection *input_section, struct bfd_link_info *info, const Elf_Internal_Rela *relocation, bfd_vma addend, reloc_howto_type *howto, Elf_Internal_Sym *local_syms, asection **local_sections, bfd_vma *valuep, const char **namep, bfd_boolean *require_jalxp, bfd_boolean save_addend)
static bfd_vma mips_elf_obtain_contents (reloc_howto_type *howto, const Elf_Internal_Rela *relocation, bfd *input_bfd, bfd_byte *contents)
static bfd_boolean mips_elf_perform_relocation (struct bfd_link_info *info, reloc_howto_type *howto, const Elf_Internal_Rela *relocation, bfd_vma value, bfd *input_bfd, asection *input_section, bfd_byte *contents, bfd_boolean require_jalx)
static bfd_boolean mips16_stub_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
static void mips_elf_allocate_dynamic_relocations (bfd *abfd, struct bfd_link_info *info, unsigned int n)
unsigned long _bfd_elf_mips_mach (flagword flags)
static INLINE char * elf_mips_abi_name (bfd *abfd)
void _bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
unsigned int _bfd_mips_elf_eh_frame_address_size (bfd *abfd, asection *sec)
bfd_boolean _bfd_mips_elf_name_local_section_symbols (bfd *abfd)
bfd_boolean _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
bfd_boolean _bfd_mips_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, const char *name, int shindex)
bfd_boolean _bfd_mips_elf_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
bfd_boolean _bfd_mips_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, int *retval)
bfd_boolean _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym, const char **namep, flagword *flagsp ATTRIBUTE_UNUSED, asection **secp, bfd_vma *valp)
bfd_boolean _bfd_mips_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym, asection *input_sec, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
bfd_boolean _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
bfd_boolean _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)
bfd_boolean _bfd_mips_relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again)
bfd_boolean _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
bfd_boolean _bfd_mips_vxworks_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
static bfd_size_type count_section_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
bfd_boolean _bfd_mips_elf_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
bfd_boolean _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
static void mips_elf_adjust_addend (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, Elf_Internal_Sym *local_syms, asection **local_sections, Elf_Internal_Rela *rel)
bfd_boolean _bfd_mips_elf_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 void mips_elf_irix6_finish_dynamic_symbol (bfd *abfd ATTRIBUTE_UNUSED, const char *name, Elf_Internal_Sym *sym)
bfd_boolean _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
bfd_boolean _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
static void mips_vxworks_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
static void mips_vxworks_finish_shared_plt (bfd *output_bfd, struct bfd_link_info *info)
bfd_boolean _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
static void mips_set_isa_flags (bfd *abfd)
void _bfd_mips_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
int _bfd_mips_elf_additional_program_headers (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
bfd_boolean _bfd_mips_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
asection_bfd_mips_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info, Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
bfd_boolean _bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
void _bfd_mips_elf_copy_indirect_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *dir, struct elf_link_hash_entry *ind)
void _bfd_mips_elf_hide_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *entry, bfd_boolean force_local)
bfd_boolean _bfd_mips_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie, struct bfd_link_info *info)
bfd_boolean _bfd_mips_elf_ignore_discarded_relocs (asection *sec)
bfd_boolean _bfd_mips_elf_write_section (bfd *output_bfd, struct bfd_link_info *link_info ATTRIBUTE_UNUSED, asection *sec, bfd_byte *contents)
bfd_boolean _bfd_mips_elf_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset, const char **filename_ptr, const char **functionname_ptr, unsigned int *line_ptr)
bfd_boolean _bfd_mips_elf_find_inliner_info (bfd *abfd, const char **filename_ptr, const char **functionname_ptr, unsigned int *line_ptr)
bfd_boolean _bfd_mips_elf_set_section_contents (bfd *abfd, sec_ptr section, const void *location, file_ptr offset, bfd_size_type count)
bfd_byte_bfd_elf_mips_get_relocated_section_contents (bfd *abfd, struct bfd_link_info *link_info, struct bfd_link_order *link_order, bfd_byte *data, bfd_boolean relocatable, asymbol **symbols)
struct bfd_link_hash_table_bfd_mips_elf_link_hash_table_create (bfd *abfd)
struct bfd_link_hash_table_bfd_mips_vxworks_link_hash_table_create (bfd *abfd)
bfd_boolean _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
static bfd_boolean mips_mach_extends_p (unsigned long base, unsigned long extension)
static bfd_boolean mips_32bit_flags_p (flagword flags)
bfd_boolean _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
bfd_boolean _bfd_mips_elf_set_private_flags (bfd *abfd, flagword flags)
bfd_boolean _bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
void _bfd_mips_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, const Elf_Internal_Sym *isym, bfd_boolean definition, bfd_boolean dynamic ATTRIBUTE_UNUSED)
bfd_boolean _bfd_mips_elf_ignore_undef_symbol (struct elf_link_hash_entry *h)
bfd_boolean _bfd_mips_elf_common_definition (Elf_Internal_Sym *sym)

Variables

static const char *const mips_elf_dynsym_rtproc_names []
static bfdreldyn_sorting_bfd
static const bfd_vma mips_vxworks_exec_plt0_entry []
static const bfd_vma mips_vxworks_exec_plt_entry []
static const bfd_vma mips_vxworks_shared_plt0_entry []
static const bfd_vma mips_vxworks_shared_plt_entry []
static struct mips_hi16mips_hi16_list
static asection mips_elf_scom_section
static asymbol mips_elf_scom_symbol
static asymbolmips_elf_scom_symbol_ptr
static asection mips_elf_acom_section
static asymbol mips_elf_acom_symbol
static asymbolmips_elf_acom_symbol_ptr
static struct mips_mach_extension []

Class Documentation

struct mips_got_entry

Definition at line 80 of file elfxx-mips.c.

Collaboration diagram for mips_got_entry:
Class Members
bfd * abfd
union mips_got_entry d
long gotidx
long symndx
unsigned char tls_type
struct mips_got_info

Definition at line 115 of file elfxx-mips.c.

Collaboration diagram for mips_got_info:
Class Members
unsigned int assigned_gotno
struct htab * bfd2got
unsigned int global_gotno
struct elf_link_hash_entry * global_gotsym
struct htab * got_entries
unsigned int local_gotno
struct mips_got_info * next
unsigned int tls_assigned_gotno
unsigned int tls_gotno
bfd_vma tls_ldm_offset
struct mips_elf_bfd2got_hash

Definition at line 148 of file elfxx-mips.c.

Collaboration diagram for mips_elf_bfd2got_hash:
Class Members
bfd * bfd
struct mips_got_info * g
struct mips_elf_got_per_bfd_arg

Definition at line 156 of file elfxx-mips.c.

Collaboration diagram for mips_elf_got_per_bfd_arg:
Class Members
htab_t bfd2got
struct mips_got_info * current
unsigned int current_count
unsigned int global_count
struct bfd_link_info * info
unsigned int max_count
bfd * obfd
struct mips_got_info * primary
unsigned int primary_count
struct mips_elf_set_global_got_offset_arg

Definition at line 187 of file elfxx-mips.c.

Collaboration diagram for mips_elf_set_global_got_offset_arg:
Class Members
struct mips_got_info * g
struct bfd_link_info * info
unsigned int needed_relocs
int value
struct mips_elf_count_tls_arg

Definition at line 198 of file elfxx-mips.c.

Collaboration diagram for mips_elf_count_tls_arg:
Class Members
struct bfd_link_info * info
unsigned int needed
struct _mips_elf_section_data

Definition at line 204 of file elfxx-mips.c.

Class Members
union _mips_elf_section_data u
struct mips_elf_hash_sort_data

Definition at line 220 of file elfxx-mips.c.

Collaboration diagram for mips_elf_hash_sort_data:
Class Members
struct elf_link_hash_entry * low
long max_non_got_dynindx
long max_unref_got_dynindx
long min_got_dynindx
struct mips_elf_link_hash_entry

Definition at line 240 of file elfxx-mips.c.

Collaboration diagram for mips_elf_link_hash_entry:
Class Members
asection * call_fp_stub
asection * call_stub
EXTR esym
asection * fn_stub
bfd_boolean forced_local
bfd_boolean is_branch_target
bfd_boolean is_relocation_target
bfd_boolean need_fn_stub
bfd_boolean no_fn_stub
unsigned int possibly_dynamic_relocs
bfd_boolean readonly_reloc
bfd_vma tls_got_offset
unsigned char tls_type
struct mips_elf_link_hash_table

Definition at line 305 of file elfxx-mips.c.

Collaboration diagram for mips_elf_link_hash_table:
Class Members
bfd_size_type compact_rel_size
bfd_vma function_stub_size
bfd_boolean is_vxworks
bfd_boolean mips16_stubs_seen
bfd_vma plt_entry_size
bfd_vma plt_header_size
bfd_size_type procedure_count
bfd_vma rld_value
asection * sdynbss
asection * sgotplt
asection * splt
asection * srelbss
asection * srelplt
asection * srelplt2
bfd_boolean use_rld_obj_head
struct extsym_info

Definition at line 3884 of file ecoff.c.

Collaboration diagram for extsym_info:
Class Members
bfd * abfd
struct ecoff_debug_info * debug
bfd_boolean failed
struct bfd_link_info * info
struct ecoff_debug_swap * swap
struct Elf32_compact_rel

Definition at line 381 of file elfxx-mips.c.

Class Members
unsigned long id1
unsigned long id2
unsigned long num
unsigned long offset
unsigned long reserved0
unsigned long reserved1
struct Elf32_External_compact_rel

Definition at line 391 of file elfxx-mips.c.

Class Members
bfd_byte id1
bfd_byte id2
bfd_byte num
bfd_byte offset
bfd_byte reserved0
bfd_byte reserved1
struct Elf32_crinfo

Definition at line 401 of file elfxx-mips.c.

Class Members
unsigned int ctype: 1
unsigned int dist2to: 8
unsigned long konst
unsigned int relvaddr: 19
unsigned int rtype: 4
unsigned long vaddr
struct Elf32_crinfo2

Definition at line 411 of file elfxx-mips.c.

Class Members
unsigned int ctype: 1
unsigned int dist2to: 8
unsigned long konst
unsigned int relvaddr: 19
unsigned int rtype: 4
struct Elf32_External_crinfo

Definition at line 420 of file elfxx-mips.c.

Class Members
bfd_byte info
bfd_byte konst
bfd_byte vaddr
struct Elf32_External_crinfo2

Definition at line 427 of file elfxx-mips.c.

Class Members
bfd_byte info
bfd_byte konst
struct runtime_pdr

Definition at line 473 of file elfxx-mips.c.

Class Members
bfd_vma adr
struct exception_info * exception_info
long frameoffset
short framereg
long fregmask
long fregoffset
long irpss
short pcreg
long regmask
long regoffset
long reserved
struct mips_hi16

Definition at line 1363 of file elfxx-mips.c.

Collaboration diagram for mips_hi16:
Class Members
bfd_byte * data
asection * input_section
struct mips_hi16 * next
arelent rel
struct mips_elf_find_line

Definition at line 1417 of file elf64-alpha.c.

struct mips_mach_extension

Definition at line 10887 of file elfxx-mips.c.

Class Members
unsigned long base
unsigned long extension
union mips_got_entry.d

Definition at line 87 of file elfxx-mips.c.

Class Members
bfd_vma addend
bfd_vma address
struct mips_elf_link_hash_entry * h
union _mips_elf_section_data.u

Definition at line 207 of file elfxx-mips.c.

Class Members
struct mips_got_info * got_info
bfd_byte * tdata

Define Documentation

#define ABI_64_P (   abfd)    (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)

Definition at line 517 of file elfxx-mips.c.

#define ABI_N32_P (   abfd)    ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)

Definition at line 513 of file elfxx-mips.c.

#define CALL_FP_STUB   ".mips16.call.fp."

Definition at line 711 of file elfxx-mips.c.

Definition at line 715 of file elfxx-mips.c.

#define CALL_STUB   ".mips16.call."

Definition at line 710 of file elfxx-mips.c.

#define CALL_STUB_P (   name)    CONST_STRNEQ (name, CALL_STUB)

Definition at line 714 of file elfxx-mips.c.

#define cbRPDR   sizeof (RPDR)

Definition at line 486 of file elfxx-mips.c.

#define CRF_MIPS_LONG   1

Definition at line 447 of file elfxx-mips.c.

#define CRF_MIPS_SHORT   0

Definition at line 448 of file elfxx-mips.c.

#define CRINFO_CTYPE   (0x1)

Definition at line 435 of file elfxx-mips.c.

#define CRINFO_CTYPE_SH   (31)

Definition at line 436 of file elfxx-mips.c.

#define CRINFO_DIST2TO   (0xff)

Definition at line 439 of file elfxx-mips.c.

#define CRINFO_DIST2TO_SH   (19)

Definition at line 440 of file elfxx-mips.c.

#define CRINFO_RELVADDR   (0x7ffff)

Definition at line 441 of file elfxx-mips.c.

#define CRINFO_RELVADDR_SH   (0)

Definition at line 442 of file elfxx-mips.c.

#define CRINFO_RTYPE   (0xf)

Definition at line 437 of file elfxx-mips.c.

#define CRINFO_RTYPE_SH   (27)

Definition at line 438 of file elfxx-mips.c.

#define CRT_MIPS_GPHI_LO   0xc

Definition at line 462 of file elfxx-mips.c.

#define CRT_MIPS_JMPAD   0xd

Definition at line 463 of file elfxx-mips.c.

#define CRT_MIPS_REL32   0xa

Definition at line 460 of file elfxx-mips.c.

#define CRT_MIPS_WORD   0xb

Definition at line 461 of file elfxx-mips.c.

#define DTP_OFFSET   0x8000

Definition at line 779 of file elfxx-mips.c.

Value:
(ABI_N32_P (abfd) ? "/usr/lib32/libc.so.1"       \
    : ABI_64_P (abfd) ? "/usr/lib64/libc.so.1"   \
    : "/usr/lib/libc.so.1")

Definition at line 651 of file elfxx-mips.c.

#define ELF_MIPS_GP_OFFSET (   INFO)    (mips_elf_hash_table (INFO)->is_vxworks ? 0x0 : 0x7ff0)

Definition at line 620 of file elfxx-mips.c.

#define ELF_R_INFO (   bfd,
  s,
  t 
)    (ELF32_R_INFO (s, t))

Definition at line 671 of file elfxx-mips.c.

#define ELF_R_SYM (   bfd,
  i 
)    (ELF32_R_SYM (i))

Definition at line 667 of file elfxx-mips.c.

#define ELF_R_TYPE (   bfd,
  i 
)    (ELF32_R_TYPE (i))

Definition at line 669 of file elfxx-mips.c.

#define FN_STUB   ".mips16.fn."

Definition at line 709 of file elfxx-mips.c.

#define FN_STUB_P (   name)    CONST_STRNEQ (name, FN_STUB)

Definition at line 713 of file elfxx-mips.c.

#define GOT_NORMAL   0

Definition at line 287 of file elfxx-mips.c.

#define GOT_TLS_DONE   0x80

Definition at line 292 of file elfxx-mips.c.

#define GOT_TLS_GD   1

Definition at line 288 of file elfxx-mips.c.

#define GOT_TLS_IE   4

Definition at line 290 of file elfxx-mips.c.

#define GOT_TLS_LDM   2

Definition at line 289 of file elfxx-mips.c.

#define GOT_TLS_OFFSET_DONE   0x40

Definition at line 291 of file elfxx-mips.c.

Definition at line 524 of file elfxx-mips.c.

#define MINUS_ONE   (((bfd_vma)0) - 1)

Definition at line 612 of file elfxx-mips.c.

#define MINUS_TWO   (((bfd_vma)0) - 2)

Definition at line 613 of file elfxx-mips.c.

#define MIPS_ELF_ADD_DYNAMIC_ENTRY (   info,
  tag,
  val 
)    _bfd_elf_add_dynamic_entry (info, tag, val)

Definition at line 583 of file elfxx-mips.c.

#define MIPS_ELF_DYN_SIZE (   abfd)    (get_elf_backend_data (abfd)->s->sizeof_dyn)

Definition at line 557 of file elfxx-mips.c.

#define MIPS_ELF_GET_WORD (   abfd,
  ptr 
)    (ABI_64_P (abfd) ? bfd_get_64 (abfd, ptr) : bfd_get_32 (abfd, ptr))

Definition at line 573 of file elfxx-mips.c.

#define MIPS_ELF_GOT_MAX_SIZE (   INFO)    (ELF_MIPS_GP_OFFSET (INFO) + 0x7fff)

Definition at line 625 of file elfxx-mips.c.

#define MIPS_ELF_GOT_SIZE (   abfd)    (get_elf_backend_data (abfd)->s->arch_size / 8)

Definition at line 561 of file elfxx-mips.c.

#define mips_elf_hash_table (   p)    ((struct mips_elf_link_hash_table *) ((p)->hash))

Definition at line 772 of file elfxx-mips.c.

#define mips_elf_link_hash_lookup (   table,
  string,
  create,
  copy,
  follow 
)
Value:
((struct mips_elf_link_hash_entry *)                                  \
   elf_link_hash_lookup (&(table)->root, (string), (create),          \
                      (copy), (follow)))

Definition at line 757 of file elfxx-mips.c.

#define mips_elf_link_hash_traverse (   table,
  func,
  info 
)
Value:
(elf_link_hash_traverse                                        \
   (&(table)->root,                                            \
    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),  \
    (info)))

Definition at line 764 of file elfxx-mips.c.

#define MIPS_ELF_LOG_FILE_ALIGN (   abfd)    (get_elf_backend_data (abfd)->s->log_file_align)

Definition at line 569 of file elfxx-mips.c.

#define MIPS_ELF_OPTIONS_SECTION_NAME (   abfd)    (NEWABI_P (abfd) ? ".MIPS.options" : ".options")

Definition at line 532 of file elfxx-mips.c.

#define MIPS_ELF_OPTIONS_SECTION_NAME_P (   NAME)    (strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)

Definition at line 537 of file elfxx-mips.c.

#define MIPS_ELF_PUT_WORD (   abfd,
  val,
  ptr 
)
Value:
(ABI_64_P (abfd)                          \
   ? bfd_put_64 (abfd, val, ptr)          \
   : bfd_put_32 (abfd, val, ptr))

Definition at line 577 of file elfxx-mips.c.

#define MIPS_ELF_READONLY_SECTION (   sec)
Value:
((sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY))          \
   == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))

Definition at line 541 of file elfxx-mips.c.

#define MIPS_ELF_REL_DYN_NAME (   INFO)    (mips_elf_hash_table (INFO)->is_vxworks ? ".rela.dyn" : ".rel.dyn")

Definition at line 607 of file elfxx-mips.c.

#define MIPS_ELF_REL_SIZE (   abfd)    (get_elf_backend_data (abfd)->s->sizeof_rel)

Definition at line 549 of file elfxx-mips.c.

#define MIPS_ELF_RELA_SIZE (   abfd)    (get_elf_backend_data (abfd)->s->sizeof_rela)

Definition at line 553 of file elfxx-mips.c.

#define MIPS_ELF_RTYPE_TO_HOWTO (   abfd,
  rtype,
  rela 
)    (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))

Definition at line 586 of file elfxx-mips.c.

Definition at line 214 of file elfxx-mips.c.

#define mips_elf_set_cr_dist2to (   x,
  v 
)    ((x).dist2to = (v))

Definition at line 467 of file elfxx-mips.c.

#define mips_elf_set_cr_format (   x,
  format 
)    ((x).ctype = (format))

Definition at line 465 of file elfxx-mips.c.

#define mips_elf_set_cr_relvaddr (   x,
  d 
)    ((x).relvaddr = (d)<<2)

Definition at line 468 of file elfxx-mips.c.

#define mips_elf_set_cr_type (   x,
  type 
)    ((x).rtype = (type))

Definition at line 466 of file elfxx-mips.c.

#define MIPS_ELF_STUB_SECTION_NAME (   abfd)    ".MIPS.stubs"

Definition at line 546 of file elfxx-mips.c.

#define MIPS_ELF_SYM_SIZE (   abfd)    (get_elf_backend_data (abfd)->s->sizeof_sym)

Definition at line 565 of file elfxx-mips.c.

#define MIPS_FUNCTION_STUB_BIG_SIZE   20

Definition at line 646 of file elfxx-mips.c.

Definition at line 645 of file elfxx-mips.c.

#define MIPS_RELOC_RELA_P (   abfd,
  sec,
  rel_idx 
)
Value:
((NUM_SHDR_ENTRIES (&elf_section_data (sec)->rel_hdr)                 \
    * get_elf_backend_data (abfd)->s->int_rels_per_ext_rel            \
    > (bfd_vma)(rel_idx))                                      \
   == (elf_section_data (sec)->rel_hdr.sh_entsize                     \
       == (ABI_64_P (abfd) ? sizeof (Elf64_External_Rela)             \
          : sizeof (Elf32_External_Rela))))

Definition at line 598 of file elfxx-mips.c.

#define MIPS_RESERVED_GOTNO (   INFO)    (mips_elf_hash_table (INFO)->is_vxworks ? 3 : 2)

Definition at line 616 of file elfxx-mips.c.

#define MNAME (   bfd,
  pre,
  pos 
)    CONCAT4 (pre,32,_,pos)

Definition at line 666 of file elfxx-mips.c.

#define NEWABI_P (   abfd)    (ABI_N32_P (abfd) || ABI_64_P (abfd))

Definition at line 521 of file elfxx-mips.c.

#define PDR_SIZE   32

Definition at line 9746 of file elfxx-mips.c.

#define READ (   ptr,
  offset,
  count,
  size,
  type 
)
Value:
if (symhdr->count == 0)                                        \
    debug->ptr = NULL;                                                \
  else                                                         \
    {                                                          \
      bfd_size_type amt = (bfd_size_type) size * symhdr->count;              \
      debug->ptr = bfd_malloc (amt);                                  \
      if (debug->ptr == NULL)                                         \
       goto error_return;                                      \
      if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0              \
         || bfd_bread (debug->ptr, amt, abfd) != amt)                 \
       goto error_return;                                      \
    }
#define rpdNil   ((pRPDR) 0)

Definition at line 487 of file elfxx-mips.c.

#define SGI_COMPAT (   abfd)    (IRIX_COMPAT (abfd) != ict_none)

Definition at line 528 of file elfxx-mips.c.

#define STUB_JALR   0x0320f809 /* jalr t9,ra */

Definition at line 637 of file elfxx-mips.c.

#define STUB_LI16S (   abfd,
  VAL 
)
Value:
((ABI_64_P (abfd)                                              \
    ? (0x64180000 + (VAL))  /* daddiu t8,zero,VAL sign extended */    \
    : (0x24180000 + (VAL))))       /* addiu t8,zero,VAL sign extended */

Definition at line 640 of file elfxx-mips.c.

#define STUB_LI16U (   VAL)    (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned */

Definition at line 639 of file elfxx-mips.c.

#define STUB_LUI (   VAL)    (0x3c180000 + (VAL)) /* lui t8,VAL */

Definition at line 636 of file elfxx-mips.c.

#define STUB_LW (   abfd)
Value:
((ABI_64_P (abfd)                                              \
    ? 0xdf998010                          /* ld t9,0x8010(gp) */      \
    : 0x8f998010))                        /* lw t9,0x8010(gp) */

Definition at line 628 of file elfxx-mips.c.

#define STUB_MOVE (   abfd)
Value:
((ABI_64_P (abfd)                                              \
     ? 0x03e0782d                         /* daddu t7,ra */    \
     : 0x03e07821))                       /* addu t7,ra */

Definition at line 632 of file elfxx-mips.c.

#define STUB_ORI (   VAL)    (0x37180000 + (VAL)) /* ori t8,t8,VAL */

Definition at line 638 of file elfxx-mips.c.

#define TLS_RELOC_P (   r_type)
Value:
(r_type == R_MIPS_TLS_DTPMOD32            \
   || r_type == R_MIPS_TLS_DTPMOD64              \
   || r_type == R_MIPS_TLS_DTPREL32              \
   || r_type == R_MIPS_TLS_DTPREL64              \
   || r_type == R_MIPS_TLS_GD                    \
   || r_type == R_MIPS_TLS_LDM                   \
   || r_type == R_MIPS_TLS_DTPREL_HI16           \
   || r_type == R_MIPS_TLS_DTPREL_LO16           \
   || r_type == R_MIPS_TLS_GOTTPREL              \
   || r_type == R_MIPS_TLS_TPREL32        \
   || r_type == R_MIPS_TLS_TPREL64        \
   || r_type == R_MIPS_TLS_TPREL_HI16            \
   || r_type == R_MIPS_TLS_TPREL_LO16)

Definition at line 342 of file elfxx-mips.c.

#define TP_OFFSET   0x7000

Definition at line 778 of file elfxx-mips.c.


Typedef Documentation


Function Documentation

bfd_byte* _bfd_elf_mips_get_relocated_section_contents ( bfd abfd,
struct bfd_link_info link_info,
struct bfd_link_order link_order,
bfd_byte data,
bfd_boolean  relocatable,
asymbol **  symbols 
)

Definition at line 10011 of file elfxx-mips.c.

{
  /* Get enough memory to hold the stuff */
  bfd *input_bfd = link_order->u.indirect.section->owner;
  asection *input_section = link_order->u.indirect.section;
  bfd_size_type sz;

  long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
  arelent **reloc_vector = NULL;
  long reloc_count;

  if (reloc_size < 0)
    goto error_return;

  reloc_vector = bfd_malloc (reloc_size);
  if (reloc_vector == NULL && reloc_size != 0)
    goto error_return;

  /* read in the section */
  sz = input_section->rawsize ? input_section->rawsize : input_section->size;
  if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
    goto error_return;

  reloc_count = bfd_canonicalize_reloc (input_bfd,
                                   input_section,
                                   reloc_vector,
                                   symbols);
  if (reloc_count < 0)
    goto error_return;

  if (reloc_count > 0)
    {
      arelent **parent;
      /* for mips */
      int gp_found;
      bfd_vma gp = 0x12345678;     /* initialize just to shut gcc up */

      {
       struct bfd_hash_entry *h;
       struct bfd_link_hash_entry *lh;
       /* Skip all this stuff if we aren't mixing formats.  */
       if (abfd && input_bfd
           && abfd->xvec == input_bfd->xvec)
         lh = 0;
       else
         {
           h = bfd_hash_lookup (&link_info->hash->table, "_gp", FALSE, FALSE);
           lh = (struct bfd_link_hash_entry *) h;
         }
      lookup:
       if (lh)
         {
           switch (lh->type)
             {
             case bfd_link_hash_undefined:
             case bfd_link_hash_undefweak:
             case bfd_link_hash_common:
              gp_found = 0;
              break;
             case bfd_link_hash_defined:
             case bfd_link_hash_defweak:
              gp_found = 1;
              gp = lh->u.def.value;
              break;
             case bfd_link_hash_indirect:
             case bfd_link_hash_warning:
              lh = lh->u.i.link;
              /* @@FIXME  ignoring warning for now */
              goto lookup;
             case bfd_link_hash_new:
             default:
              abort ();
             }
         }
       else
         gp_found = 0;
      }
      /* end mips */
      for (parent = reloc_vector; *parent != NULL; parent++)
       {
         char *error_message = NULL;
         bfd_reloc_status_type r;

         /* Specific to MIPS: Deal with relocation types that require
            knowing the gp of the output bfd.  */
         asymbol *sym = *(*parent)->sym_ptr_ptr;

         /* If we've managed to find the gp and have a special
            function for the relocation then go ahead, else default
            to the generic handling.  */
         if (gp_found
             && (*parent)->howto->special_function
             == _bfd_mips_elf32_gprel16_reloc)
           r = _bfd_mips_elf_gprel16_with_gp (input_bfd, sym, *parent,
                                          input_section, relocatable,
                                          data, gp);
         else
           r = bfd_perform_relocation (input_bfd, *parent, data,
                                   input_section,
                                   relocatable ? abfd : NULL,
                                   &error_message);

         if (relocatable)
           {
             asection *os = input_section->output_section;

             /* A partial link, so keep the relocs */
             os->orelocation[os->reloc_count] = *parent;
             os->reloc_count++;
           }

         if (r != bfd_reloc_ok)
           {
             switch (r)
              {
              case bfd_reloc_undefined:
                if (!((*link_info->callbacks->undefined_symbol)
                     (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
                      input_bfd, input_section, (*parent)->address, TRUE)))
                  goto error_return;
                break;
              case bfd_reloc_dangerous:
                BFD_ASSERT (error_message != NULL);
                if (!((*link_info->callbacks->reloc_dangerous)
                     (link_info, error_message, input_bfd, input_section,
                      (*parent)->address)))
                  goto error_return;
                break;
              case bfd_reloc_overflow:
                if (!((*link_info->callbacks->reloc_overflow)
                     (link_info, NULL,
                      bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
                      (*parent)->howto->name, (*parent)->addend,
                      input_bfd, input_section, (*parent)->address)))
                  goto error_return;
                break;
              case bfd_reloc_outofrange:
              default:
                abort ();
                break;
              }

           }
       }
    }
  if (reloc_vector != NULL)
    free (reloc_vector);
  return data;

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

Here is the call graph for this function:

Definition at line 4975 of file elfxx-mips.c.

Here is the caller graph for this function:

void _bfd_mips16_elf_reloc_shuffle ( bfd abfd,
int  r_type,
bfd_boolean  jal_shuffle,
bfd_byte data 
)

Definition at line 1276 of file elfxx-mips.c.

{
  bfd_vma extend, insn, val;

  if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL
      && r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
    return;

  val = bfd_get_32 (abfd, data);
  if (r_type == R_MIPS16_26)
    {
      if (jal_shuffle)
       {
         insn = val & 0xffff;
         extend = ((val >> 16) & 0xfc00) | ((val >> 11) & 0x3e0)
                 | ((val >> 21) & 0x1f);
       }
      else
       {
         insn = val & 0xffff;
         extend = val >> 16;
       }
    }
  else
    {
      insn = ((val >> 11) & 0xffe0) | (val & 0x1f);
      extend = ((val >> 16) & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0);
    }
  bfd_put_16 (abfd, insn, data + 2);
  bfd_put_16 (abfd, extend, data);
}

Here is the caller graph for this function:

void _bfd_mips16_elf_reloc_unshuffle ( bfd abfd,
int  r_type,
bfd_boolean  jal_shuffle,
bfd_byte data 
)

Definition at line 1249 of file elfxx-mips.c.

{
  bfd_vma extend, insn, val;

  if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL
      && r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
    return;

  /* Pick up the mips16 extend instruction and the real instruction.  */
  extend = bfd_get_16 (abfd, data);
  insn = bfd_get_16 (abfd, data + 2);
  if (r_type == R_MIPS16_26)
    {
      if (jal_shuffle)
       val = ((extend & 0xfc00) << 16) | ((extend & 0x3e0) << 11)
             | ((extend & 0x1f) << 21) | insn;
      else
       val = extend << 16 | insn;
    }
  else
    val = ((extend & 0xf800) << 16) | ((insn & 0xffe0) << 11)
         | ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
  bfd_put_32 (abfd, val, data);
}

Here is the caller graph for this function:

bfd_boolean _bfd_mips_elf_add_symbol_hook ( bfd abfd,
struct bfd_link_info info,
Elf_Internal_Sym *  sym,
const char **  namep,
flagword *flagsp  ATTRIBUTE_UNUSED,
asection **  secp,
bfd_vma valp 
)

Definition at line 5733 of file elfxx-mips.c.

{
  if (SGI_COMPAT (abfd)
      && (abfd->flags & DYNAMIC) != 0
      && strcmp (*namep, "_rld_new_interface") == 0)
    {
      /* Skip IRIX5 rld entry name.  */
      *namep = NULL;
      return TRUE;
    }

  /* Shared objects may have a dynamic symbol '_gp_disp' defined as
     a SECTION *ABS*.  This causes ld to think it can resolve _gp_disp
     by setting a DT_NEEDED for the shared object.  Since _gp_disp is
     a magic symbol resolved by the linker, we ignore this bogus definition
     of _gp_disp.  New ABI objects do not suffer from this problem so this
     is not done for them. */
  if (!NEWABI_P(abfd)
      && (sym->st_shndx == SHN_ABS)
      && (strcmp (*namep, "_gp_disp") == 0))
    {
      *namep = NULL;
      return TRUE;
    }

  switch (sym->st_shndx)
    {
    case SHN_COMMON:
      /* Common symbols less than the GP size are automatically
        treated as SHN_MIPS_SCOMMON symbols.  */
      if (sym->st_size > elf_gp_size (abfd)
         || ELF_ST_TYPE (sym->st_info) == STT_TLS
         || IRIX_COMPAT (abfd) == ict_irix6)
       break;
      /* Fall through.  */
    case SHN_MIPS_SCOMMON:
      *secp = bfd_make_section_old_way (abfd, ".scommon");
      (*secp)->flags |= SEC_IS_COMMON;
      *valp = sym->st_size;
      break;

    case SHN_MIPS_TEXT:
      /* This section is used in a shared object.  */
      if (elf_tdata (abfd)->elf_text_section == NULL)
       {
         asymbol *elf_text_symbol;
         asection *elf_text_section;
         bfd_size_type amt = sizeof (asection);

         elf_text_section = bfd_zalloc (abfd, amt);
         if (elf_text_section == NULL)
           return FALSE;

         amt = sizeof (asymbol);
         elf_text_symbol = bfd_zalloc (abfd, amt);
         if (elf_text_symbol == NULL)
           return FALSE;

         /* Initialize the section.  */

         elf_tdata (abfd)->elf_text_section = elf_text_section;
         elf_tdata (abfd)->elf_text_symbol = elf_text_symbol;

         elf_text_section->symbol = elf_text_symbol;
         elf_text_section->symbol_ptr_ptr = &elf_tdata (abfd)->elf_text_symbol;

         elf_text_section->name = ".text";
         elf_text_section->flags = SEC_NO_FLAGS;
         elf_text_section->output_section = NULL;
         elf_text_section->owner = abfd;
         elf_text_symbol->name = ".text";
         elf_text_symbol->flags = BSF_SECTION_SYM | BSF_DYNAMIC;
         elf_text_symbol->section = elf_text_section;
       }
      /* This code used to do *secp = bfd_und_section_ptr if
         info->shared.  I don't know why, and that doesn't make sense,
         so I took it out.  */
      *secp = elf_tdata (abfd)->elf_text_section;
      break;

    case SHN_MIPS_ACOMMON:
      /* Fall through. XXX Can we treat this as allocated data?  */
    case SHN_MIPS_DATA:
      /* This section is used in a shared object.  */
      if (elf_tdata (abfd)->elf_data_section == NULL)
       {
         asymbol *elf_data_symbol;
         asection *elf_data_section;
         bfd_size_type amt = sizeof (asection);

         elf_data_section = bfd_zalloc (abfd, amt);
         if (elf_data_section == NULL)
           return FALSE;

         amt = sizeof (asymbol);
         elf_data_symbol = bfd_zalloc (abfd, amt);
         if (elf_data_symbol == NULL)
           return FALSE;

         /* Initialize the section.  */

         elf_tdata (abfd)->elf_data_section = elf_data_section;
         elf_tdata (abfd)->elf_data_symbol = elf_data_symbol;

         elf_data_section->symbol = elf_data_symbol;
         elf_data_section->symbol_ptr_ptr = &elf_tdata (abfd)->elf_data_symbol;

         elf_data_section->name = ".data";
         elf_data_section->flags = SEC_NO_FLAGS;
         elf_data_section->output_section = NULL;
         elf_data_section->owner = abfd;
         elf_data_symbol->name = ".data";
         elf_data_symbol->flags = BSF_SECTION_SYM | BSF_DYNAMIC;
         elf_data_symbol->section = elf_data_section;
       }
      /* This code used to do *secp = bfd_und_section_ptr if
         info->shared.  I don't know why, and that doesn't make sense,
         so I took it out.  */
      *secp = elf_tdata (abfd)->elf_data_section;
      break;

    case SHN_MIPS_SUNDEFINED:
      *secp = bfd_und_section_ptr;
      break;
    }

  if (SGI_COMPAT (abfd)
      && ! info->shared
      && info->hash->creator == abfd->xvec
      && strcmp (*namep, "__rld_obj_head") == 0)
    {
      struct elf_link_hash_entry *h;
      struct bfd_link_hash_entry *bh;

      /* Mark __rld_obj_head as dynamic.  */
      bh = NULL;
      if (! (_bfd_generic_link_add_one_symbol
            (info, abfd, *namep, BSF_GLOBAL, *secp, *valp, NULL, FALSE,
             get_elf_backend_data (abfd)->collect, &bh)))
       return FALSE;

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

      if (! bfd_elf_link_record_dynamic_symbol (info, h))
       return FALSE;

      mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
    }

  /* If this is a mips16 text symbol, add 1 to the value to make it
     odd.  This will cause something like .word SYM to come up with
     the right value when it is loaded into the PC.  */
  if (sym->st_other == STO_MIPS16)
    ++*valp;

  return TRUE;
}

Here is the call graph for this function:

Definition at line 9294 of file elfxx-mips.c.

{
  asection *s;
  int ret = 0;

  /* See if we need a PT_MIPS_REGINFO segment.  */
  s = bfd_get_section_by_name (abfd, ".reginfo");
  if (s && (s->flags & SEC_LOAD))
    ++ret;

  /* See if we need a PT_MIPS_OPTIONS segment.  */
  if (IRIX_COMPAT (abfd) == ict_irix6
      && bfd_get_section_by_name (abfd,
                              MIPS_ELF_OPTIONS_SECTION_NAME (abfd)))
    ++ret;

  /* See if we need a PT_MIPS_RTPROC segment.  */
  if (IRIX_COMPAT (abfd) == ict_irix5
      && bfd_get_section_by_name (abfd, ".dynamic")
      && bfd_get_section_by_name (abfd, ".mdebug"))
    ++ret;

  /* Allocate a PT_NULL header in dynamic objects.  See
     _bfd_mips_elf_modify_segment_map for details.  */
  if (!SGI_COMPAT (abfd)
      && bfd_get_section_by_name (abfd, ".dynamic"))
    ++ret;

  return ret;
}

Here is the call graph for this function:

Definition at line 6930 of file elfxx-mips.c.

{
  bfd *dynobj;
  struct mips_elf_link_hash_entry *hmips;
  asection *s;
  struct mips_elf_link_hash_table *htab;

  htab = mips_elf_hash_table (info);
  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 symbol is defined in a dynamic object, we need to copy
     any R_MIPS_32 or R_MIPS_REL32 relocs against it into the output
     file.  */
  hmips = (struct mips_elf_link_hash_entry *) h;
  if (! info->relocatable
      && hmips->possibly_dynamic_relocs != 0
      && (h->root.type == bfd_link_hash_defweak
         || !h->def_regular))
    {
      mips_elf_allocate_dynamic_relocations
       (dynobj, info, hmips->possibly_dynamic_relocs);
      if (hmips->readonly_reloc)
       /* We tell the dynamic linker that there are relocations
          against the text segment.  */
       info->flags |= DF_TEXTREL;
    }

  /* For a function, create a stub, if allowed.  */
  if (! hmips->no_fn_stub
      && h->needs_plt)
    {
      if (! elf_hash_table (info)->dynamic_sections_created)
       return TRUE;

      /* If this symbol is not defined in a regular file, then set
        the symbol to the stub location.  This is required to make
        function pointers compare as equal between the normal
        executable and the shared library.  */
      if (!h->def_regular)
       {
         /* We need .stub section.  */
         s = bfd_get_section_by_name (dynobj,
                                   MIPS_ELF_STUB_SECTION_NAME (dynobj));
         BFD_ASSERT (s != NULL);

         h->root.u.def.section = s;
         h->root.u.def.value = s->size;

         /* XXX Write this stub address somewhere.  */
         h->plt.offset = s->size;

         /* Make room for this stub code.  */
         s->size += htab->function_stub_size;

         /* The last half word of the stub will be filled with the index
            of this symbol in .dynsym section.  */
         return TRUE;
       }
    }
  else if ((h->type == STT_FUNC)
          && !h->needs_plt)
    {
      /* This will set the entry for this symbol in the GOT to 0, and
         the dynamic linker will take care of this.  */
      h->root.u.def.value = 0;
      return TRUE;
    }

  /* 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.  */

  return TRUE;
}

Here is the call graph for this function:

Definition at line 7210 of file elfxx-mips.c.

{
  asection *ri;

  bfd *dynobj;
  asection *s;
  struct mips_got_info *g;
  int i;
  bfd_size_type loadable_size = 0;
  bfd_size_type local_gotno;
  bfd_size_type dynsymcount;
  bfd *sub;
  struct mips_elf_count_tls_arg count_tls_arg;
  struct mips_elf_link_hash_table *htab;

  htab = mips_elf_hash_table (info);

  /* The .reginfo section has a fixed size.  */
  ri = bfd_get_section_by_name (output_bfd, ".reginfo");
  if (ri != NULL)
    bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo));

  if (! (info->relocatable
        || ! mips_elf_hash_table (info)->mips16_stubs_seen))
    mips_elf_link_hash_traverse (mips_elf_hash_table (info),
                             mips_elf_check_mips16_stubs, NULL);

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj == NULL)
    /* Relocatable links don't have it.  */
    return TRUE;

  g = mips_elf_got_info (dynobj, &s);
  if (s == NULL)
    return TRUE;

  /* Calculate the total loadable size of the output.  That
     will give us the maximum number of GOT_PAGE entries
     required.  */
  for (sub = info->input_bfds; sub; sub = sub->link_next)
    {
      asection *subsection;

      for (subsection = sub->sections;
          subsection;
          subsection = subsection->next)
       {
         if ((subsection->flags & SEC_ALLOC) == 0)
           continue;
         loadable_size += ((subsection->size + 0xf)
                         &~ (bfd_size_type) 0xf);
       }
    }

  /* There has to be a global GOT entry for every symbol with
     a dynamic symbol table index of DT_MIPS_GOTSYM or
     higher.  Therefore, it make sense to put those symbols
     that need GOT entries at the end of the symbol table.  We
     do that here.  */
  if (! mips_elf_sort_hash_table (info, 1))
    return FALSE;

  if (g->global_gotsym != NULL)
    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
  else
    /* If there are no global symbols, or none requiring
       relocations, then GLOBAL_GOTSYM will be NULL.  */
    i = 0;

  /* Get a worst-case estimate of the number of dynamic symbols needed.
     At this point, dynsymcount does not account for section symbols
     and count_section_dynsyms may overestimate the number that will
     be needed.  */
  dynsymcount = (elf_hash_table (info)->dynsymcount
               + count_section_dynsyms (output_bfd, info));

  /* Determine the size of one stub entry.  */
  htab->function_stub_size = (dynsymcount > 0x10000
                           ? MIPS_FUNCTION_STUB_BIG_SIZE
                           : MIPS_FUNCTION_STUB_NORMAL_SIZE);

  /* In the worst case, we'll get one stub per dynamic symbol, plus
     one to account for the dummy entry at the end required by IRIX
     rld.  */
  loadable_size += htab->function_stub_size * (i + 1);

  if (htab->is_vxworks)
    /* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16
       relocations against local symbols evaluate to "G", and the EABI does
       not include R_MIPS_GOT_PAGE.  */
    local_gotno = 0;
  else
    /* Assume there are two loadable segments consisting of contiguous
       sections.  Is 5 enough?  */
    local_gotno = (loadable_size >> 16) + 5;

  g->local_gotno += local_gotno;
  s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);

  g->global_gotno = i;
  s->size += i * MIPS_ELF_GOT_SIZE (output_bfd);

  /* We need to calculate tls_gotno for global symbols at this point
     instead of building it up earlier, to avoid doublecounting
     entries for one global symbol from multiple input files.  */
  count_tls_arg.info = info;
  count_tls_arg.needed = 0;
  elf_link_hash_traverse (elf_hash_table (info),
                       mips_elf_count_global_tls_entries,
                       &count_tls_arg);
  g->tls_gotno += count_tls_arg.needed;
  s->size += g->tls_gotno * MIPS_ELF_GOT_SIZE (output_bfd);

  mips_elf_resolve_final_got_entries (g);

  /* VxWorks does not support multiple GOTs.  It initializes $gp to
     __GOTT_BASE__[__GOTT_INDEX__], the value of which is set by the
     dynamic loader.  */
  if (!htab->is_vxworks && s->size > MIPS_ELF_GOT_MAX_SIZE (info))
    {
      if (! mips_elf_multi_got (output_bfd, info, g, s, local_gotno))
       return FALSE;
    }
  else
    {
      /* Set up TLS entries for the first GOT.  */
      g->tls_assigned_gotno = g->global_gotno + g->local_gotno;
      htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g);
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 6121 of file elfxx-mips.c.

{
  const char *name;
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  struct mips_got_info *g;
  size_t extsymoff;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  asection *sgot;
  asection *sreloc;
  const struct elf_backend_data *bed;
  struct mips_elf_link_hash_table *htab;

  if (info->relocatable)
    return TRUE;

  htab = mips_elf_hash_table (info);
  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;

  /* Check for the mips16 stub sections.  */

  name = bfd_get_section_name (abfd, sec);
  if (FN_STUB_P (name))
    {
      unsigned long r_symndx;

      /* Look at the relocation information to figure out which symbol
         this is for.  */

      r_symndx = ELF_R_SYM (abfd, relocs->r_info);

      if (r_symndx < extsymoff
         || sym_hashes[r_symndx - extsymoff] == NULL)
       {
         asection *o;

         /* This stub is for a local symbol.  This stub will only be
             needed if there is some relocation in this BFD, other
             than a 16 bit function call, which refers to this symbol.  */
         for (o = abfd->sections; o != NULL; o = o->next)
           {
             Elf_Internal_Rela *sec_relocs;
             const Elf_Internal_Rela *r, *rend;

             /* We can ignore stub sections when looking for relocs.  */
             if ((o->flags & SEC_RELOC) == 0
                || o->reloc_count == 0
                || mips16_stub_section_p (abfd, o))
              continue;

             sec_relocs
              = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
                                        info->keep_memory);
             if (sec_relocs == NULL)
              return FALSE;

             rend = sec_relocs + o->reloc_count;
             for (r = sec_relocs; r < rend; r++)
              if (ELF_R_SYM (abfd, r->r_info) == r_symndx
                  && ELF_R_TYPE (abfd, r->r_info) != R_MIPS16_26)
                break;

             if (elf_section_data (o)->relocs != sec_relocs)
              free (sec_relocs);

             if (r < rend)
              break;
           }

         if (o == NULL)
           {
             /* There is no non-call reloc for this stub, so we do
                 not need it.  Since this function is called before
                 the linker maps input sections to output sections, we
                 can easily discard it by setting the SEC_EXCLUDE
                 flag.  */
             sec->flags |= SEC_EXCLUDE;
             return TRUE;
           }

         /* Record this stub in an array of local symbol stubs for
             this BFD.  */
         if (elf_tdata (abfd)->local_stubs == NULL)
           {
             unsigned long symcount;
             asection **n;
             bfd_size_type amt;

             if (elf_bad_symtab (abfd))
              symcount = NUM_SHDR_ENTRIES (symtab_hdr);
             else
              symcount = symtab_hdr->sh_info;
             amt = symcount * sizeof (asection *);
             n = bfd_zalloc (abfd, amt);
             if (n == NULL)
              return FALSE;
             elf_tdata (abfd)->local_stubs = n;
           }

         sec->flags |= SEC_KEEP;
         elf_tdata (abfd)->local_stubs[r_symndx] = sec;

         /* We don't need to set mips16_stubs_seen in this case.
             That flag is used to see whether we need to look through
             the global symbol table for stubs.  We don't need to set
             it here, because we just have a local stub.  */
       }
      else
       {
         struct mips_elf_link_hash_entry *h;

         h = ((struct mips_elf_link_hash_entry *)
              sym_hashes[r_symndx - extsymoff]);

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

         /* H is the symbol this stub is for.  */

         /* If we already have an appropriate stub for this function, we
            don't need another one, so we can discard this one.  Since
            this function is called before the linker maps input sections
            to output sections, we can easily discard it by setting the
            SEC_EXCLUDE flag.  */
         if (h->fn_stub != NULL)
           {
             sec->flags |= SEC_EXCLUDE;
             return TRUE;
           }

         sec->flags |= SEC_KEEP;
         h->fn_stub = sec;
         mips_elf_hash_table (info)->mips16_stubs_seen = TRUE;
       }
    }
  else if (CALL_STUB_P (name) || CALL_FP_STUB_P (name))
    {
      unsigned long r_symndx;
      struct mips_elf_link_hash_entry *h;
      asection **loc;

      /* Look at the relocation information to figure out which symbol
         this is for.  */

      r_symndx = ELF_R_SYM (abfd, relocs->r_info);

      if (r_symndx < extsymoff
         || sym_hashes[r_symndx - extsymoff] == NULL)
       {
         asection *o;

         /* This stub is for a local symbol.  This stub will only be
             needed if there is some relocation (R_MIPS16_26) in this BFD
             that refers to this symbol.  */
         for (o = abfd->sections; o != NULL; o = o->next)
           {
             Elf_Internal_Rela *sec_relocs;
             const Elf_Internal_Rela *r, *rend;

             /* We can ignore stub sections when looking for relocs.  */
             if ((o->flags & SEC_RELOC) == 0
                || o->reloc_count == 0
                || mips16_stub_section_p (abfd, o))
              continue;

             sec_relocs
              = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
                                        info->keep_memory);
             if (sec_relocs == NULL)
              return FALSE;

             rend = sec_relocs + o->reloc_count;
             for (r = sec_relocs; r < rend; r++)
              if (ELF_R_SYM (abfd, r->r_info) == r_symndx
                  && ELF_R_TYPE (abfd, r->r_info) == R_MIPS16_26)
                  break;

             if (elf_section_data (o)->relocs != sec_relocs)
              free (sec_relocs);

             if (r < rend)
              break;
           }

         if (o == NULL)
           {
             /* There is no non-call reloc for this stub, so we do
                 not need it.  Since this function is called before
                 the linker maps input sections to output sections, we
                 can easily discard it by setting the SEC_EXCLUDE
                 flag.  */
             sec->flags |= SEC_EXCLUDE;
             return TRUE;
           }

         /* Record this stub in an array of local symbol call_stubs for
             this BFD.  */
         if (elf_tdata (abfd)->local_call_stubs == NULL)
           {
             unsigned long symcount;
             asection **n;
             bfd_size_type amt;

             if (elf_bad_symtab (abfd))
              symcount = NUM_SHDR_ENTRIES (symtab_hdr);
             else
              symcount = symtab_hdr->sh_info;
             amt = symcount * sizeof (asection *);
             n = bfd_zalloc (abfd, amt);
             if (n == NULL)
              return FALSE;
             elf_tdata (abfd)->local_call_stubs = n;
           }

         sec->flags |= SEC_KEEP;
         elf_tdata (abfd)->local_call_stubs[r_symndx] = sec;

         /* We don't need to set mips16_stubs_seen in this case.
             That flag is used to see whether we need to look through
             the global symbol table for stubs.  We don't need to set
             it here, because we just have a local stub.  */
       }
      else
       {
         h = ((struct mips_elf_link_hash_entry *)
              sym_hashes[r_symndx - extsymoff]);
         
         /* H is the symbol this stub is for.  */
         
         if (CALL_FP_STUB_P (name))
           loc = &h->call_fp_stub;
         else
           loc = &h->call_stub;
         
         /* If we already have an appropriate stub for this function, we
            don't need another one, so we can discard this one.  Since
            this function is called before the linker maps input sections
            to output sections, we can easily discard it by setting the
            SEC_EXCLUDE flag.  */
         if (*loc != NULL)
           {
             sec->flags |= SEC_EXCLUDE;
             return TRUE;
           }

         sec->flags |= SEC_KEEP;
         *loc = sec;
         mips_elf_hash_table (info)->mips16_stubs_seen = TRUE;
       }
    }

  if (dynobj == NULL)
    {
      sgot = NULL;
      g = NULL;
    }
  else
    {
      sgot = mips_elf_got_section (dynobj, FALSE);
      if (sgot == NULL)
       g = NULL;
      else
       {
         BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
         g = mips_elf_section_data (sgot)->u.got_info;
         BFD_ASSERT (g != NULL);
       }
    }

  sreloc = NULL;
  bed = get_elf_backend_data (abfd);
  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
  for (rel = relocs; rel < rel_end; ++rel)
    {
      unsigned long r_symndx;
      unsigned int r_type;
      struct elf_link_hash_entry *h;

      r_symndx = ELF_R_SYM (abfd, rel->r_info);
      r_type = ELF_R_TYPE (abfd, rel->r_info);

      if (r_symndx < extsymoff)
       h = NULL;
      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
       {
         (*_bfd_error_handler)
           (_("%B: Malformed reloc detected for section %s"),
            abfd, name);
         bfd_set_error (bfd_error_bad_value);
         return FALSE;
       }
      else
       {
         h = sym_hashes[r_symndx - extsymoff];

         /* This may be an indirect symbol created because of a version.  */
         if (h != NULL)
           {
             while (h->root.type == bfd_link_hash_indirect)
              h = (struct elf_link_hash_entry *) h->root.u.i.link;
           }
       }

      /* Some relocs require a global offset table.  */
      if (dynobj == NULL || sgot == NULL)
       {
         switch (r_type)
           {
           case R_MIPS_GOT16:
           case R_MIPS_CALL16:
           case R_MIPS_CALL_HI16:
           case R_MIPS_CALL_LO16:
           case R_MIPS_GOT_HI16:
           case R_MIPS_GOT_LO16:
           case R_MIPS_GOT_PAGE:
           case R_MIPS_GOT_OFST:
           case R_MIPS_GOT_DISP:
           case R_MIPS_TLS_GOTTPREL:
           case R_MIPS_TLS_GD:
           case R_MIPS_TLS_LDM:
             if (dynobj == NULL)
              elf_hash_table (info)->dynobj = dynobj = abfd;
             if (! mips_elf_create_got_section (dynobj, info, FALSE))
              return FALSE;
             g = mips_elf_got_info (dynobj, &sgot);
             if (htab->is_vxworks && !info->shared)
              {
                (*_bfd_error_handler)
                  (_("%B: GOT reloc at 0x%lx not expected in executables"),
                   abfd, (unsigned long) rel->r_offset);
                bfd_set_error (bfd_error_bad_value);
                return FALSE;
              }
             break;

           case R_MIPS_32:
           case R_MIPS_REL32:
           case R_MIPS_64:
             /* In VxWorks executables, references to external symbols
               are handled using copy relocs or PLT stubs, so there's
               no need to add a dynamic relocation here.  */
             if (dynobj == NULL
                && (info->shared || (h != NULL && !htab->is_vxworks))
                && (sec->flags & SEC_ALLOC) != 0)
              elf_hash_table (info)->dynobj = dynobj = abfd;
             break;

           default:
             break;
           }
       }

      if (h)
       {
         ((struct mips_elf_link_hash_entry *) h)->is_relocation_target = TRUE;

         /* Relocations against the special VxWorks __GOTT_BASE__ and
            __GOTT_INDEX__ symbols must be left to the loader.  Allocate
            room for them in .rela.dyn.  */
         if (is_gott_symbol (info, h))
           {
             if (sreloc == NULL)
              {
                sreloc = mips_elf_rel_dyn_section (info, TRUE);
                if (sreloc == NULL)
                  return FALSE;
              }
             mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
           }
       }
      else if (r_type == R_MIPS_CALL_LO16
              || r_type == R_MIPS_GOT_LO16
              || r_type == R_MIPS_GOT_DISP
              || (r_type == R_MIPS_GOT16 && htab->is_vxworks))
       {
         /* We may need a local GOT entry for this relocation.  We
            don't count R_MIPS_GOT_PAGE because we can estimate the
            maximum number of pages needed by looking at the size of
            the segment.  Similar comments apply to R_MIPS_GOT16 and
            R_MIPS_CALL16, except on VxWorks, where GOT relocations
            always evaluate to "G".  We don't count R_MIPS_GOT_HI16, or
            R_MIPS_CALL_HI16 because these are always followed by an
            R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.  */
         if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
                                            rel->r_addend, g, 0))
           return FALSE;
       }

      switch (r_type)
       {
       case R_MIPS_CALL16:
         if (h == NULL)
           {
             (*_bfd_error_handler)
              (_("%B: CALL16 reloc at 0x%lx not against global symbol"),
               abfd, (unsigned long) rel->r_offset);
             bfd_set_error (bfd_error_bad_value);
             return FALSE;
           }
         /* Fall through.  */

       case R_MIPS_CALL_HI16:
       case R_MIPS_CALL_LO16:
         if (h != NULL)
           {
             /* VxWorks call relocations point the function's .got.plt
               entry, which will be allocated by adjust_dynamic_symbol.
               Otherwise, this symbol requires a global GOT entry.  */
             if (!htab->is_vxworks
                && !mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
              return FALSE;

             /* We need a stub, not a plt entry for the undefined
               function.  But we record it as if it needs plt.  See
               _bfd_elf_adjust_dynamic_symbol.  */
             h->needs_plt = 1;
             h->type = STT_FUNC;
           }
         break;

       case R_MIPS_GOT_PAGE:
         /* If this is a global, overridable symbol, GOT_PAGE will
            decay to GOT_DISP, so we'll need a GOT entry for it.  */
         if (h == NULL)
           break;
         else
           {
             struct mips_elf_link_hash_entry *hmips =
              (struct mips_elf_link_hash_entry *) h;

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

             if (hmips->root.def_regular
                && ! (info->shared && ! info->symbolic
                     && ! hmips->root.forced_local))
              break;
           }
         /* Fall through.  */

       case R_MIPS_GOT16:
       case R_MIPS_GOT_HI16:
       case R_MIPS_GOT_LO16:
       case R_MIPS_GOT_DISP:
         if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
           return FALSE;
         break;

       case R_MIPS_TLS_GOTTPREL:
         if (info->shared)
           info->flags |= DF_STATIC_TLS;
         /* Fall through */

       case R_MIPS_TLS_LDM:
         if (r_type == R_MIPS_TLS_LDM)
           {
             r_symndx = 0;
             h = NULL;
           }
         /* Fall through */

       case R_MIPS_TLS_GD:
         /* This symbol requires a global offset table entry, or two
            for TLS GD relocations.  */
         {
           unsigned char flag = (r_type == R_MIPS_TLS_GD
                              ? GOT_TLS_GD
                              : r_type == R_MIPS_TLS_LDM
                              ? GOT_TLS_LDM
                              : GOT_TLS_IE);
           if (h != NULL)
             {
              struct mips_elf_link_hash_entry *hmips =
                (struct mips_elf_link_hash_entry *) h;
              hmips->tls_type |= flag;

              if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, flag))
                return FALSE;
             }
           else
             {
              BFD_ASSERT (flag == GOT_TLS_LDM || r_symndx != 0);

              if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
                                                 rel->r_addend, g, flag))
                return FALSE;
             }
         }
         break;

       case R_MIPS_32:
       case R_MIPS_REL32:
       case R_MIPS_64:
         /* In VxWorks executables, references to external symbols
            are handled using copy relocs or PLT stubs, so there's
            no need to add a .rela.dyn entry for this relocation.  */
         if ((info->shared || (h != NULL && !htab->is_vxworks))
             && (sec->flags & SEC_ALLOC) != 0)
           {
             if (sreloc == NULL)
              {
                sreloc = mips_elf_rel_dyn_section (info, TRUE);
                if (sreloc == NULL)
                  return FALSE;
              }
             if (info->shared)
              {
                /* When creating a shared object, we must copy these
                   reloc types into the output file as R_MIPS_REL32
                   relocs.  Make room for this reloc in .rel(a).dyn.  */
                mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
                if (MIPS_ELF_READONLY_SECTION (sec))
                  /* We tell the dynamic linker that there are
                     relocations against the text segment.  */
                  info->flags |= DF_TEXTREL;
              }
             else
              {
                struct mips_elf_link_hash_entry *hmips;

                /* We only need to copy this reloc if the symbol is
                     defined in a dynamic object.  */
                hmips = (struct mips_elf_link_hash_entry *) h;
                ++hmips->possibly_dynamic_relocs;
                if (MIPS_ELF_READONLY_SECTION (sec))
                  /* We need it to tell the dynamic linker if there
                     are relocations against the text segment.  */
                  hmips->readonly_reloc = TRUE;
              }

             /* Even though we don't directly need a GOT entry for
               this symbol, a symbol must have a dynamic symbol
               table index greater that DT_MIPS_GOTSYM if there are
               dynamic relocations against it.  This does not apply
               to VxWorks, which does not have the usual coupling
               between global GOT entries and .dynsym entries.  */
             if (h != NULL && !htab->is_vxworks)
              {
                if (dynobj == NULL)
                  elf_hash_table (info)->dynobj = dynobj = abfd;
                if (! mips_elf_create_got_section (dynobj, info, TRUE))
                  return FALSE;
                g = mips_elf_got_info (dynobj, &sgot);
                if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
                  return FALSE;
              }
           }

         if (SGI_COMPAT (abfd))
           mips_elf_hash_table (info)->compact_rel_size +=
             sizeof (Elf32_External_crinfo);
         break;

       case R_MIPS_PC16:
         if (h)
           ((struct mips_elf_link_hash_entry *) h)->is_branch_target = TRUE;
         break;

       case R_MIPS_26:
         if (h)
           ((struct mips_elf_link_hash_entry *) h)->is_branch_target = TRUE;
         /* Fall through.  */

       case R_MIPS_GPREL16:
       case R_MIPS_LITERAL:
       case R_MIPS_GPREL32:
         if (SGI_COMPAT (abfd))
           mips_elf_hash_table (info)->compact_rel_size +=
             sizeof (Elf32_External_crinfo);
         break;

         /* This relocation describes the C++ object vtable hierarchy.
            Reconstruct it for later use during GC.  */
       case R_MIPS_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_MIPS_GNU_VTENTRY:
         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
           return FALSE;
         break;

       default:
         break;
       }

      /* We must not create a stub for a symbol that has relocations
        related to taking the function's address.  This doesn't apply to
        VxWorks, where CALL relocs refer to a .got.plt entry instead of
        a normal .got entry.  */
      if (!htab->is_vxworks && h != NULL)
       switch (r_type)
         {
         default:
           ((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE;
           break;
         case R_MIPS_CALL16:
         case R_MIPS_CALL_HI16:
         case R_MIPS_CALL_LO16:
         case R_MIPS_JALR:
           break;
         }

      /* If this reloc is not a 16 bit call, and it has a global
         symbol, then we will need the fn_stub if there is one.
         References from a stub section do not count.  */
      if (h != NULL
         && r_type != R_MIPS16_26
         && !mips16_stub_section_p (abfd, sec))
       {
         struct mips_elf_link_hash_entry *mh;

         mh = (struct mips_elf_link_hash_entry *) h;
         mh->need_fn_stub = TRUE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

bfd_boolean _bfd_mips_elf_common_definition ( Elf_Internal_Sym *  sym)

Definition at line 11344 of file elfxx-mips.c.

{
  return (sym->st_shndx == SHN_COMMON
         || sym->st_shndx == SHN_MIPS_ACOMMON
         || sym->st_shndx == SHN_MIPS_SCOMMON);
}

Definition at line 9651 of file elfxx-mips.c.

{
  struct mips_elf_link_hash_entry *dirmips, *indmips;

  _bfd_elf_link_hash_copy_indirect (info, dir, ind);

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

  dirmips = (struct mips_elf_link_hash_entry *) dir;
  indmips = (struct mips_elf_link_hash_entry *) ind;
  dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs;
  if (indmips->readonly_reloc)
    dirmips->readonly_reloc = TRUE;
  if (indmips->no_fn_stub)
    dirmips->no_fn_stub = TRUE;

  if (dirmips->tls_type == 0)
    dirmips->tls_type = indmips->tls_type;
}

Here is the call graph for this function:

Definition at line 5925 of file elfxx-mips.c.

{
  struct elf_link_hash_entry *h;
  struct bfd_link_hash_entry *bh;
  flagword flags;
  register asection *s;
  const char * const *namep;
  struct mips_elf_link_hash_table *htab;

  htab = mips_elf_hash_table (info);
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
          | SEC_LINKER_CREATED | SEC_READONLY);

  /* The psABI requires a read-only .dynamic section, but the VxWorks
     EABI doesn't.  */
  if (!htab->is_vxworks)
    {
      s = bfd_get_section_by_name (abfd, ".dynamic");
      if (s != NULL)
       {
         if (! bfd_set_section_flags (abfd, s, flags))
           return FALSE;
       }
    }

  /* We need to create .got section.  */
  if (! mips_elf_create_got_section (abfd, info, FALSE))
    return FALSE;

  if (! mips_elf_rel_dyn_section (info, TRUE))
    return FALSE;

  /* Create .stub section.  */
  if (bfd_get_section_by_name (abfd,
                            MIPS_ELF_STUB_SECTION_NAME (abfd)) == NULL)
    {
      s = bfd_make_section_with_flags (abfd,
                                   MIPS_ELF_STUB_SECTION_NAME (abfd),
                                   flags | SEC_CODE);
      if (s == NULL
         || ! bfd_set_section_alignment (abfd, s,
                                     MIPS_ELF_LOG_FILE_ALIGN (abfd)))
       return FALSE;
    }

  if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
      && !info->shared
      && bfd_get_section_by_name (abfd, ".rld_map") == NULL)
    {
      s = bfd_make_section_with_flags (abfd, ".rld_map",
                                   flags &~ (flagword) SEC_READONLY);
      if (s == NULL
         || ! bfd_set_section_alignment (abfd, s,
                                     MIPS_ELF_LOG_FILE_ALIGN (abfd)))
       return FALSE;
    }

  /* On IRIX5, we adjust add some additional symbols and change the
     alignments of several sections.  There is no ABI documentation
     indicating that this is necessary on IRIX6, nor any evidence that
     the linker takes such action.  */
  if (IRIX_COMPAT (abfd) == ict_irix5)
    {
      for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
       {
         bh = NULL;
         if (! (_bfd_generic_link_add_one_symbol
               (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, 0,
                NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
           return FALSE;

         h = (struct elf_link_hash_entry *) bh;
         h->non_elf = 0;
         h->def_regular = 1;
         h->type = STT_SECTION;

         if (! bfd_elf_link_record_dynamic_symbol (info, h))
           return FALSE;
       }

      /* We need to create a .compact_rel section.  */
      if (SGI_COMPAT (abfd))
       {
         if (!mips_elf_create_compact_rel_section (abfd, info))
           return FALSE;
       }

      /* Change alignments of some sections.  */
      s = bfd_get_section_by_name (abfd, ".hash");
      if (s != NULL)
       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
      s = bfd_get_section_by_name (abfd, ".dynsym");
      if (s != NULL)
       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
      s = bfd_get_section_by_name (abfd, ".dynstr");
      if (s != NULL)
       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
      s = bfd_get_section_by_name (abfd, ".reginfo");
      if (s != NULL)
       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
      s = bfd_get_section_by_name (abfd, ".dynamic");
      if (s != NULL)
       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
    }

  if (!info->shared)
    {
      const char *name;

      name = SGI_COMPAT (abfd) ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING";
      bh = NULL;
      if (!(_bfd_generic_link_add_one_symbol
           (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr, 0,
            NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
       return FALSE;

      h = (struct elf_link_hash_entry *) bh;
      h->non_elf = 0;
      h->def_regular = 1;
      h->type = STT_SECTION;

      if (! bfd_elf_link_record_dynamic_symbol (info, h))
       return FALSE;

      if (! mips_elf_hash_table (info)->use_rld_obj_head)
       {
         /* __rld_map is a four byte word located in the .data section
            and is filled in by the rtld to contain a pointer to
            the _r_debug structure. Its symbol value will be set in
            _bfd_mips_elf_finish_dynamic_symbol.  */
         s = bfd_get_section_by_name (abfd, ".rld_map");
         BFD_ASSERT (s != NULL);

         name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP";
         bh = NULL;
         if (!(_bfd_generic_link_add_one_symbol
              (info, abfd, name, BSF_GLOBAL, s, 0, NULL, FALSE,
               get_elf_backend_data (abfd)->collect, &bh)))
           return FALSE;

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

         if (! bfd_elf_link_record_dynamic_symbol (info, h))
           return FALSE;
       }
    }

  if (htab->is_vxworks)
    {
      /* Create the .plt, .rela.plt, .dynbss and .rela.bss sections.
        Also create the _PROCEDURE_LINKAGE_TABLE symbol.  */
      if (!_bfd_elf_create_dynamic_sections (abfd, info))
       return FALSE;

      /* Cache the sections created above.  */
      htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
      htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
      htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
      htab->splt = bfd_get_section_by_name (abfd, ".plt");
      if (!htab->sdynbss
         || (!htab->srelbss && !info->shared)
         || !htab->srelplt
         || !htab->splt)
       abort ();

      /* Do the usual VxWorks handling.  */
      if (!elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
       return FALSE;

      /* Work out the PLT sizes.  */
      if (info->shared)
       {
         htab->plt_header_size
           = 4 * ARRAY_SIZE (mips_vxworks_shared_plt0_entry);
         htab->plt_entry_size
           = 4 * ARRAY_SIZE (mips_vxworks_shared_plt_entry);
       }
      else
       {
         htab->plt_header_size
           = 4 * ARRAY_SIZE (mips_vxworks_exec_plt0_entry);
         htab->plt_entry_size
           = 4 * ARRAY_SIZE (mips_vxworks_exec_plt_entry);
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 9749 of file elfxx-mips.c.

{
  asection *o;
  bfd_boolean ret = FALSE;
  unsigned char *tdata;
  size_t i, skip;

  o = bfd_get_section_by_name (abfd, ".pdr");
  if (! o)
    return FALSE;
  if (o->size == 0)
    return FALSE;
  if (o->size % PDR_SIZE != 0)
    return FALSE;
  if (o->output_section != NULL
      && bfd_is_abs_section (o->output_section))
    return FALSE;

  tdata = bfd_zmalloc (o->size / PDR_SIZE);
  if (! tdata)
    return FALSE;

  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
                                       info->keep_memory);
  if (!cookie->rels)
    {
      free (tdata);
      return FALSE;
    }

  cookie->rel = cookie->rels;
  cookie->relend = cookie->rels + o->reloc_count;

  for (i = 0, skip = 0; i < o->size / PDR_SIZE; i ++)
    {
      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
       {
         tdata[i] = 1;
         skip ++;
       }
    }

  if (skip != 0)
    {
      mips_elf_section_data (o)->u.tdata = tdata;
      o->size -= skip * PDR_SIZE;
      ret = TRUE;
    }
  else
    free (tdata);

  if (! info->keep_memory)
    free (cookie->rels);

  return ret;
}

Here is the call graph for this function:

Definition at line 5226 of file elfxx-mips.c.

{
  if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
    return 8;
  if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64)
    {
      bfd_boolean long32_p, long64_p;

      long32_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long32") != 0;
      long64_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long64") != 0;
      if (long32_p && long64_p)
       return 0;
      if (long32_p)
       return 4;
      if (long64_p)
       return 8;

      if (sec->reloc_count > 0
         && elf_section_data (sec)->relocs != NULL
         && (ELF32_R_TYPE (elf_section_data (sec)->relocs[0].r_info)
             == R_MIPS_64))
       return 8;

      return 0;
    }
  return 4;
}

Here is the call graph for this function:

Definition at line 5584 of file elfxx-mips.c.

{
  register const char *name;
  unsigned int sh_type;

  name = bfd_get_section_name (abfd, sec);
  sh_type = hdr->sh_type;

  if (strcmp (name, ".liblist") == 0)
    {
      hdr->sh_type = SHT_MIPS_LIBLIST;
      hdr->sh_info = sec->size / sizeof (Elf32_Lib);
      /* The sh_link field is set in final_write_processing.  */
    }
  else if (strcmp (name, ".conflict") == 0)
    hdr->sh_type = SHT_MIPS_CONFLICT;
  else if (CONST_STRNEQ (name, ".gptab."))
    {
      hdr->sh_type = SHT_MIPS_GPTAB;
      hdr->sh_entsize = sizeof (Elf32_External_gptab);
      /* The sh_info field is set in final_write_processing.  */
    }
  else if (strcmp (name, ".ucode") == 0)
    hdr->sh_type = SHT_MIPS_UCODE;
  else if (strcmp (name, ".mdebug") == 0)
    {
      hdr->sh_type = SHT_MIPS_DEBUG;
      /* In a shared object on IRIX 5.3, the .mdebug section has an
         entsize of 0.  FIXME: Does this matter?  */
      if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0)
       hdr->sh_entsize = 0;
      else
       hdr->sh_entsize = 1;
    }
  else if (strcmp (name, ".reginfo") == 0)
    {
      hdr->sh_type = SHT_MIPS_REGINFO;
      /* In a shared object on IRIX 5.3, the .reginfo section has an
         entsize of 0x18.  FIXME: Does this matter?  */
      if (SGI_COMPAT (abfd))
       {
         if ((abfd->flags & DYNAMIC) != 0)
           hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
         else
           hdr->sh_entsize = 1;
       }
      else
       hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
    }
  else if (SGI_COMPAT (abfd)
          && (strcmp (name, ".hash") == 0
              || strcmp (name, ".dynamic") == 0
              || strcmp (name, ".dynstr") == 0))
    {
      if (SGI_COMPAT (abfd))
       hdr->sh_entsize = 0;
#if 0
      /* This isn't how the IRIX6 linker behaves.  */
      hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
#endif
    }
  else if (strcmp (name, ".got") == 0
          || strcmp (name, ".srdata") == 0
          || strcmp (name, ".sdata") == 0
          || strcmp (name, ".sbss") == 0
          || strcmp (name, ".lit4") == 0
          || strcmp (name, ".lit8") == 0)
    hdr->sh_flags |= SHF_MIPS_GPREL;
  else if (strcmp (name, ".MIPS.interfaces") == 0)
    {
      hdr->sh_type = SHT_MIPS_IFACE;
      hdr->sh_flags |= SHF_MIPS_NOSTRIP;
    }
  else if (CONST_STRNEQ (name, ".MIPS.content"))
    {
      hdr->sh_type = SHT_MIPS_CONTENT;
      hdr->sh_flags |= SHF_MIPS_NOSTRIP;
      /* The sh_info field is set in final_write_processing.  */
    }
  else if (MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
    {
      hdr->sh_type = SHT_MIPS_OPTIONS;
      hdr->sh_entsize = 1;
      hdr->sh_flags |= SHF_MIPS_NOSTRIP;
    }
  else if (CONST_STRNEQ (name, ".debug_"))
    hdr->sh_type = SHT_MIPS_DWARF;
  else if (strcmp (name, ".MIPS.symlib") == 0)
    {
      hdr->sh_type = SHT_MIPS_SYMBOL_LIB;
      /* The sh_link and sh_info fields are set in
         final_write_processing.  */
    }
  else if (CONST_STRNEQ (name, ".MIPS.events")
          || CONST_STRNEQ (name, ".MIPS.post_rel"))
    {
      hdr->sh_type = SHT_MIPS_EVENTS;
      hdr->sh_flags |= SHF_MIPS_NOSTRIP;
      /* The sh_link field is set in final_write_processing.  */
    }
  else if (strcmp (name, ".msym") == 0)
    {
      hdr->sh_type = SHT_MIPS_MSYM;
      hdr->sh_flags |= SHF_ALLOC;
      hdr->sh_entsize = 8;
    }

  /* In the unlikely event a special section is empty it has to lose its
     special meaning.  This may happen e.g. when using `strip' with the
     "--only-keep-debug" option.  */
  if (sec->size > 0 && !(sec->flags & SEC_HAS_CONTENTS))
    hdr->sh_type = sh_type;

  /* The generic elf_fake_sections will set up REL_HDR using the default
   kind of relocations.  We used to set up a second header for the
   non-default kind of relocations here, but only NewABI would use
   these, and the IRIX ld doesn't like resulting empty RELA sections.
   Thus we create those header only on demand now.  */

  return TRUE;
}

Here is the call graph for this function:

Definition at line 10238 of file elfxx-mips.c.

{
  asection *o;
  struct bfd_link_order *p;
  asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec;
  asection *rtproc_sec;
  Elf32_RegInfo reginfo;
  struct ecoff_debug_info debug;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct ecoff_debug_swap *swap = bed->elf_backend_ecoff_debug_swap;
  HDRR *symhdr = &debug.symbolic_header;
  void *mdebug_handle = NULL;
  asection *s;
  EXTR esym;
  unsigned int i;
  bfd_size_type amt;
  struct mips_elf_link_hash_table *htab;

  static const char * const secname[] =
  {
    ".text", ".init", ".fini", ".data",
    ".rodata", ".sdata", ".sbss", ".bss"
  };
  static const int sc[] =
  {
    scText, scInit, scFini, scData,
    scRData, scSData, scSBss, scBss
  };

  /* We'd carefully arranged the dynamic symbol indices, and then the
     generic size_dynamic_sections renumbered them out from under us.
     Rather than trying somehow to prevent the renumbering, just do
     the sort again.  */
  htab = mips_elf_hash_table (info);
  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfd *dynobj;
      asection *got;
      struct mips_got_info *g;
      bfd_size_type dynsecsymcount;

      /* When we resort, we must tell mips_elf_sort_hash_table what
        the lowest index it may use is.  That's the number of section
        symbols we're going to add.  The generic ELF linker only
        adds these symbols when building a shared object.  Note that
        we count the sections after (possibly) removing the .options
        section above.  */

      dynsecsymcount = count_section_dynsyms (abfd, info);
      if (! mips_elf_sort_hash_table (info, dynsecsymcount + 1))
       return FALSE;

      /* Make sure we didn't grow the global .got region.  */
      dynobj = elf_hash_table (info)->dynobj;
      got = mips_elf_got_section (dynobj, FALSE);
      g = mips_elf_section_data (got)->u.got_info;

      if (g->global_gotsym != NULL)
       BFD_ASSERT ((elf_hash_table (info)->dynsymcount
                   - g->global_gotsym->dynindx)
                  <= g->global_gotno);
    }

  /* Get a value for the GP register.  */
  if (elf_gp (abfd) == 0)
    {
      struct bfd_link_hash_entry *h;

      h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
      if (h != NULL && h->type == bfd_link_hash_defined)
       elf_gp (abfd) = (h->u.def.value
                      + h->u.def.section->output_section->vma
                      + h->u.def.section->output_offset);
      else if (htab->is_vxworks
              && (h = bfd_link_hash_lookup (info->hash,
                                        "_GLOBAL_OFFSET_TABLE_",
                                        FALSE, FALSE, TRUE))
              && h->type == bfd_link_hash_defined)
       elf_gp (abfd) = (h->u.def.section->output_section->vma
                      + h->u.def.section->output_offset
                      + h->u.def.value);
      else if (info->relocatable)
       {
         bfd_vma lo = MINUS_ONE;

         /* Find the GP-relative section with the lowest offset.  */
         for (o = abfd->sections; o != NULL; o = o->next)
           if (o->vma < lo
              && (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL))
             lo = o->vma;

         /* And calculate GP relative to that.  */
         elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (info);
       }
      else
       {
         /* If the relocate_section function needs to do a reloc
            involving the GP value, it should make a reloc_dangerous
            callback to warn that GP is not defined.  */
       }
    }

  /* Go through the sections and collect the .reginfo and .mdebug
     information.  */
  reginfo_sec = NULL;
  mdebug_sec = NULL;
  gptab_data_sec = NULL;
  gptab_bss_sec = NULL;
  for (o = abfd->sections; o != NULL; o = o->next)
    {
      if (strcmp (o->name, ".reginfo") == 0)
       {
         memset (&reginfo, 0, sizeof reginfo);

         /* We have found the .reginfo section in the output file.
            Look through all the link_orders comprising it and merge
            the information together.  */
         for (p = o->map_head.link_order; p != NULL; p = p->next)
           {
             asection *input_section;
             bfd *input_bfd;
             Elf32_External_RegInfo ext;
             Elf32_RegInfo sub;

             if (p->type != bfd_indirect_link_order)
              {
                if (p->type == bfd_data_link_order)
                  continue;
                abort ();
              }

             input_section = p->u.indirect.section;
             input_bfd = input_section->owner;

             if (! bfd_get_section_contents (input_bfd, input_section,
                                         &ext, 0, sizeof ext))
              return FALSE;

             bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);

             reginfo.ri_gprmask |= sub.ri_gprmask;
             reginfo.ri_cprmask[0] |= sub.ri_cprmask[0];
             reginfo.ri_cprmask[1] |= sub.ri_cprmask[1];
             reginfo.ri_cprmask[2] |= sub.ri_cprmask[2];
             reginfo.ri_cprmask[3] |= sub.ri_cprmask[3];

             /* ri_gp_value is set by the function
               mips_elf32_section_processing when the section is
               finally written out.  */

             /* Hack: reset the SEC_HAS_CONTENTS flag so that
               elf_link_input_bfd ignores this section.  */
             input_section->flags &= ~SEC_HAS_CONTENTS;
           }

         /* Size has been set in _bfd_mips_elf_always_size_sections.  */
         BFD_ASSERT(o->size == sizeof (Elf32_External_RegInfo));

         /* Skip this section later on (I don't think this currently
            matters, but someday it might).  */
         o->map_head.link_order = NULL;

         reginfo_sec = o;
       }

      if (strcmp (o->name, ".mdebug") == 0)
       {
         struct extsym_info einfo;
         bfd_vma last;

         /* We have found the .mdebug section in the output file.
            Look through all the link_orders comprising it and merge
            the information together.  */
         symhdr->magic = swap->sym_magic;
         /* FIXME: What should the version stamp be?  */
         symhdr->vstamp = 0;
         symhdr->ilineMax = 0;
         symhdr->cbLine = 0;
         symhdr->idnMax = 0;
         symhdr->ipdMax = 0;
         symhdr->isymMax = 0;
         symhdr->ioptMax = 0;
         symhdr->iauxMax = 0;
         symhdr->issMax = 0;
         symhdr->issExtMax = 0;
         symhdr->ifdMax = 0;
         symhdr->crfd = 0;
         symhdr->iextMax = 0;

         /* We accumulate the debugging information itself in the
            debug_info structure.  */
         debug.line = NULL;
         debug.external_dnr = NULL;
         debug.external_pdr = NULL;
         debug.external_sym = NULL;
         debug.external_opt = NULL;
         debug.external_aux = NULL;
         debug.ss = NULL;
         debug.ssext = debug.ssext_end = NULL;
         debug.external_fdr = NULL;
         debug.external_rfd = NULL;
         debug.external_ext = debug.external_ext_end = NULL;

         mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
         if (mdebug_handle == NULL)
           return FALSE;

         esym.jmptbl = 0;
         esym.cobol_main = 0;
         esym.weakext = 0;
         esym.reserved = 0;
         esym.ifd = ifdNil;
         esym.asym.iss = issNil;
         esym.asym.st = stLocal;
         esym.asym.reserved = 0;
         esym.asym.index = indexNil;
         last = 0;
         for (i = 0; i < sizeof (secname) / sizeof (secname[0]); i++)
           {
             esym.asym.sc = sc[i];
             s = bfd_get_section_by_name (abfd, secname[i]);
             if (s != NULL)
              {
                esym.asym.value = s->vma;
                last = s->vma + s->size;
              }
             else
              esym.asym.value = last;
             if (!bfd_ecoff_debug_one_external (abfd, &debug, swap,
                                           secname[i], &esym))
              return FALSE;
           }

         for (p = o->map_head.link_order; p != NULL; p = p->next)
           {
             asection *input_section;
             bfd *input_bfd;
             const struct ecoff_debug_swap *input_swap;
             struct ecoff_debug_info input_debug;
             char *eraw_src;
             char *eraw_end;

             if (p->type != bfd_indirect_link_order)
              {
                if (p->type == bfd_data_link_order)
                  continue;
                abort ();
              }

             input_section = p->u.indirect.section;
             input_bfd = input_section->owner;

             if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
                || (get_elf_backend_data (input_bfd)
                    ->elf_backend_ecoff_debug_swap) == NULL)
              {
                /* I don't know what a non MIPS ELF bfd would be
                   doing with a .mdebug section, but I don't really
                   want to deal with it.  */
                continue;
              }

             input_swap = (get_elf_backend_data (input_bfd)
                         ->elf_backend_ecoff_debug_swap);

             BFD_ASSERT (p->size == input_section->size);

             /* The ECOFF linking code expects that we have already
               read in the debugging information and set up an
               ecoff_debug_info structure, so we do that now.  */
             if (! _bfd_mips_elf_read_ecoff_info (input_bfd, input_section,
                                             &input_debug))
              return FALSE;

             if (! (bfd_ecoff_debug_accumulate
                   (mdebug_handle, abfd, &debug, swap, input_bfd,
                    &input_debug, input_swap, info)))
              return FALSE;

             /* Loop through the external symbols.  For each one with
               interesting information, try to find the symbol in
               the linker global hash table and save the information
               for the output external symbols.  */
             eraw_src = input_debug.external_ext;
             eraw_end = (eraw_src
                       + (input_debug.symbolic_header.iextMax
                          * input_swap->external_ext_size));
             for (;
                 eraw_src < eraw_end;
                 eraw_src += input_swap->external_ext_size)
              {
                EXTR ext;
                const char *name;
                struct mips_elf_link_hash_entry *h;

                (*input_swap->swap_ext_in) (input_bfd, eraw_src, &ext);
                if (ext.asym.sc == scNil
                    || ext.asym.sc == scUndefined
                    || ext.asym.sc == scSUndefined)
                  continue;

                name = input_debug.ssext + ext.asym.iss;
                h = mips_elf_link_hash_lookup (mips_elf_hash_table (info),
                                           name, FALSE, FALSE, TRUE);
                if (h == NULL || h->esym.ifd != -2)
                  continue;

                if (ext.ifd != -1)
                  {
                    BFD_ASSERT (ext.ifd
                              < input_debug.symbolic_header.ifdMax);
                    ext.ifd = input_debug.ifdmap[ext.ifd];
                  }

                h->esym = ext;
              }

             /* Free up the information we just read.  */
             free (input_debug.line);
             free (input_debug.external_dnr);
             free (input_debug.external_pdr);
             free (input_debug.external_sym);
             free (input_debug.external_opt);
             free (input_debug.external_aux);
             free (input_debug.ss);
             free (input_debug.ssext);
             free (input_debug.external_fdr);
             free (input_debug.external_rfd);
             free (input_debug.external_ext);

             /* Hack: reset the SEC_HAS_CONTENTS flag so that
               elf_link_input_bfd ignores this section.  */
             input_section->flags &= ~SEC_HAS_CONTENTS;
           }

         if (SGI_COMPAT (abfd) && info->shared)
           {
             /* Create .rtproc section.  */
             rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
             if (rtproc_sec == NULL)
              {
                flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
                                | SEC_LINKER_CREATED | SEC_READONLY);

                rtproc_sec = bfd_make_section_with_flags (abfd,
                                                     ".rtproc",
                                                     flags);
                if (rtproc_sec == NULL
                    || ! bfd_set_section_alignment (abfd, rtproc_sec, 4))
                  return FALSE;
              }

             if (! mips_elf_create_procedure_table (mdebug_handle, abfd,
                                               info, rtproc_sec,
                                               &debug))
              return FALSE;
           }

         /* Build the external symbol information.  */
         einfo.abfd = abfd;
         einfo.info = info;
         einfo.debug = &debug;
         einfo.swap = swap;
         einfo.failed = FALSE;
         mips_elf_link_hash_traverse (mips_elf_hash_table (info),
                                   mips_elf_output_extsym, &einfo);
         if (einfo.failed)
           return FALSE;

         /* Set the size of the .mdebug section.  */
         o->size = bfd_ecoff_debug_size (abfd, &debug, swap);

         /* Skip this section later on (I don't think this currently
            matters, but someday it might).  */
         o->map_head.link_order = NULL;

         mdebug_sec = o;
       }

      if (CONST_STRNEQ (o->name, ".gptab."))
       {
         const char *subname;
         unsigned int c;
         Elf32_gptab *tab;
         Elf32_External_gptab *ext_tab;
         unsigned int j;

         /* The .gptab.sdata and .gptab.sbss sections hold
            information describing how the small data area would
            change depending upon the -G switch.  These sections
            not used in executables files.  */
         if (! info->relocatable)
           {
             for (p = o->map_head.link_order; p != NULL; p = p->next)
              {
                asection *input_section;

                if (p->type != bfd_indirect_link_order)
                  {
                    if (p->type == bfd_data_link_order)
                     continue;
                    abort ();
                  }

                input_section = p->u.indirect.section;

                /* Hack: reset the SEC_HAS_CONTENTS flag so that
                   elf_link_input_bfd ignores this section.  */
                input_section->flags &= ~SEC_HAS_CONTENTS;
              }

             /* Skip this section later on (I don't think this
               currently matters, but someday it might).  */
             o->map_head.link_order = NULL;

             /* Really remove the section.  */
             bfd_section_list_remove (abfd, o);
             --abfd->section_count;

             continue;
           }

         /* There is one gptab for initialized data, and one for
            uninitialized data.  */
         if (strcmp (o->name, ".gptab.sdata") == 0)
           gptab_data_sec = o;
         else if (strcmp (o->name, ".gptab.sbss") == 0)
           gptab_bss_sec = o;
         else
           {
             (*_bfd_error_handler)
              (_("%s: illegal section name `%s'"),
               bfd_get_filename (abfd), o->name);
             bfd_set_error (bfd_error_nonrepresentable_section);
             return FALSE;
           }

         /* The linker script always combines .gptab.data and
            .gptab.sdata into .gptab.sdata, and likewise for
            .gptab.bss and .gptab.sbss.  It is possible that there is
            no .sdata or .sbss section in the output file, in which
            case we must change the name of the output section.  */
         subname = o->name + sizeof ".gptab" - 1;
         if (bfd_get_section_by_name (abfd, subname) == NULL)
           {
             if (o == gptab_data_sec)
              o->name = ".gptab.data";
             else
              o->name = ".gptab.bss";
             subname = o->name + sizeof ".gptab" - 1;
             BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL);
           }

         /* Set up the first entry.  */
         c = 1;
         amt = c * sizeof (Elf32_gptab);
         tab = bfd_malloc (amt);
         if (tab == NULL)
           return FALSE;
         tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
         tab[0].gt_header.gt_unused = 0;

         /* Combine the input sections.  */
         for (p = o->map_head.link_order; p != NULL; p = p->next)
           {
             asection *input_section;
             bfd *input_bfd;
             bfd_size_type size;
             unsigned long last;
             bfd_size_type gpentry;

             if (p->type != bfd_indirect_link_order)
              {
                if (p->type == bfd_data_link_order)
                  continue;
                abort ();
              }

             input_section = p->u.indirect.section;
             input_bfd = input_section->owner;

             /* Combine the gptab entries for this input section one
               by one.  We know that the input gptab entries are
               sorted by ascending -G value.  */
             size = input_section->size;
             last = 0;
             for (gpentry = sizeof (Elf32_External_gptab);
                 gpentry < size;
                 gpentry += sizeof (Elf32_External_gptab))
              {
                Elf32_External_gptab ext_gptab;
                Elf32_gptab int_gptab;
                unsigned long val;
                unsigned long add;
                bfd_boolean exact;
                unsigned int look;

                if (! (bfd_get_section_contents
                      (input_bfd, input_section, &ext_gptab, gpentry,
                       sizeof (Elf32_External_gptab))))
                  {
                    free (tab);
                    return FALSE;
                  }

                bfd_mips_elf32_swap_gptab_in (input_bfd, &ext_gptab,
                                          &int_gptab);
                val = int_gptab.gt_entry.gt_g_value;
                add = int_gptab.gt_entry.gt_bytes - last;

                exact = FALSE;
                for (look = 1; look < c; look++)
                  {
                    if (tab[look].gt_entry.gt_g_value >= val)
                     tab[look].gt_entry.gt_bytes += add;

                    if (tab[look].gt_entry.gt_g_value == val)
                     exact = TRUE;
                  }

                if (! exact)
                  {
                    Elf32_gptab *new_tab;
                    unsigned int max;

                    /* We need a new table entry.  */
                    amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab);
                    new_tab = bfd_realloc (tab, amt);
                    if (new_tab == NULL)
                     {
                       free (tab);
                       return FALSE;
                     }
                    tab = new_tab;
                    tab[c].gt_entry.gt_g_value = val;
                    tab[c].gt_entry.gt_bytes = add;

                    /* Merge in the size for the next smallest -G
                      value, since that will be implied by this new
                      value.  */
                    max = 0;
                    for (look = 1; look < c; look++)
                     {
                       if (tab[look].gt_entry.gt_g_value < val
                           && (max == 0
                              || (tab[look].gt_entry.gt_g_value
                                  > tab[max].gt_entry.gt_g_value)))
                         max = look;
                     }
                    if (max != 0)
                     tab[c].gt_entry.gt_bytes +=
                       tab[max].gt_entry.gt_bytes;

                    ++c;
                  }

                last = int_gptab.gt_entry.gt_bytes;
              }

             /* Hack: reset the SEC_HAS_CONTENTS flag so that
               elf_link_input_bfd ignores this section.  */
             input_section->flags &= ~SEC_HAS_CONTENTS;
           }

         /* The table must be sorted by -G value.  */
         if (c > 2)
           qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare);

         /* Swap out the table.  */
         amt = (bfd_size_type) c * sizeof (Elf32_External_gptab);
         ext_tab = bfd_alloc (abfd, amt);
         if (ext_tab == NULL)
           {
             free (tab);
             return FALSE;
           }

         for (j = 0; j < c; j++)
           bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j);
         free (tab);

         o->size = c * sizeof (Elf32_External_gptab);
         o->contents = (bfd_byte *) ext_tab;

         /* Skip this section later on (I don't think this currently
            matters, but someday it might).  */
         o->map_head.link_order = NULL;
       }
    }

  /* Invoke the regular ELF backend linker to do all the work.  */
  if (!bfd_elf_final_link (abfd, info))
    return FALSE;

  /* Now write out the computed sections.  */

  if (reginfo_sec != NULL)
    {
      Elf32_External_RegInfo ext;

      bfd_mips_elf32_swap_reginfo_out (abfd, &reginfo, &ext);
      if (! bfd_set_section_contents (abfd, reginfo_sec, &ext, 0, sizeof ext))
       return FALSE;
    }

  if (mdebug_sec != NULL)
    {
      BFD_ASSERT (abfd->output_has_begun);
      if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
                                          swap, info,
                                          mdebug_sec->filepos))
       return FALSE;

      bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
    }

  if (gptab_data_sec != NULL)
    {
      if (! bfd_set_section_contents (abfd, gptab_data_sec,
                                  gptab_data_sec->contents,
                                  0, gptab_data_sec->size))
       return FALSE;
    }

  if (gptab_bss_sec != NULL)
    {
      if (! bfd_set_section_contents (abfd, gptab_bss_sec,
                                  gptab_bss_sec->contents,
                                  0, gptab_bss_sec->size))
       return FALSE;
    }

  if (SGI_COMPAT (abfd))
    {
      rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
      if (rtproc_sec != NULL)
       {
         if (! bfd_set_section_contents (abfd, rtproc_sec,
                                     rtproc_sec->contents,
                                     0, rtproc_sec->size))
           return FALSE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

void _bfd_mips_elf_final_write_processing ( bfd abfd,
bfd_boolean linker  ATTRIBUTE_UNUSED 
)

Definition at line 9209 of file elfxx-mips.c.

{
  unsigned int i;
  Elf_Internal_Shdr **hdrpp;
  const char *name;
  asection *sec;

  /* Keep the existing EF_MIPS_MACH and EF_MIPS_ARCH flags if the former
     is nonzero.  This is for compatibility with old objects, which used
     a combination of a 32-bit EF_MIPS_ARCH and a 64-bit EF_MIPS_MACH.  */
  if ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == 0)
    mips_set_isa_flags (abfd);

  /* Set the sh_info field for .gptab sections and other appropriate
     info for each special section.  */
  for (i = 1, hdrpp = elf_elfsections (abfd) + 1;
       i < elf_numsections (abfd);
       i++, hdrpp++)
    {
      switch ((*hdrpp)->sh_type)
       {
       case SHT_MIPS_MSYM:
       case SHT_MIPS_LIBLIST:
         sec = bfd_get_section_by_name (abfd, ".dynstr");
         if (sec != NULL)
           (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
         break;

       case SHT_MIPS_GPTAB:
         BFD_ASSERT ((*hdrpp)->bfd_section != NULL);
         name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section);
         BFD_ASSERT (name != NULL
                    && CONST_STRNEQ (name, ".gptab."));
         sec = bfd_get_section_by_name (abfd, name + sizeof ".gptab" - 1);
         BFD_ASSERT (sec != NULL);
         (*hdrpp)->sh_info = elf_section_data (sec)->this_idx;
         break;

       case SHT_MIPS_CONTENT:
         BFD_ASSERT ((*hdrpp)->bfd_section != NULL);
         name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section);
         BFD_ASSERT (name != NULL
                    && CONST_STRNEQ (name, ".MIPS.content"));
         sec = bfd_get_section_by_name (abfd,
                                    name + sizeof ".MIPS.content" - 1);
         BFD_ASSERT (sec != NULL);
         (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
         break;

       case SHT_MIPS_SYMBOL_LIB:
         sec = bfd_get_section_by_name (abfd, ".dynsym");
         if (sec != NULL)
           (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
         sec = bfd_get_section_by_name (abfd, ".liblist");
         if (sec != NULL)
           (*hdrpp)->sh_info = elf_section_data (sec)->this_idx;
         break;

       case SHT_MIPS_EVENTS:
         BFD_ASSERT ((*hdrpp)->bfd_section != NULL);
         name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section);
         BFD_ASSERT (name != NULL);
         if (CONST_STRNEQ (name, ".MIPS.events"))
           sec = bfd_get_section_by_name (abfd,
                                      name + sizeof ".MIPS.events" - 1);
         else
           {
             BFD_ASSERT (CONST_STRNEQ (name, ".MIPS.post_rel"));
             sec = bfd_get_section_by_name (abfd,
                                        (name
                                         + sizeof ".MIPS.post_rel" - 1));
           }
         BFD_ASSERT (sec != NULL);
         (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
         break;

       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_mips_elf_find_inliner_info ( bfd abfd,
const char **  filename_ptr,
const char **  functionname_ptr,
unsigned int line_ptr 
)

Definition at line 9957 of file elfxx-mips.c.

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

Here is the call graph for this function:

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

Definition at line 9856 of file elfxx-mips.c.

{
  asection *msec;

  if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
                                 filename_ptr, functionname_ptr,
                                 line_ptr))
    return TRUE;

  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
                                 filename_ptr, functionname_ptr,
                                 line_ptr, ABI_64_P (abfd) ? 8 : 0,
                                 &elf_tdata (abfd)->dwarf2_find_line_info))
    return TRUE;

  msec = bfd_get_section_by_name (abfd, ".mdebug");
  if (msec != NULL)
    {
      flagword origflags;
      struct mips_elf_find_line *fi;
      const struct ecoff_debug_swap * const swap =
       get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;

      /* If we are called during a link, mips_elf_final_link may have
        cleared the SEC_HAS_CONTENTS field.  We force it back on here
        if appropriate (which it normally will be).  */
      origflags = msec->flags;
      if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
       msec->flags |= SEC_HAS_CONTENTS;

      fi = elf_tdata (abfd)->find_line_info;
      if (fi == NULL)
       {
         bfd_size_type external_fdr_size;
         char *fraw_src;
         char *fraw_end;
         struct fdr *fdr_ptr;
         bfd_size_type amt = sizeof (struct mips_elf_find_line);

         fi = bfd_zalloc (abfd, amt);
         if (fi == NULL)
           {
             msec->flags = origflags;
             return FALSE;
           }

         if (! _bfd_mips_elf_read_ecoff_info (abfd, msec, &fi->d))
           {
             msec->flags = origflags;
             return FALSE;
           }

         /* Swap in the FDR information.  */
         amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
         fi->d.fdr = bfd_alloc (abfd, amt);
         if (fi->d.fdr == NULL)
           {
             msec->flags = origflags;
             return FALSE;
           }
         external_fdr_size = swap->external_fdr_size;
         fdr_ptr = fi->d.fdr;
         fraw_src = (char *) fi->d.external_fdr;
         fraw_end = (fraw_src
                    + fi->d.symbolic_header.ifdMax * external_fdr_size);
         for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
           (*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr);

         elf_tdata (abfd)->find_line_info = fi;

         /* Note that we don't bother to ever free this information.
             find_nearest_line is either called all the time, as in
             objdump -l, so the information should be saved, or it is
             rarely called, as in ld error messages, so the memory
             wasted is unimportant.  Still, it would probably be a
             good idea for free_cached_info to throw it away.  */
       }

      if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
                              &fi->i, filename_ptr, functionname_ptr,
                              line_ptr))
       {
         msec->flags = origflags;
         return TRUE;
       }

      msec->flags = origflags;
    }

  /* Fall back on the generic ELF find_nearest_line routine.  */

  return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
                                 filename_ptr, functionname_ptr,
                                 line_ptr);
}

Here is the call graph for this function:

Definition at line 8689 of file elfxx-mips.c.

{
  bfd *dynobj;
  asection *sdyn;
  asection *sgot;
  struct mips_got_info *gg, *g;
  struct mips_elf_link_hash_table *htab;

  htab = mips_elf_hash_table (info);
  dynobj = elf_hash_table (info)->dynobj;

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

  sgot = mips_elf_got_section (dynobj, FALSE);
  if (sgot == NULL)
    gg = g = NULL;
  else
    {
      BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
      gg = mips_elf_section_data (sgot)->u.got_info;
      BFD_ASSERT (gg != NULL);
      g = mips_elf_got_for_ibfd (gg, output_bfd);
      BFD_ASSERT (g != NULL);
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfd_byte *b;
      int dyn_to_skip = 0, dyn_skipped = 0;

      BFD_ASSERT (sdyn != NULL);
      BFD_ASSERT (g != NULL);

      for (b = sdyn->contents;
          b < sdyn->contents + sdyn->size;
          b += MIPS_ELF_DYN_SIZE (dynobj))
       {
         Elf_Internal_Dyn dyn;
         const char *name;
         size_t elemsize;
         asection *s;
         bfd_boolean swap_out_p;

         /* Read in the current dynamic entry.  */
         (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);

         /* Assume that we're going to modify it and write it out.  */
         swap_out_p = TRUE;

         switch (dyn.d_tag)
           {
           case DT_RELENT:
             dyn.d_un.d_val = MIPS_ELF_REL_SIZE (dynobj);
             break;

           case DT_RELAENT:
             BFD_ASSERT (htab->is_vxworks);
             dyn.d_un.d_val = MIPS_ELF_RELA_SIZE (dynobj);
             break;

           case DT_STRSZ:
             /* Rewrite DT_STRSZ.  */
             dyn.d_un.d_val =
              _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
             break;

           case DT_PLTGOT:
             name = ".got";
             if (htab->is_vxworks)
              {
                /* _GLOBAL_OFFSET_TABLE_ is defined to be the beginning
                   of the ".got" section in DYNOBJ.  */
                s = bfd_get_section_by_name (dynobj, name);
                BFD_ASSERT (s != NULL);
                dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              }
             else
              {
                s = bfd_get_section_by_name (output_bfd, name);
                BFD_ASSERT (s != NULL);
                dyn.d_un.d_ptr = s->vma;
              }
             break;

           case DT_MIPS_RLD_VERSION:
             dyn.d_un.d_val = 1; /* XXX */
             break;

           case DT_MIPS_FLAGS:
             dyn.d_un.d_val = RHF_NOTPOT; /* XXX */
             break;

           case DT_MIPS_TIME_STAMP:
             {
              time_t t;
              time (&t);
              dyn.d_un.d_val = t;
             }
             break;

           case DT_MIPS_ICHECKSUM:
             /* XXX FIXME: */
             swap_out_p = FALSE;
             break;

           case DT_MIPS_IVERSION:
             /* XXX FIXME: */
             swap_out_p = FALSE;
             break;

           case DT_MIPS_BASE_ADDRESS:
             s = output_bfd->sections;
             BFD_ASSERT (s != NULL);
             dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
             break;

           case DT_MIPS_LOCAL_GOTNO:
             dyn.d_un.d_val = g->local_gotno;
             break;

           case DT_MIPS_UNREFEXTNO:
             /* The index into the dynamic symbol table which is the
               entry of the first external symbol that is not
               referenced within the same object.  */
             dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
             break;

           case DT_MIPS_GOTSYM:
             if (gg->global_gotsym)
              {
                dyn.d_un.d_val = gg->global_gotsym->dynindx;
                break;
              }
             /* In case if we don't have global got symbols we default
               to setting DT_MIPS_GOTSYM to the same value as
               DT_MIPS_SYMTABNO, so we just fall through.  */

           case DT_MIPS_SYMTABNO:
             name = ".dynsym";
             elemsize = MIPS_ELF_SYM_SIZE (output_bfd);
             s = bfd_get_section_by_name (output_bfd, name);
             BFD_ASSERT (s != NULL);

             dyn.d_un.d_val = s->size / elemsize;
             break;

           case DT_MIPS_HIPAGENO:
             dyn.d_un.d_val = g->local_gotno - MIPS_RESERVED_GOTNO (info);
             break;

           case DT_MIPS_RLD_MAP:
             dyn.d_un.d_ptr = mips_elf_hash_table (info)->rld_value;
             break;

           case DT_MIPS_OPTIONS:
             s = (bfd_get_section_by_name
                 (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (output_bfd)));
             dyn.d_un.d_ptr = s->vma;
             break;

           case DT_RELASZ:
             BFD_ASSERT (htab->is_vxworks);
             /* The count does not include the JUMP_SLOT relocations.  */
             if (htab->srelplt)
              dyn.d_un.d_val -= htab->srelplt->size;
             break;

           case DT_PLTREL:
             BFD_ASSERT (htab->is_vxworks);
             dyn.d_un.d_val = DT_RELA;
             break;

           case DT_PLTRELSZ:
             BFD_ASSERT (htab->is_vxworks);
             dyn.d_un.d_val = htab->srelplt->size;
             break;

           case DT_JMPREL:
             BFD_ASSERT (htab->is_vxworks);
             dyn.d_un.d_val = (htab->srelplt->output_section->vma
                            + htab->srelplt->output_offset);
             break;

           case DT_TEXTREL:
             /* If we didn't need any text relocations after all, delete
               the dynamic tag.  */
             if (!(info->flags & DF_TEXTREL))
              {
                dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
                swap_out_p = FALSE;
              }
             break;

           case DT_FLAGS:
             /* If we didn't need any text relocations after all, clear
               DF_TEXTREL from DT_FLAGS.  */
             if (!(info->flags & DF_TEXTREL))
              dyn.d_un.d_val &= ~DF_TEXTREL;
             else
              swap_out_p = FALSE;
             break;

           default:
             swap_out_p = FALSE;
             break;
           }

         if (swap_out_p || dyn_skipped)
           (*get_elf_backend_data (dynobj)->s->swap_dyn_out)
             (dynobj, &dyn, b - dyn_skipped);

         if (dyn_to_skip)
           {
             dyn_skipped += dyn_to_skip;
             dyn_to_skip = 0;
           }
       }

      /* Wipe out any trailing entries if we shifted down a dynamic tag.  */
      if (dyn_skipped > 0)
       memset (b - dyn_skipped, 0, dyn_skipped);
    }

  if (sgot != NULL && sgot->size > 0)
    {
      if (htab->is_vxworks)
       {
         /* The first entry of the global offset table points to the
            ".dynamic" section.  The second is initialized by the
            loader and contains the shared library identifier.
            The third is also initialized by the loader and points
            to the lazy resolution stub.  */
         MIPS_ELF_PUT_WORD (output_bfd,
                          sdyn->output_offset + sdyn->output_section->vma,
                          sgot->contents);
         MIPS_ELF_PUT_WORD (output_bfd, 0,
                          sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd));
         MIPS_ELF_PUT_WORD (output_bfd, 0,
                          sgot->contents
                          + 2 * MIPS_ELF_GOT_SIZE (output_bfd));
       }
      else
       {
         /* The first entry of the global offset table will be filled at
            runtime. The second entry will be used by some runtime loaders.
            This isn't the case of IRIX rld.  */
         MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0, sgot->contents);
         MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0x80000000,
                          sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd));
       }

      elf_section_data (sgot->output_section)->this_hdr.sh_entsize
        = MIPS_ELF_GOT_SIZE (output_bfd);
    }

  /* Generate dynamic relocations for the non-primary gots.  */
  if (gg != NULL && gg->next)
    {
      Elf_Internal_Rela rel[3];
      bfd_vma addend = 0;

      memset (rel, 0, sizeof (rel));
      rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_REL32);

      for (g = gg->next; g->next != gg; g = g->next)
       {
         bfd_vma index = g->next->local_gotno + g->next->global_gotno
           + g->next->tls_gotno;

         MIPS_ELF_PUT_WORD (output_bfd, 0, sgot->contents
                          + index++ * MIPS_ELF_GOT_SIZE (output_bfd));
         MIPS_ELF_PUT_WORD (output_bfd, 0x80000000, sgot->contents
                          + index++ * MIPS_ELF_GOT_SIZE (output_bfd));

         if (! info->shared)
           continue;

         while (index < g->assigned_gotno)
           {
             rel[0].r_offset = rel[1].r_offset = rel[2].r_offset
              = index++ * MIPS_ELF_GOT_SIZE (output_bfd);
             if (!(mips_elf_create_dynamic_relocation
                  (output_bfd, info, rel, NULL,
                   bfd_abs_section_ptr,
                   0, &addend, sgot)))
              return FALSE;
             BFD_ASSERT (addend == 0);
           }
       }
    }

  /* The generation of dynamic relocations for the non-primary gots
     adds more dynamic relocations.  We cannot count them until
     here.  */

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfd_byte *b;
      bfd_boolean swap_out_p;

      BFD_ASSERT (sdyn != NULL);

      for (b = sdyn->contents;
          b < sdyn->contents + sdyn->size;
          b += MIPS_ELF_DYN_SIZE (dynobj))
       {
         Elf_Internal_Dyn dyn;
         asection *s;

         /* Read in the current dynamic entry.  */
         (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);

         /* Assume that we're going to modify it and write it out.  */
         swap_out_p = TRUE;

         switch (dyn.d_tag)
           {
           case DT_RELSZ:
             /* Reduce DT_RELSZ to account for any relocations we
               decided not to make.  This is for the n64 irix rld,
               which doesn't seem to apply any relocations if there
               are trailing null entries.  */
             s = mips_elf_rel_dyn_section (info, FALSE);
             dyn.d_un.d_val = (s->reloc_count
                            * (ABI_64_P (output_bfd)
                               ? sizeof (Elf64_Mips_External_Rel)
                               : sizeof (Elf32_External_Rel)));
             /* Adjust the section size too.  Tools like the prelinker
               can reasonably expect the values to the same.  */
             elf_section_data (s->output_section)->this_hdr.sh_size
              = dyn.d_un.d_val;
             break;

           default:
             swap_out_p = FALSE;
             break;
           }

         if (swap_out_p)
           (*get_elf_backend_data (dynobj)->s->swap_dyn_out)
             (dynobj, &dyn, b);
       }
    }

  {
    asection *s;
    Elf32_compact_rel cpt;

    if (SGI_COMPAT (output_bfd))
      {
       /* Write .compact_rel section out.  */
       s = bfd_get_section_by_name (dynobj, ".compact_rel");
       if (s != NULL)
         {
           cpt.id1 = 1;
           cpt.num = s->reloc_count;
           cpt.id2 = 2;
           cpt.offset = (s->output_section->filepos
                       + sizeof (Elf32_External_compact_rel));
           cpt.reserved0 = 0;
           cpt.reserved1 = 0;
           bfd_elf32_swap_compact_rel_out (output_bfd, &cpt,
                                       ((Elf32_External_compact_rel *)
                                        s->contents));

           /* Clean up a dummy stub function entry in .text.  */
           s = bfd_get_section_by_name (dynobj,
                                    MIPS_ELF_STUB_SECTION_NAME (dynobj));
           if (s != NULL)
             {
              file_ptr dummy_offset;

              BFD_ASSERT (s->size >= htab->function_stub_size);
              dummy_offset = s->size - htab->function_stub_size;
              memset (s->contents + dummy_offset, 0,
                     htab->function_stub_size);
             }
         }
      }

    /* The psABI says that the dynamic relocations must be sorted in
       increasing order of r_symndx.  The VxWorks EABI doesn't require
       this, and because the code below handles REL rather than RELA
       relocations, using it for VxWorks would be outright harmful.  */
    if (!htab->is_vxworks)
      {
       s = mips_elf_rel_dyn_section (info, FALSE);
       if (s != NULL
           && s->size > (bfd_vma)2 * MIPS_ELF_REL_SIZE (output_bfd))
         {
           reldyn_sorting_bfd = output_bfd;

           if (ABI_64_P (output_bfd))
             qsort ((Elf64_External_Rel *) s->contents + 1,
                   s->reloc_count - 1, sizeof (Elf64_Mips_External_Rel),
                   sort_dynamic_relocs_64);
           else
             qsort ((Elf32_External_Rel *) s->contents + 1,
                   s->reloc_count - 1, sizeof (Elf32_External_Rel),
                   sort_dynamic_relocs);
         }
      }
  }

  if (htab->is_vxworks && htab->splt->size > 0)
    {
      if (info->shared)
       mips_vxworks_finish_shared_plt (output_bfd, info);
      else
       mips_vxworks_finish_exec_plt (output_bfd, info);
    }
  return TRUE;
}

Here is the call graph for this function:

bfd_boolean _bfd_mips_elf_finish_dynamic_symbol ( bfd output_bfd,
struct bfd_link_info info,
struct elf_link_hash_entry h,
Elf_Internal_Sym *  sym 
)

Definition at line 8193 of file elfxx-mips.c.

{
  bfd *dynobj;
  asection *sgot;
  struct mips_got_info *g, *gg;
  const char *name;
  int idx;
  struct mips_elf_link_hash_table *htab;

  htab = mips_elf_hash_table (info);
  dynobj = elf_hash_table (info)->dynobj;

  if (h->plt.offset != MINUS_ONE)
    {
      asection *s;
      bfd_byte stub[MIPS_FUNCTION_STUB_BIG_SIZE];

      /* This symbol has a stub.  Set it up.  */

      BFD_ASSERT (h->dynindx != -1);

      s = bfd_get_section_by_name (dynobj,
                               MIPS_ELF_STUB_SECTION_NAME (dynobj));
      BFD_ASSERT (s != NULL);

      BFD_ASSERT ((htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
                  || (h->dynindx <= 0xffff));

      /* Values up to 2^31 - 1 are allowed.  Larger values would cause
        sign extension at runtime in the stub, resulting in a negative
        index value.  */
      if (h->dynindx & ~0x7fffffff)
       return FALSE;

      /* Fill the stub.  */
      idx = 0;
      bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub + idx);
      idx += 4;
      bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
      idx += 4;
      if (htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
        {
          bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16) & 0x7fff),
                      stub + idx);
          idx += 4;
        }
      bfd_put_32 (output_bfd, STUB_JALR, stub + idx);
      idx += 4;

      /* If a large stub is not required and sign extension is not a
         problem, then use legacy code in the stub.  */
      if (htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
       bfd_put_32 (output_bfd, STUB_ORI (h->dynindx & 0xffff), stub + idx);
      else if (h->dynindx & ~0x7fff)
        bfd_put_32 (output_bfd, STUB_LI16U (h->dynindx & 0xffff), stub + idx);
      else
        bfd_put_32 (output_bfd, STUB_LI16S (output_bfd, h->dynindx),
                  stub + idx);

      BFD_ASSERT (h->plt.offset <= s->size);
      memcpy (s->contents + h->plt.offset, stub, htab->function_stub_size);

      /* Mark the symbol as undefined.  plt.offset != -1 occurs
        only for the referenced symbol.  */
      sym->st_shndx = SHN_UNDEF;

      /* The run-time linker uses the st_value field of the symbol
        to reset the global offset table entry for this external
        to its stub address when unlinking a shared object.  */
      sym->st_value = (s->output_section->vma + s->output_offset
                     + h->plt.offset);
    }

  BFD_ASSERT (h->dynindx != -1
             || h->forced_local);

  sgot = mips_elf_got_section (dynobj, FALSE);
  BFD_ASSERT (sgot != NULL);
  BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
  g = mips_elf_section_data (sgot)->u.got_info;
  BFD_ASSERT (g != NULL);

  /* Run through the global symbol table, creating GOT entries for all
     the symbols that need them.  */
  if (g->global_gotsym != NULL
      && h->dynindx >= g->global_gotsym->dynindx)
    {
      bfd_vma offset;
      bfd_vma value;

      value = sym->st_value;
      offset = mips_elf_global_got_index (dynobj, output_bfd, h, R_MIPS_GOT16, info);
      MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
    }

  if (g->next && h->dynindx != -1 && h->type != STT_TLS)
    {
      struct mips_got_entry e, *p;
      bfd_vma entry;
      bfd_vma offset;

      gg = g;

      e.abfd = output_bfd;
      e.symndx = -1;
      e.d.h = (struct mips_elf_link_hash_entry *)h;
      e.tls_type = 0;

      for (g = g->next; g->next != gg; g = g->next)
       {
         if (g->got_entries
             && (p = (struct mips_got_entry *) htab_find (g->got_entries,
                                                    &e)))
           {
             offset = p->gotidx;
             if (info->shared
                || (elf_hash_table (info)->dynamic_sections_created
                    && p->d.h != NULL
                    && p->d.h->root.def_dynamic
                    && !p->d.h->root.def_regular))
              {
                /* Create an R_MIPS_REL32 relocation for this entry.  Due to
                   the various compatibility problems, it's easier to mock
                   up an R_MIPS_32 or R_MIPS_64 relocation and leave
                   mips_elf_create_dynamic_relocation to calculate the
                   appropriate addend.  */
                Elf_Internal_Rela rel[3];

                memset (rel, 0, sizeof (rel));
                if (ABI_64_P (output_bfd))
                  rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_64);
                else
                  rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_32);
                rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;

                entry = 0;
                if (! (mips_elf_create_dynamic_relocation
                      (output_bfd, info, rel,
                       e.d.h, NULL, sym->st_value, &entry, sgot)))
                  return FALSE;
              }
             else
              entry = sym->st_value;
             MIPS_ELF_PUT_WORD (output_bfd, entry, sgot->contents + offset);
           }
       }
    }

  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
  name = h->root.root.string;
  if (strcmp (name, "_DYNAMIC") == 0
      || h == elf_hash_table (info)->hgot)
    sym->st_shndx = SHN_ABS;
  else if (strcmp (name, "_DYNAMIC_LINK") == 0
          || strcmp (name, "_DYNAMIC_LINKING") == 0)
    {
      sym->st_shndx = SHN_ABS;
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
      sym->st_value = 1;
    }
  else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (output_bfd))
    {
      sym->st_shndx = SHN_ABS;
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
      sym->st_value = elf_gp (output_bfd);
    }
  else if (SGI_COMPAT (output_bfd))
    {
      if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
         || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0)
       {
         sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
         sym->st_other = STO_PROTECTED;
         sym->st_value = 0;
         sym->st_shndx = SHN_MIPS_DATA;
       }
      else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0)
       {
         sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
         sym->st_other = STO_PROTECTED;
         sym->st_value = mips_elf_hash_table (info)->procedure_count;
         sym->st_shndx = SHN_ABS;
       }
      else if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS)
       {
         if (h->type == STT_FUNC)
           sym->st_shndx = SHN_MIPS_TEXT;
         else if (h->type == STT_OBJECT)
           sym->st_shndx = SHN_MIPS_DATA;
       }
    }

  /* Handle the IRIX6-specific symbols.  */
  if (IRIX_COMPAT (output_bfd) == ict_irix6)
    mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);

  if (! info->shared)
    {
      if (! mips_elf_hash_table (info)->use_rld_obj_head
         && (strcmp (name, "__rld_map") == 0
             || strcmp (name, "__RLD_MAP") == 0))
       {
         asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
         BFD_ASSERT (s != NULL);
         sym->st_value = s->output_section->vma + s->output_offset;
         bfd_put_32 (output_bfd, 0, s->contents);
         if (mips_elf_hash_table (info)->rld_value == 0)
           mips_elf_hash_table (info)->rld_value = sym->st_value;
       }
      else if (mips_elf_hash_table (info)->use_rld_obj_head
              && strcmp (name, "__rld_obj_head") == 0)
       {
         /* IRIX6 does not use a .rld_map section.  */
         if (IRIX_COMPAT (output_bfd) == ict_irix5
              || IRIX_COMPAT (output_bfd) == ict_none)
           BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map")
                     != NULL);
         mips_elf_hash_table (info)->rld_value = sym->st_value;
       }
    }

  /* If this is a mips16 symbol, force the value to be even.  */
  if (sym->st_other == STO_MIPS16)
    sym->st_value &= ~1;

  return TRUE;
}

Here is the call graph for this function:

asection* _bfd_mips_elf_gc_mark_hook ( asection sec,
struct bfd_link_info info,
Elf_Internal_Rela rel,
struct elf_link_hash_entry h,
Elf_Internal_Sym *  sym 
)

Definition at line 9580 of file elfxx-mips.c.

{
  /* ??? Do mips16 stub sections need to be handled special?  */

  if (h != NULL)
    switch (ELF_R_TYPE (sec->owner, rel->r_info))
      {
      case R_MIPS_GNU_VTINHERIT:
      case R_MIPS_GNU_VTENTRY:
       return NULL;
      }

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

Here is the call graph for this function:

bfd_boolean _bfd_mips_elf_gc_sweep_hook ( bfd *abfd  ATTRIBUTE_UNUSED,
struct bfd_link_info *info  ATTRIBUTE_UNUSED,
asection *sec  ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *relocs  ATTRIBUTE_UNUSED 
)

Definition at line 9602 of file elfxx-mips.c.

{
#if 0
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_signed_vma *local_got_refcounts;
  const Elf_Internal_Rela *rel, *relend;
  unsigned long r_symndx;
  struct elf_link_hash_entry *h;

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

  relend = relocs + sec->reloc_count;
  for (rel = relocs; rel < relend; rel++)
    switch (ELF_R_TYPE (abfd, rel->r_info))
      {
      case R_MIPS_GOT16:
      case R_MIPS_CALL16:
      case R_MIPS_CALL_HI16:
      case R_MIPS_CALL_LO16:
      case R_MIPS_GOT_HI16:
      case R_MIPS_GOT_LO16:
      case R_MIPS_GOT_DISP:
      case R_MIPS_GOT_PAGE:
      case R_MIPS_GOT_OFST:
       /* ??? It would seem that the existing MIPS code does no sort
          of reference counting or whatnot on its GOT and PLT entries,
          so it is not possible to garbage collect them at this time.  */
       break;

      default:
       break;
      }
#endif

  return TRUE;
}
bfd_reloc_status_type _bfd_mips_elf_generic_reloc ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent reloc_entry,
asymbol symbol,
void *data  ATTRIBUTE_UNUSED,
asection input_section,
bfd output_bfd,
char **error_message  ATTRIBUTE_UNUSED 
)

Definition at line 1492 of file elfxx-mips.c.

{
  bfd_signed_vma val;
  bfd_reloc_status_type status;
  bfd_boolean relocatable;

  relocatable = (output_bfd != NULL);

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

  /* Build up the field adjustment in VAL.  */
  val = 0;
  if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0)
    {
      /* Either we're calculating the final field value or we have a
        relocation against a section symbol.  Add in the section's
        offset or address.  */
      val += symbol->section->output_section->vma;
      val += symbol->section->output_offset;
    }

  if (!relocatable)
    {
      /* We're calculating the final field value.  Add in the symbol's value
        and, if pc-relative, subtract the address of the field itself.  */
      val += symbol->value;
      if (reloc_entry->howto->pc_relative)
       {
         val -= input_section->output_section->vma;
         val -= input_section->output_offset;
         val -= reloc_entry->address;
       }
    }

  /* VAL is now the final adjustment.  If we're keeping this relocation
     in the output file, and if the relocation uses a separate addend,
     we just need to add VAL to that addend.  Otherwise we need to add
     VAL to the relocation field itself.  */
  if (relocatable && !reloc_entry->howto->partial_inplace)
    reloc_entry->addend += val;
  else
    {
      bfd_byte *location = (bfd_byte *) data + reloc_entry->address;

      /* Add in the separate addend, if any.  */
      val += reloc_entry->addend;

      /* Add VAL to the relocation field.  */
      _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
                                   location);
      status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
                                   location);
      _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE,
                                 location);

      if (status != bfd_reloc_ok)
       return status;
    }

  if (relocatable)
    reloc_entry->address += input_section->output_offset;

  return bfd_reloc_ok;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 1416 of file elfxx-mips.c.

{
  if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
      || bfd_is_und_section (bfd_get_section (symbol))
      || bfd_is_com_section (bfd_get_section (symbol)))
    /* The relocation is against a global symbol.  */
    return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
                                   input_section, output_bfd,
                                   error_message);

  return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
                               input_section, output_bfd, error_message);
}

Here is the call graph for this function:

bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp ( bfd abfd,
asymbol symbol,
arelent reloc_entry,
asection input_section,
bfd_boolean  relocatable,
void *  data,
bfd_vma  gp 
)

Definition at line 1310 of file elfxx-mips.c.

{
  bfd_vma relocation;
  bfd_signed_vma val;
  bfd_reloc_status_type status;

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

  relocation += symbol->section->output_section->vma;
  relocation += symbol->section->output_offset;

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

  /* Set val to the offset into the section or symbol.  */
  val = reloc_entry->addend;

  _bfd_mips_elf_sign_extend (val, 16);

  /* Adjust val for the final section location and GP value.  If we
     are producing relocatable output, we don't want to do this for
     an external symbol.  */
  if (! relocatable
      || (symbol->flags & BSF_SECTION_SYM) != 0)
    val += relocation - gp;

  if (reloc_entry->howto->partial_inplace)
    {
      status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
                                   (bfd_byte *) data
                                   + reloc_entry->address);
      if (status != bfd_reloc_ok)
       return status;
    }
  else
    reloc_entry->addend = val;

  if (relocatable)
    reloc_entry->address += input_section->output_offset;

  return bfd_reloc_ok;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 1385 of file elfxx-mips.c.

{
  struct mips_hi16 *n;

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

  n = bfd_malloc (sizeof *n);
  if (n == NULL)
    return bfd_reloc_outofrange;

  n->next = mips_hi16_list;
  n->data = data;
  n->input_section = input_section;
  n->rel = *reloc_entry;
  mips_hi16_list = n;

  if (output_bfd != NULL)
    reloc_entry->address += input_section->output_offset;

  return bfd_reloc_ok;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 9675 of file elfxx-mips.c.

{
  bfd *dynobj;
  asection *got;
  struct mips_got_info *g;
  struct mips_elf_link_hash_entry *h;

  h = (struct mips_elf_link_hash_entry *) entry;
  if (h->forced_local)
    return;
  h->forced_local = force_local;

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj != NULL && force_local && h->root.type != STT_TLS
      && (got = mips_elf_got_section (dynobj, TRUE)) != NULL
      && (g = mips_elf_section_data (got)->u.got_info) != NULL)
    {
      if (g->next)
       {
         struct mips_got_entry e;
         struct mips_got_info *gg = g;

         /* Since we're turning what used to be a global symbol into a
            local one, bump up the number of local entries of each GOT
            that had an entry for it.  This will automatically decrease
            the number of global entries, since global_gotno is actually
            the upper limit of global entries.  */
         e.abfd = dynobj;
         e.symndx = -1;
         e.d.h = h;
         e.tls_type = 0;

         for (g = g->next; g != gg; g = g->next)
           if (htab_find (g->got_entries, &e))
             {
              BFD_ASSERT (g->global_gotno > 0);
              g->local_gotno++;
              g->global_gotno--;
             }

         /* If this was a global symbol forced into the primary GOT, we
            no longer need an entry for it.  We can't release the entry
            at this point, but we must at least stop counting it as one
            of the symbols that required a forced got entry.  */
         if (h->root.got.offset == 2)
           {
             BFD_ASSERT (gg->assigned_gotno > 0);
             gg->assigned_gotno--;
           }
       }
      else if (g->global_gotno == 0 && g->global_gotsym == NULL)
       /* If we haven't got through GOT allocation yet, just bump up the
          number of local entries, as this symbol won't be counted as
          global.  */
       g->local_gotno++;
      else if (h->root.got.offset == 1)
       {
         /* If we're past non-multi-GOT allocation and this symbol had
            been marked for a global got entry, give it a local entry
            instead.  */
         BFD_ASSERT (g->global_gotno > 0);
         g->local_gotno++;
         g->global_gotno--;
       }
    }

  _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 9808 of file elfxx-mips.c.

{
  if (strcmp (sec->name, ".pdr") == 0)
    return TRUE;
  return FALSE;
}

Here is the call graph for this function:

Definition at line 11338 of file elfxx-mips.c.

{
  return ELF_MIPS_IS_OPTIONAL (h->other) ? TRUE : FALSE;
}

Definition at line 10174 of file elfxx-mips.c.

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

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

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

#if 0
  /* We no longer use this.  */
  for (i = 0; i < SIZEOF_MIPS_DYNSYM_SECNAMES; i++)
    ret->dynsym_sec_strindex[i] = (bfd_size_type) -1;
#endif
  ret->procedure_count = 0;
  ret->compact_rel_size = 0;
  ret->use_rld_obj_head = FALSE;
  ret->rld_value = 0;
  ret->mips16_stubs_seen = FALSE;
  ret->is_vxworks = FALSE;
  ret->srelbss = NULL;
  ret->sdynbss = NULL;
  ret->srelplt = NULL;
  ret->srelplt2 = NULL;
  ret->sgotplt = NULL;
  ret->splt = NULL;
  ret->plt_header_size = 0;
  ret->plt_entry_size = 0;
  ret->function_stub_size = 0;

  return &ret->root.root;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_mips_elf_link_output_symbol_hook ( struct bfd_link_info *info  ATTRIBUTE_UNUSED,
const char *name  ATTRIBUTE_UNUSED,
Elf_Internal_Sym *  sym,
asection input_sec,
struct elf_link_hash_entry *h  ATTRIBUTE_UNUSED 
)

Definition at line 5903 of file elfxx-mips.c.

{
  /* If we see a common symbol, which implies a relocatable link, then
     if a symbol was small common in an input file, mark it as small
     common in the output file.  */
  if (sym->st_shndx == SHN_COMMON
      && strcmp (input_sec->name, ".scommon") == 0)
    sym->st_shndx = SHN_MIPS_SCOMMON;

  if (sym->st_other == STO_MIPS16)
    sym->st_value &= ~1;

  return TRUE;
}

Here is the call graph for this function:

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

Definition at line 1437 of file elfxx-mips.c.

{
  bfd_vma vallo;
  bfd_byte *location = (bfd_byte *) data + reloc_entry->address;

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

  _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
                               location);
  vallo = bfd_get_32 (abfd, location);
  _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE,
                             location);

  while (mips_hi16_list != NULL)
    {
      bfd_reloc_status_type ret;
      struct mips_hi16 *hi;

      hi = mips_hi16_list;

      /* R_MIPS_GOT16 relocations are something of a special case.  We
        want to install the addend in the same way as for a R_MIPS_HI16
        relocation (with a rightshift of 16).  However, since GOT16
        relocations can also be used with global symbols, their howto
        has a rightshift of 0.  */
      if (hi->rel.howto->type == R_MIPS_GOT16)
       hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE);

      /* VALLO is a signed 16-bit number.  Bias it by 0x8000 so that any
        carry or borrow will induce a change of +1 or -1 in the high part.  */
      hi->rel.addend += (vallo + 0x8000) & 0xffff;

      ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
                                    hi->input_section, output_bfd,
                                    error_message);
      if (ret != bfd_reloc_ok)
       return ret;

      mips_hi16_list = hi->next;
      free (hi);
    }

  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
                                  input_section, output_bfd,
                                  error_message);
}

Here is the call graph for this function:

Definition at line 10996 of file elfxx-mips.c.

{
  flagword old_flags;
  flagword new_flags;
  bfd_boolean ok;
  bfd_boolean null_input_bfd = TRUE;
  asection *sec;

  /* Check if we have the same endianess */
  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
    {
      (*_bfd_error_handler)
       (_("%B: endianness incompatible with that of the selected emulation"),
        ibfd);
      return FALSE;
    }

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

  if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
    {
      (*_bfd_error_handler)
       (_("%B: ABI is incompatible with that of the selected emulation"),
        ibfd);
      return FALSE;
    }

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

  if (! elf_flags_init (obfd))
    {
      elf_flags_init (obfd) = TRUE;
      elf_elfheader (obfd)->e_flags = new_flags;
      elf_elfheader (obfd)->e_ident[EI_CLASS]
       = elf_elfheader (ibfd)->e_ident[EI_CLASS];

      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
         && (bfd_get_arch_info (obfd)->the_default
             || mips_mach_extends_p (bfd_get_mach (obfd), 
                                  bfd_get_mach (ibfd))))
       {
         if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
                               bfd_get_mach (ibfd)))
           return FALSE;
       }

      return TRUE;
    }

  /* Check flag compatibility.  */

  new_flags &= ~EF_MIPS_NOREORDER;
  old_flags &= ~EF_MIPS_NOREORDER;

  /* Some IRIX 6 BSD-compatibility objects have this bit set.  It
     doesn't seem to matter.  */
  new_flags &= ~EF_MIPS_XGOT;
  old_flags &= ~EF_MIPS_XGOT;

  /* MIPSpro generates ucode info in n64 objects.  Again, we should
     just be able to ignore this.  */
  new_flags &= ~EF_MIPS_UCODE;
  old_flags &= ~EF_MIPS_UCODE;

  /* Don't care about the PIC flags from dynamic objects; they are
     PIC by design.  */
  if ((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0
      && (ibfd->flags & DYNAMIC) != 0)
    new_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC);

  if (new_flags == old_flags)
    return TRUE;

  /* Check to see if the input BFD actually contains any sections.
     If not, its flags may not have been initialised either, but it cannot
     actually cause any incompatibility.  */
  for (sec = ibfd->sections; sec != NULL; sec = sec->next)
    {
      /* Ignore synthetic sections and empty .text, .data and .bss sections
         which are automatically generated by gas.  */
      if (strcmp (sec->name, ".reginfo")
         && strcmp (sec->name, ".mdebug")
         && (sec->size != 0
             || (strcmp (sec->name, ".text")
                && strcmp (sec->name, ".data")
                && strcmp (sec->name, ".bss"))))
       {
         null_input_bfd = FALSE;
         break;
       }
    }
  if (null_input_bfd)
    return TRUE;

  ok = TRUE;

  if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)
      != ((old_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0))
    {
      (*_bfd_error_handler)
       (_("%B: warning: linking PIC files with non-PIC files"),
        ibfd);
      ok = TRUE;
    }

  if (new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC))
    elf_elfheader (obfd)->e_flags |= EF_MIPS_CPIC;
  if (! (new_flags & EF_MIPS_PIC))
    elf_elfheader (obfd)->e_flags &= ~EF_MIPS_PIC;

  new_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC);
  old_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC);

  /* Compare the ISAs.  */
  if (mips_32bit_flags_p (old_flags) != mips_32bit_flags_p (new_flags))
    {
      (*_bfd_error_handler)
       (_("%B: linking 32-bit code with 64-bit code"),
        ibfd);
      ok = FALSE;
    }
  else if (!mips_mach_extends_p (bfd_get_mach (ibfd), bfd_get_mach (obfd)))
    {
      /* OBFD's ISA isn't the same as, or an extension of, IBFD's.  */
      if (mips_mach_extends_p (bfd_get_mach (obfd), bfd_get_mach (ibfd)))
       {
         /* Copy the architecture info from IBFD to OBFD.  Also copy
            the 32-bit flag (if set) so that we continue to recognise
            OBFD as a 32-bit binary.  */
         bfd_set_arch_info (obfd, bfd_get_arch_info (ibfd));
         elf_elfheader (obfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
         elf_elfheader (obfd)->e_flags
           |= new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);

         /* Copy across the ABI flags if OBFD doesn't use them
            and if that was what caused us to treat IBFD as 32-bit.  */
         if ((old_flags & EF_MIPS_ABI) == 0
             && mips_32bit_flags_p (new_flags)
             && !mips_32bit_flags_p (new_flags & ~EF_MIPS_ABI))
           elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ABI;
       }
      else
       {
         /* The ISAs aren't compatible.  */
         (*_bfd_error_handler)
           (_("%B: linking %s module with previous %s modules"),
            ibfd,
            bfd_printable_name (ibfd),
            bfd_printable_name (obfd));
         ok = FALSE;
       }
    }

  new_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
  old_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);

  /* Compare ABIs.  The 64-bit ABI does not use EF_MIPS_ABI.  But, it
     does set EI_CLASS differently from any 32-bit ABI.  */
  if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI)
      || (elf_elfheader (ibfd)->e_ident[EI_CLASS]
         != elf_elfheader (obfd)->e_ident[EI_CLASS]))
    {
      /* Only error if both are set (to different values).  */
      if (((new_flags & EF_MIPS_ABI) && (old_flags & EF_MIPS_ABI))
         || (elf_elfheader (ibfd)->e_ident[EI_CLASS]
             != elf_elfheader (obfd)->e_ident[EI_CLASS]))
       {
         (*_bfd_error_handler)
           (_("%B: ABI mismatch: linking %s module with previous %s modules"),
            ibfd,
            elf_mips_abi_name (ibfd),
            elf_mips_abi_name (obfd));
         ok = FALSE;
       }
      new_flags &= ~EF_MIPS_ABI;
      old_flags &= ~EF_MIPS_ABI;
    }

  /* For now, allow arbitrary mixing of ASEs (retain the union).  */
  if ((new_flags & EF_MIPS_ARCH_ASE) != (old_flags & EF_MIPS_ARCH_ASE))
    {
      elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ARCH_ASE;

      new_flags &= ~ EF_MIPS_ARCH_ASE;
      old_flags &= ~ EF_MIPS_ARCH_ASE;
    }

  /* Warn about any other mismatches */
  if (new_flags != old_flags)
    {
      (*_bfd_error_handler)
       (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
        ibfd, (unsigned long) new_flags,
        (unsigned long) old_flags);
      ok = FALSE;
    }

  if (! ok)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:

void _bfd_mips_elf_merge_symbol_attribute ( struct elf_link_hash_entry h,
const Elf_Internal_Sym *  isym,
bfd_boolean  definition,
bfd_boolean dynamic  ATTRIBUTE_UNUSED 
)

Definition at line 11316 of file elfxx-mips.c.

{
  if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
    {
      unsigned char other;

      other = (definition ? isym->st_other : h->other);
      other &= ~ELF_ST_VISIBILITY (-1);
      h->other = other | ELF_ST_VISIBILITY (h->other);
    }

  if (!definition
      && ELF_MIPS_IS_OPTIONAL (isym->st_other))
    h->other |= STO_OPTIONAL;
}

Definition at line 9329 of file elfxx-mips.c.

{
  asection *s;
  struct elf_segment_map *m, **pm;
  bfd_size_type amt;

  /* If there is a .reginfo section, we need a PT_MIPS_REGINFO
     segment.  */
  s = bfd_get_section_by_name (abfd, ".reginfo");
  if (s != NULL && (s->flags & SEC_LOAD) != 0)
    {
      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
       if (m->p_type == PT_MIPS_REGINFO)
         break;
      if (m == NULL)
       {
         amt = sizeof *m;
         m = bfd_zalloc (abfd, amt);
         if (m == NULL)
           return FALSE;

         m->p_type = PT_MIPS_REGINFO;
         m->count = 1;
         m->sections[0] = s;

         /* We want to put it after the PHDR and INTERP segments.  */
         pm = &elf_tdata (abfd)->segment_map;
         while (*pm != NULL
               && ((*pm)->p_type == PT_PHDR
                   || (*pm)->p_type == PT_INTERP))
           pm = &(*pm)->next;

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

  /* For IRIX 6, we don't have .mdebug sections, nor does anything but
     .dynamic end up in PT_DYNAMIC.  However, we do have to insert a
     PT_MIPS_OPTIONS segment immediately following the program header
     table.  */
  if (NEWABI_P (abfd)
      /* On non-IRIX6 new abi, we'll have already created a segment
        for this section, so don't create another.  I'm not sure this
        is not also the case for IRIX 6, but I can't test it right
        now.  */
      && IRIX_COMPAT (abfd) == ict_irix6)
    {
      for (s = abfd->sections; s; s = s->next)
       if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
         break;

      if (s)
       {
         struct elf_segment_map *options_segment;

         pm = &elf_tdata (abfd)->segment_map;
         while (*pm != NULL
               && ((*pm)->p_type == PT_PHDR
                   || (*pm)->p_type == PT_INTERP))
           pm = &(*pm)->next;

         if (*pm == NULL || (*pm)->p_type != PT_MIPS_OPTIONS)
           {
             amt = sizeof (struct elf_segment_map);
             options_segment = bfd_zalloc (abfd, amt);
             options_segment->next = *pm;
             options_segment->p_type = PT_MIPS_OPTIONS;
             options_segment->p_flags = PF_R;
             options_segment->p_flags_valid = TRUE;
             options_segment->count = 1;
             options_segment->sections[0] = s;
             *pm = options_segment;
           }
       }
    }
  else
    {
      if (IRIX_COMPAT (abfd) == ict_irix5)
       {
         /* If there are .dynamic and .mdebug sections, we make a room
            for the RTPROC header.  FIXME: Rewrite without section names.  */
         if (bfd_get_section_by_name (abfd, ".interp") == NULL
             && bfd_get_section_by_name (abfd, ".dynamic") != NULL
             && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
           {
             for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
              if (m->p_type == PT_MIPS_RTPROC)
                break;
             if (m == NULL)
              {
                amt = sizeof *m;
                m = bfd_zalloc (abfd, amt);
                if (m == NULL)
                  return FALSE;

                m->p_type = PT_MIPS_RTPROC;

                s = bfd_get_section_by_name (abfd, ".rtproc");
                if (s == NULL)
                  {
                    m->count = 0;
                    m->p_flags = 0;
                    m->p_flags_valid = 1;
                  }
                else
                  {
                    m->count = 1;
                    m->sections[0] = s;
                  }

                /* We want to put it after the DYNAMIC segment.  */
                pm = &elf_tdata (abfd)->segment_map;
                while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
                  pm = &(*pm)->next;
                if (*pm != NULL)
                  pm = &(*pm)->next;

                m->next = *pm;
                *pm = m;
              }
           }
       }
      /* On IRIX5, the PT_DYNAMIC segment includes the .dynamic,
        .dynstr, .dynsym, and .hash sections, and everything in
        between.  */
      for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL;
          pm = &(*pm)->next)
       if ((*pm)->p_type == PT_DYNAMIC)
         break;
      m = *pm;
      if (m != NULL && IRIX_COMPAT (abfd) == ict_none)
       {
         /* For a normal mips executable the permissions for the PT_DYNAMIC
            segment are read, write and execute. We do that here since
            the code in elf.c sets only the read permission. This matters
            sometimes for the dynamic linker.  */
         if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
           {
             m->p_flags = PF_R | PF_W | PF_X;
             m->p_flags_valid = 1;
           }
       }
      /* GNU/Linux binaries do not need the extended PT_DYNAMIC section.
        glibc's dynamic linker has traditionally derived the number of
        tags from the p_filesz field, and sometimes allocates stack
        arrays of that size.  An overly-big PT_DYNAMIC segment can
        be actively harmful in such cases.  Making PT_DYNAMIC contain
        other sections can also make life hard for the prelinker,
        which might move one of the other sections to a different
        PT_LOAD segment.  */
      if (SGI_COMPAT (abfd)
         && m != NULL
         && m->count == 1
         && strcmp (m->sections[0]->name, ".dynamic") == 0)
       {
         static const char *sec_names[] =
         {
           ".dynamic", ".dynstr", ".dynsym", ".hash"
         };
         bfd_vma low, high;
         unsigned int i, c;
         struct elf_segment_map *n;

         low = ~(bfd_vma) 0;
         high = 0;
         for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++)
           {
             s = bfd_get_section_by_name (abfd, sec_names[i]);
             if (s != NULL && (s->flags & SEC_LOAD) != 0)
              {
                bfd_size_type sz;

                if (low > s->vma)
                  low = s->vma;
                sz = s->size;
                if (high < s->vma + sz)
                  high = s->vma + sz;
              }
           }

         c = 0;
         for (s = abfd->sections; s != NULL; s = s->next)
           if ((s->flags & SEC_LOAD) != 0
              && s->vma >= low
              && s->vma + s->size <= high)
             ++c;

         amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *);
         n = bfd_zalloc (abfd, amt);
         if (n == NULL)
           return FALSE;
         *n = *m;
         n->count = c;

         i = 0;
         for (s = abfd->sections; s != NULL; s = s->next)
           {
             if ((s->flags & SEC_LOAD) != 0
                && s->vma >= low
                && s->vma + s->size <= high)
              {
                n->sections[i] = s;
                ++i;
              }
           }

         *pm = n;
       }
    }

  /* Allocate a spare program header in dynamic objects so that tools
     like the prelinker can add an extra PT_LOAD entry.

     If the prelinker needs to make room for a new PT_LOAD entry, its
     standard procedure is to move the first (read-only) sections into
     the new (writable) segment.  However, the MIPS ABI requires
     .dynamic to be in a read-only segment, and the section will often
     start within sizeof (ElfNN_Phdr) bytes of the last program header.

     Although the prelinker could in principle move .dynamic to a
     writable segment, it seems better to allocate a spare program
     header instead, and avoid the need to move any sections.
     There is a long tradition of allocating spare dynamic tags,
     so allocating a spare program header seems like a natural
     extension.  */
  if (!SGI_COMPAT (abfd)
      && bfd_get_section_by_name (abfd, ".dynamic"))
    {
      for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
       if ((*pm)->p_type == PT_NULL)
         break;
      if (*pm == NULL)
       {
         m = bfd_zalloc (abfd, sizeof (*m));
         if (m == NULL)
           return FALSE;

         m->p_type = PT_NULL;
         *pm = m;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 5269 of file elfxx-mips.c.

{
  return SGI_COMPAT (abfd);
}

Definition at line 843 of file elfxx-mips.c.

{
  if (!sec->used_by_bfd)
    {
      struct _mips_elf_section_data *sdata;
      bfd_size_type amt = sizeof (*sdata);

      sdata = bfd_zalloc (abfd, amt);
      if (sdata == NULL)
       return FALSE;
      sec->used_by_bfd = sdata;
    }

  return _bfd_elf_new_section_hook (abfd, sec);
}

Here is the call graph for this function:

Definition at line 11220 of file elfxx-mips.c.

{
  FILE *file = ptr;

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

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

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

  if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_O32)
    fprintf (file, _(" [abi=O32]"));
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_O64)
    fprintf (file, _(" [abi=O64]"));
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32)
    fprintf (file, _(" [abi=EABI32]"));
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64)
    fprintf (file, _(" [abi=EABI64]"));
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI))
    fprintf (file, _(" [abi unknown]"));
  else if (ABI_N32_P (abfd))
    fprintf (file, _(" [abi=N32]"));
  else if (ABI_64_P (abfd))
    fprintf (file, _(" [abi=64]"));
  else
    fprintf (file, _(" [no abi set]"));

  if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
    fprintf (file, " [mips1]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
    fprintf (file, " [mips2]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
    fprintf (file, " [mips3]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
    fprintf (file, " [mips4]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_5)
    fprintf (file, " [mips5]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32)
    fprintf (file, " [mips32]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64)
    fprintf (file, " [mips64]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2)
    fprintf (file, " [mips32r2]");
  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R2)
    fprintf (file, " [mips64r2]");
  else
    fprintf (file, _(" [unknown ISA]"));

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MDMX)
    fprintf (file, " [mdmx]");

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_M16)
    fprintf (file, " [mips16]");

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_32BITMODE)
    fprintf (file, " [32bitmode]");
  else
    fprintf (file, _(" [not 32bitmode]"));

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_NOREORDER)
    fprintf (file, " [noreorder]");

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_PIC)
    fprintf (file, " [PIC]");

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_CPIC)
    fprintf (file, " [CPIC]");

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_XGOT)
    fprintf (file, " [XGOT]");

  if (elf_elfheader (abfd)->e_flags & EF_MIPS_UCODE)
    fprintf (file, " [UCODE]");

  fputc ('\n', file);

  return TRUE;
}

Here is the call graph for this function:

Definition at line 863 of file elfxx-mips.c.

{
  HDRR *symhdr;
  const struct ecoff_debug_swap *swap;
  char *ext_hdr;

  swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
  memset (debug, 0, sizeof (*debug));

  ext_hdr = bfd_malloc (swap->external_hdr_size);
  if (ext_hdr == NULL && swap->external_hdr_size != 0)
    goto error_return;

  if (! bfd_get_section_contents (abfd, section, ext_hdr, 0,
                              swap->external_hdr_size))
    goto error_return;

  symhdr = &debug->symbolic_header;
  (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);

  /* The symbolic header contains absolute file offsets and sizes to
     read.  */
#define READ(ptr, offset, count, size, type)                          \
  if (symhdr->count == 0)                                      \
    debug->ptr = NULL;                                                \
  else                                                         \
    {                                                          \
      bfd_size_type amt = (bfd_size_type) size * symhdr->count;              \
      debug->ptr = bfd_malloc (amt);                                  \
      if (debug->ptr == NULL)                                         \
       goto error_return;                                      \
      if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0              \
         || bfd_bread (debug->ptr, amt, abfd) != amt)                 \
       goto error_return;                                      \
    }

  READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
  READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
       union aux_ext *);
  READ (ss, cbSsOffset, issMax, sizeof (char), char *);
  READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *);
  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *);
#undef READ

  debug->fdr = NULL;

  return TRUE;

 error_return:
  if (ext_hdr != NULL)
    free (ext_hdr);
  if (debug->line != NULL)
    free (debug->line);
  if (debug->external_dnr != NULL)
    free (debug->external_dnr);
  if (debug->external_pdr != NULL)
    free (debug->external_pdr);
  if (debug->external_sym != NULL)
    free (debug->external_sym);
  if (debug->external_opt != NULL)
    free (debug->external_opt);
  if (debug->external_aux != NULL)
    free (debug->external_aux);
  if (debug->ss != NULL)
    free (debug->ss);
  if (debug->ssext != NULL)
    free (debug->ssext);
  if (debug->external_fdr != NULL)
    free (debug->external_fdr);
  if (debug->external_rfd != NULL)
    free (debug->external_rfd);
  if (debug->external_ext != NULL)
    free (debug->external_ext);
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean _bfd_mips_elf_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 
)

Definition at line 7731 of file elfxx-mips.c.

{
  Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *relend;
  bfd_vma addend = 0;
  bfd_boolean use_saved_addend_p = FALSE;
  const struct elf_backend_data *bed;

  bed = get_elf_backend_data (output_bfd);
  relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
  for (rel = relocs; rel < relend; ++rel)
    {
      const char *name;
      bfd_vma value = 0;
      reloc_howto_type *howto;
      bfd_boolean require_jalx;
      /* TRUE if the relocation is a RELA relocation, rather than a
         REL relocation.  */
      bfd_boolean rela_relocation_p = TRUE;
      unsigned int r_type = ELF_R_TYPE (output_bfd, rel->r_info);
      const char *msg;
      unsigned long r_symndx;
      asection *sec;
      Elf_Internal_Shdr *symtab_hdr;
      struct elf_link_hash_entry *h;

      /* Find the relocation howto for this relocation.  */
      howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type,
                                   NEWABI_P (input_bfd)
                                   && (MIPS_RELOC_RELA_P
                                      (input_bfd, input_section,
                                       rel - relocs)));

      r_symndx = ELF_R_SYM (input_bfd, rel->r_info);
      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
      if (mips_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE))
       {
         sec = local_sections[r_symndx];
         h = NULL;
       }
      else
       {
         unsigned long extsymoff;

         extsymoff = 0;
         if (!elf_bad_symtab (input_bfd))
           extsymoff = symtab_hdr->sh_info;
         h = elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
         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;

         sec = NULL;
         if (h->root.type == bfd_link_hash_defined
             || h->root.type == bfd_link_hash_defweak)
           sec = h->root.u.def.section;
       }

      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 (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd))
       {
         /* Some 32-bit code uses R_MIPS_64.  In particular, people use
            64-bit code, but make sure all their addresses are in the
            lowermost or uppermost 32-bit section of the 64-bit address
            space.  Thus, when they use an R_MIPS_64 they mean what is
            usually meant by R_MIPS_32, with the exception that the
            stored value is sign-extended to 64 bits.  */
         howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, R_MIPS_32, FALSE);

         /* On big-endian systems, we need to lie about the position
            of the reloc.  */
         if (bfd_big_endian (input_bfd))
           rel->r_offset += 4;
       }

      if (!use_saved_addend_p)
       {
         Elf_Internal_Shdr *rel_hdr;

         /* If these relocations were originally of the REL variety,
            we must pull the addend out of the field that will be
            relocated.  Otherwise, we simply use the contents of the
            RELA relocation.  To determine which flavor or relocation
            this is, we depend on the fact that the INPUT_SECTION's
            REL_HDR is read before its REL_HDR2.  */
         rel_hdr = &elf_section_data (input_section)->rel_hdr;
         if ((size_t) (rel - relocs)
             >= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
           rel_hdr = elf_section_data (input_section)->rel_hdr2;
         if (rel_hdr->sh_entsize == MIPS_ELF_REL_SIZE (input_bfd))
           {
             bfd_byte *location = contents + rel->r_offset;

             /* Note that this is a REL relocation.  */
             rela_relocation_p = FALSE;

             /* Get the addend, which is stored in the input file.  */
             _bfd_mips16_elf_reloc_unshuffle (input_bfd, r_type, FALSE,
                                          location);
             addend = mips_elf_obtain_contents (howto, rel, input_bfd,
                                           contents);
             _bfd_mips16_elf_reloc_shuffle(input_bfd, r_type, FALSE,
                                       location);

             addend &= howto->src_mask;

             /* For some kinds of relocations, the ADDEND is a
               combination of the addend stored in two different
               relocations.   */
             if (r_type == R_MIPS_HI16 || r_type == R_MIPS16_HI16
                || (r_type == R_MIPS_GOT16
                    && mips_elf_local_relocation_p (input_bfd, rel,
                                                local_sections, FALSE)))
              {
                const Elf_Internal_Rela *lo16_relocation;
                reloc_howto_type *lo16_howto;
                int lo16_type;

                if (r_type == R_MIPS16_HI16)
                  lo16_type = R_MIPS16_LO16;
                else
                  lo16_type = R_MIPS_LO16;

                /* The combined value is the sum of the HI16 addend,
                   left-shifted by sixteen bits, and the LO16
                   addend, sign extended.  (Usually, the code does
                   a `lui' of the HI16 value, and then an `addiu' of
                   the LO16 value.)

                   Scan ahead to find a matching LO16 relocation.

                   According to the MIPS ELF ABI, the R_MIPS_LO16
                   relocation must be immediately following.
                   However, for the IRIX6 ABI, the next relocation
                   may be a composed relocation consisting of
                   several relocations for the same address.  In
                   that case, the R_MIPS_LO16 relocation may occur
                   as one of these.  We permit a similar extension
                   in general, as that is useful for GCC.

                   In some cases GCC dead code elimination removes
                   the LO16 but keeps the corresponding HI16.  This
                   is strictly speaking a violation of the ABI but
                   not immediately harmful.  */
                lo16_relocation = mips_elf_next_relocation (input_bfd,
                                                       lo16_type,
                                                       rel, relend);
                if (lo16_relocation == NULL)
                  {
                    const char *name;

                    if (h)
                     name = h->root.root.string;
                    else
                     name = bfd_elf_sym_name (input_bfd, symtab_hdr,
                                           local_syms + r_symndx,
                                           sec);
                    (*_bfd_error_handler)
                     (_("%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"),
                      input_bfd, input_section, name, howto->name,
                      rel->r_offset);
                  }
                else
                  {
                    bfd_byte *lo16_location;
                    bfd_vma l;

                    lo16_location = contents + lo16_relocation->r_offset;

                    /* Obtain the addend kept there.  */
                    lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd,
                                                     lo16_type, FALSE);
                    _bfd_mips16_elf_reloc_unshuffle (input_bfd, lo16_type,
                                                 FALSE, lo16_location);
                    l = mips_elf_obtain_contents (lo16_howto,
                                              lo16_relocation,
                                              input_bfd, contents);
                    _bfd_mips16_elf_reloc_shuffle (input_bfd, lo16_type,
                                               FALSE, lo16_location);
                    l &= lo16_howto->src_mask;
                    l <<= lo16_howto->rightshift;
                    l = _bfd_mips_elf_sign_extend (l, 16);

                    addend <<= 16;

                    /* Compute the combined addend.  */
                    addend += l;
                  }
              }
             else
              addend <<= howto->rightshift;
           }
         else
           addend = rel->r_addend;
         mips_elf_adjust_addend (output_bfd, info, input_bfd,
                              local_syms, local_sections, rel);
       }

      if (info->relocatable)
       {
         if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)
             && bfd_big_endian (input_bfd))
           rel->r_offset -= 4;

         if (!rela_relocation_p && rel->r_addend)
           {
             addend += rel->r_addend;
             if (r_type == R_MIPS_HI16
                || r_type == R_MIPS_GOT16)
              addend = mips_elf_high (addend);
             else if (r_type == R_MIPS_HIGHER)
              addend = mips_elf_higher (addend);
             else if (r_type == R_MIPS_HIGHEST)
              addend = mips_elf_highest (addend);
             else
              addend >>= howto->rightshift;

             /* We use the source mask, rather than the destination
               mask because the place to which we are writing will be
               source of the addend in the final link.  */
             addend &= howto->src_mask;

             if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
              /* See the comment above about using R_MIPS_64 in the 32-bit
                 ABI.  Here, we need to update the addend.  It would be
                 possible to get away with just using the R_MIPS_32 reloc
                 but for endianness.  */
              {
                bfd_vma sign_bits;
                bfd_vma low_bits;
                bfd_vma high_bits;

                if (addend & ((bfd_vma) 1 << 31))
#ifdef BFD64
                  sign_bits = ((bfd_vma) 1 << 32) - 1;
#else
                  sign_bits = -1;
#endif
                else
                  sign_bits = 0;

                /* If we don't know that we have a 64-bit type,
                   do two separate stores.  */
                if (bfd_big_endian (input_bfd))
                  {
                    /* Store the sign-bits (which are most significant)
                      first.  */
                    low_bits = sign_bits;
                    high_bits = addend;
                  }
                else
                  {
                    low_bits = addend;
                    high_bits = sign_bits;
                  }
                bfd_put_32 (input_bfd, low_bits,
                           contents + rel->r_offset);
                bfd_put_32 (input_bfd, high_bits,
                           contents + rel->r_offset + 4);
                continue;
              }

             if (! mips_elf_perform_relocation (info, howto, rel, addend,
                                           input_bfd, input_section,
                                           contents, FALSE))
              return FALSE;
           }

         /* Go on to the next relocation.  */
         continue;
       }

      /* In the N32 and 64-bit ABIs there may be multiple consecutive
        relocations for the same offset.  In that case we are
        supposed to treat the output of each relocation as the addend
        for the next.  */
      if (rel + 1 < relend
         && rel->r_offset == rel[1].r_offset
         && ELF_R_TYPE (input_bfd, rel[1].r_info) != R_MIPS_NONE)
       use_saved_addend_p = TRUE;
      else
       use_saved_addend_p = FALSE;

      /* Figure out what value we are supposed to relocate.  */
      switch (mips_elf_calculate_relocation (output_bfd, input_bfd,
                                        input_section, info, rel,
                                        addend, howto, local_syms,
                                        local_sections, &value,
                                        &name, &require_jalx,
                                        use_saved_addend_p))
       {
       case bfd_reloc_continue:
         /* There's nothing to do.  */
         continue;

       case bfd_reloc_undefined:
         /* mips_elf_calculate_relocation already called the
            undefined_symbol callback.  There's no real point in
            trying to perform the relocation at this point, so we
            just skip ahead to the next relocation.  */
         continue;

       case bfd_reloc_notsupported:
         msg = _("internal error: unsupported relocation error");
         info->callbacks->warning
           (info, msg, name, input_bfd, input_section, rel->r_offset);
         return FALSE;

       case bfd_reloc_overflow:
         if (use_saved_addend_p)
           /* Ignore overflow until we reach the last relocation for
              a given location.  */
           ;
         else
           {
             BFD_ASSERT (name != NULL);
             if (! ((*info->callbacks->reloc_overflow)
                   (info, NULL, name, howto->name, (bfd_vma) 0,
                    input_bfd, input_section, rel->r_offset)))
              return FALSE;
           }
         break;

       case bfd_reloc_ok:
         break;

       default:
         abort ();
         break;
       }

      /* If we've got another relocation for the address, keep going
        until we reach the last one.  */
      if (use_saved_addend_p)
       {
         addend = value;
         continue;
       }

      if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
       /* See the comment above about using R_MIPS_64 in the 32-bit
          ABI.  Until now, we've been using the HOWTO for R_MIPS_32;
          that calculated the right value.  Now, however, we
          sign-extend the 32-bit result to 64-bits, and store it as a
          64-bit value.  We are especially generous here in that we
          go to extreme lengths to support this usage on systems with
          only a 32-bit VMA.  */
       {
         bfd_vma sign_bits;
         bfd_vma low_bits;
         bfd_vma high_bits;

         if (value & ((bfd_vma) 1 << 31))
#ifdef BFD64
           sign_bits = ((bfd_vma) 1 << 32) - 1;
#else
           sign_bits = -1;
#endif
         else
           sign_bits = 0;

         /* If we don't know that we have a 64-bit type,
            do two separate stores.  */
         if (bfd_big_endian (input_bfd))
           {
             /* Undo what we did above.  */
             rel->r_offset -= 4;
             /* Store the sign-bits (which are most significant)
               first.  */
             low_bits = sign_bits;
             high_bits = value;
           }
         else
           {
             low_bits = value;
             high_bits = sign_bits;
           }
         bfd_put_32 (input_bfd, low_bits,
                    contents + rel->r_offset);
         bfd_put_32 (input_bfd, high_bits,
                    contents + rel->r_offset + 4);
         continue;
       }

      /* Actually perform the relocation.  */
      if (! mips_elf_perform_relocation (info, howto, rel, value,
                                    input_bfd, input_section,
                                    contents, require_jalx))
       return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:

bfd_boolean _bfd_mips_elf_section_from_bfd_section ( bfd *abfd  ATTRIBUTE_UNUSED,
asection sec,
int retval 
)

Definition at line 5713 of file elfxx-mips.c.

{
  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
    {
      *retval = SHN_MIPS_SCOMMON;
      return TRUE;
    }
  if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0)
    {
      *retval = SHN_MIPS_ACOMMON;
      return TRUE;
    }
  return FALSE;
}

Here is the call graph for this function:

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

Definition at line 5413 of file elfxx-mips.c.

{
  flagword flags = 0;

  /* There ought to be a place to keep ELF backend specific flags, but
     at the moment there isn't one.  We just keep track of the
     sections by their name, instead.  Fortunately, the ABI gives
     suggested names for all the MIPS specific sections, so we will
     probably get away with this.  */
  switch (hdr->sh_type)
    {
    case SHT_MIPS_LIBLIST:
      if (strcmp (name, ".liblist") != 0)
       return FALSE;
      break;
    case SHT_MIPS_MSYM:
      if (strcmp (name, ".msym") != 0)
       return FALSE;
      break;
    case SHT_MIPS_CONFLICT:
      if (strcmp (name, ".conflict") != 0)
       return FALSE;
      break;
    case SHT_MIPS_GPTAB:
      if (! CONST_STRNEQ (name, ".gptab."))
       return FALSE;
      break;
    case SHT_MIPS_UCODE:
      if (strcmp (name, ".ucode") != 0)
       return FALSE;
      break;
    case SHT_MIPS_DEBUG:
      if (strcmp (name, ".mdebug") != 0)
       return FALSE;
      flags = SEC_DEBUGGING;
      break;
    case SHT_MIPS_REGINFO:
      if (strcmp (name, ".reginfo") != 0
         || hdr->sh_size != sizeof (Elf32_External_RegInfo))
       return FALSE;
      flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE);
      break;
    case SHT_MIPS_IFACE:
      if (strcmp (name, ".MIPS.interfaces") != 0)
       return FALSE;
      break;
    case SHT_MIPS_CONTENT:
      if (! CONST_STRNEQ (name, ".MIPS.content"))
       return FALSE;
      break;
    case SHT_MIPS_OPTIONS:
      if (!MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
       return FALSE;
      break;
    case SHT_MIPS_DWARF:
      if (! CONST_STRNEQ (name, ".debug_"))
       return FALSE;
      break;
    case SHT_MIPS_SYMBOL_LIB:
      if (strcmp (name, ".MIPS.symlib") != 0)
       return FALSE;
      break;
    case SHT_MIPS_EVENTS:
      if (! CONST_STRNEQ (name, ".MIPS.events")
         && ! CONST_STRNEQ (name, ".MIPS.post_rel"))
       return FALSE;
      break;
    default:
      break;
    }

  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
    return FALSE;

  if (flags)
    {
      if (! bfd_set_section_flags (abfd, hdr->bfd_section,
                               (bfd_get_section_flags (abfd,
                                                    hdr->bfd_section)
                                | flags)))
       return FALSE;
    }

  /* FIXME: We should record sh_info for a .gptab section.  */

  /* For a .reginfo section, set the gp value in the tdata information
     from the contents of this section.  We need the gp value while
     processing relocs, so we just get it now.  The .reginfo section
     is not used in the 64-bit MIPS ELF ABI.  */
  if (hdr->sh_type == SHT_MIPS_REGINFO)
    {
      Elf32_External_RegInfo ext;
      Elf32_RegInfo s;

      if (! bfd_get_section_contents (abfd, hdr->bfd_section,
                                  &ext, 0, sizeof ext))
       return FALSE;
      bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
      elf_gp (abfd) = s.ri_gp_value;
    }

  /* For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and
     set the gp value based on what we find.  We may see both
     SHT_MIPS_REGINFO and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case,
     they should agree.  */
  if (hdr->sh_type == SHT_MIPS_OPTIONS)
    {
      bfd_byte *contents, *l, *lend;

      contents = bfd_malloc (hdr->sh_size);
      if (contents == NULL)
       return FALSE;
      if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
                                  0, hdr->sh_size))
       {
         free (contents);
         return FALSE;
       }
      l = contents;
      lend = contents + hdr->sh_size;
      while (l + sizeof (Elf_External_Options) <= lend)
       {
         Elf_Internal_Options intopt;

         bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
                                   &intopt);
         if (intopt.size < sizeof (Elf_External_Options))
           {
             (*_bfd_error_handler)
              (_("%B: Warning: bad `%s' option size %u smaller than its header"),
              abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
             break;
           }
         if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO)
           {
             Elf64_Internal_RegInfo intreg;

             bfd_mips_elf64_swap_reginfo_in
              (abfd,
               ((Elf64_External_RegInfo *)
                (l + sizeof (Elf_External_Options))),
               &intreg);
             elf_gp (abfd) = intreg.ri_gp_value;
           }
         else if (intopt.kind == ODK_REGINFO)
           {
             Elf32_RegInfo intreg;

             bfd_mips_elf32_swap_reginfo_in
              (abfd,
               ((Elf32_External_RegInfo *)
                (l + sizeof (Elf_External_Options))),
               &intreg);
             elf_gp (abfd) = intreg.ri_gp_value;
           }
         l += intopt.size;
       }
      free (contents);
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 5280 of file elfxx-mips.c.

{
  if (hdr->sh_type == SHT_MIPS_REGINFO
      && hdr->sh_size > 0)
    {
      bfd_byte buf[4];

      BFD_ASSERT (hdr->sh_size == sizeof (Elf32_External_RegInfo));
      BFD_ASSERT (hdr->contents == NULL);

      if (bfd_seek (abfd,
                  hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4,
                  SEEK_SET) != 0)
       return FALSE;
      H_PUT_32 (abfd, elf_gp (abfd), buf);
      if (bfd_bwrite (buf, 4, abfd) != 4)
       return FALSE;
    }

  if (hdr->sh_type == SHT_MIPS_OPTIONS
      && hdr->bfd_section != NULL
      && mips_elf_section_data (hdr->bfd_section) != NULL
      && mips_elf_section_data (hdr->bfd_section)->u.tdata != NULL)
    {
      bfd_byte *contents, *l, *lend;

      /* We stored the section contents in the tdata field in the
        set_section_contents routine.  We save the section contents
        so that we don't have to read them again.
        At this point we know that elf_gp is set, so we can look
        through the section contents to see if there is an
        ODK_REGINFO structure.  */

      contents = mips_elf_section_data (hdr->bfd_section)->u.tdata;
      l = contents;
      lend = contents + hdr->sh_size;
      while (l + sizeof (Elf_External_Options) <= lend)
       {
         Elf_Internal_Options intopt;

         bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
                                   &intopt);
         if (intopt.size < sizeof (Elf_External_Options))
           {
             (*_bfd_error_handler)
              (_("%B: Warning: bad `%s' option size %u smaller than its header"),
              abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
             break;
           }
         if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO)
           {
             bfd_byte buf[8];

             if (bfd_seek (abfd,
                         (hdr->sh_offset
                          + (l - contents)
                          + sizeof (Elf_External_Options)
                          + (sizeof (Elf64_External_RegInfo) - 8)),
                          SEEK_SET) != 0)
              return FALSE;
             H_PUT_64 (abfd, elf_gp (abfd), buf);
             if (bfd_bwrite (buf, 8, abfd) != 8)
              return FALSE;
           }
         else if (intopt.kind == ODK_REGINFO)
           {
             bfd_byte buf[4];

             if (bfd_seek (abfd,
                         (hdr->sh_offset
                          + (l - contents)
                          + sizeof (Elf_External_Options)
                          + (sizeof (Elf32_External_RegInfo) - 4)),
                         SEEK_SET) != 0)
              return FALSE;
             H_PUT_32 (abfd, elf_gp (abfd), buf);
             if (bfd_bwrite (buf, 4, abfd) != 4)
              return FALSE;
           }
         l += intopt.size;
       }
    }

  if (hdr->bfd_section != NULL)
    {
      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);

      if (strcmp (name, ".sdata") == 0
         || strcmp (name, ".lit8") == 0
         || strcmp (name, ".lit4") == 0)
       {
         hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
         hdr->sh_type = SHT_PROGBITS;
       }
      else if (strcmp (name, ".sbss") == 0)
       {
         hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
         hdr->sh_type = SHT_NOBITS;
       }
      else if (strcmp (name, ".srdata") == 0)
       {
         hdr->sh_flags |= SHF_ALLOC | SHF_MIPS_GPREL;
         hdr->sh_type = SHT_PROGBITS;
       }
      else if (strcmp (name, ".compact_rel") == 0)
       {
         hdr->sh_flags = 0;
         hdr->sh_type = SHT_PROGBITS;
       }
      else if (strcmp (name, ".rtproc") == 0)
       {
         if (hdr->sh_addralign != 0 && hdr->sh_entsize == 0)
           {
             unsigned int adjust;

             adjust = hdr->sh_size % hdr->sh_addralign;
             if (adjust != 0)
              hdr->sh_size += hdr->sh_addralign - adjust;
           }
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 11209 of file elfxx-mips.c.

{
  BFD_ASSERT (!elf_flags_init (abfd)
             || elf_elfheader (abfd)->e_flags == flags);

  elf_elfheader (abfd)->e_flags = flags;
  elf_flags_init (abfd) = TRUE;
  return TRUE;
}
bfd_boolean _bfd_mips_elf_set_section_contents ( bfd abfd,
sec_ptr  section,
const void *  location,
file_ptr  offset,
bfd_size_type  count 
)

Definition at line 9975 of file elfxx-mips.c.

{
  if (MIPS_ELF_OPTIONS_SECTION_NAME_P (section->name))
    {
      bfd_byte *c;

      if (elf_section_data (section) == NULL)
       {
         bfd_size_type amt = sizeof (struct bfd_elf_section_data);
         section->used_by_bfd = bfd_zalloc (abfd, amt);
         if (elf_section_data (section) == NULL)
           return FALSE;
       }
      c = mips_elf_section_data (section)->u.tdata;
      if (c == NULL)
       {
         c = bfd_zalloc (abfd, section->size);
         if (c == NULL)
           return FALSE;
         mips_elf_section_data (section)->u.tdata = c;
       }

      memcpy (c + offset, location, count);
    }

  return _bfd_elf_set_section_contents (abfd, section, location, offset,
                                   count);
}

Here is the call graph for this function:

Definition at line 3663 of file elfxx-mips.c.

{
  if (value & ((bfd_vma) 1 << (bits - 1)))
    /* VALUE is negative.  */
    value |= ((bfd_vma) - 1) << bits;

  return value;
}

Here is the caller graph for this function:

Definition at line 7347 of file elfxx-mips.c.

{
  bfd *dynobj;
  asection *s, *sreldyn;
  bfd_boolean reltext;
  struct mips_elf_link_hash_table *htab;

  htab = mips_elf_hash_table (info);
  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
           = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
         s->contents
           = (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd);
       }
    }

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

      /* 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);

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

      if (CONST_STRNEQ (name, ".rel"))
       {
         if (s->size != 0)
           {
             const char *outname;
             asection *target;

             /* If this relocation section applies to a read only
                 section, then we probably need a DT_TEXTREL entry.
                 If the relocation section is .rel(a).dyn, we always
                 assert a DT_TEXTREL entry rather than testing whether
                 there exists a relocation to a read only section or
                 not.  */
             outname = bfd_get_section_name (output_bfd,
                                         s->output_section);
             target = bfd_get_section_by_name (output_bfd, outname + 4);
             if ((target != NULL
                 && (target->flags & SEC_READONLY) != 0
                 && (target->flags & SEC_ALLOC) != 0)
                || strcmp (outname, MIPS_ELF_REL_DYN_NAME (info)) == 0)
              reltext = TRUE;

             /* We use the reloc_count field as a counter if we need
               to copy relocs into the output file.  */
             if (strcmp (name, MIPS_ELF_REL_DYN_NAME (info)) != 0)
              s->reloc_count = 0;

             /* If combreloc is enabled, elf_link_sort_relocs() will
               sort relocations, but in a different way than we do,
               and before we're done creating relocations.  Also, it
               will move them around between input sections'
               relocation's contents, so our sorting would be
               broken, so don't let it run.  */
             info->combreloc = 0;
           }
       }
      else if (htab->is_vxworks && strcmp (name, ".got") == 0)
       {
         /* Executables do not need a GOT.  */
         if (info->shared)
           {
             /* Allocate relocations for all but the reserved entries.  */
             struct mips_got_info *g;
             unsigned int count;

             g = mips_elf_got_info (dynobj, NULL);
             count = (g->global_gotno
                     + g->local_gotno
                     - MIPS_RESERVED_GOTNO (info));
             mips_elf_allocate_dynamic_relocations (dynobj, info, count);
           }
       }
      else if (!htab->is_vxworks && CONST_STRNEQ (name, ".got"))
       {
         /* _bfd_mips_elf_always_size_sections() has already done
            most of the work, but some symbols may have been mapped
            to versions that we must now resolve in the got_entries
            hash tables.  */
         struct mips_got_info *gg = mips_elf_got_info (dynobj, NULL);
         struct mips_got_info *g = gg;
         struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
         unsigned int needed_relocs = 0;

         if (gg->next)
           {
             set_got_offset_arg.value = MIPS_ELF_GOT_SIZE (output_bfd);
             set_got_offset_arg.info = info;

             /* NOTE 2005-02-03: How can this call, or the next, ever
               find any indirect entries to resolve?  They were all
               resolved in mips_elf_multi_got.  */
             mips_elf_resolve_final_got_entries (gg);
             for (g = gg->next; g && g->next != gg; g = g->next)
              {
                unsigned int save_assign;

                mips_elf_resolve_final_got_entries (g);

                /* Assign offsets to global GOT entries.  */
                save_assign = g->assigned_gotno;
                g->assigned_gotno = g->local_gotno;
                set_got_offset_arg.g = g;
                set_got_offset_arg.needed_relocs = 0;
                htab_traverse (g->got_entries,
                             mips_elf_set_global_got_offset,
                             &set_got_offset_arg);
                needed_relocs += set_got_offset_arg.needed_relocs;
                BFD_ASSERT (g->assigned_gotno - g->local_gotno
                           <= g->global_gotno);

                g->assigned_gotno = save_assign;
                if (info->shared)
                  {
                    needed_relocs += g->local_gotno - g->assigned_gotno;
                    BFD_ASSERT (g->assigned_gotno == g->next->local_gotno
                              + g->next->global_gotno
                              + g->next->tls_gotno
                              + MIPS_RESERVED_GOTNO (info));
                  }
              }
           }
         else
           {
             struct mips_elf_count_tls_arg arg;
             arg.info = info;
             arg.needed = 0;

             htab_traverse (gg->got_entries, mips_elf_count_local_tls_relocs,
                          &arg);
             elf_link_hash_traverse (elf_hash_table (info),
                                  mips_elf_count_global_tls_relocs,
                                  &arg);

             needed_relocs += arg.needed;
           }

         if (needed_relocs)
           mips_elf_allocate_dynamic_relocations (dynobj, info,
                                             needed_relocs);
       }
      else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
       {
         /* IRIX rld assumes that the function stub isn't at the end
            of .text section.  So put a dummy.  XXX  */
         s->size += htab->function_stub_size;
       }
      else if (! info->shared
              && ! mips_elf_hash_table (info)->use_rld_obj_head
              && CONST_STRNEQ (name, ".rld_map"))
       {
         /* We add a room for __rld_map.  It will be filled in by the
            rtld to contain a pointer to the _r_debug structure.  */
         s->size += 4;
       }
      else if (SGI_COMPAT (output_bfd)
              && CONST_STRNEQ (name, ".compact_rel"))
       s->size += mips_elf_hash_table (info)->compact_rel_size;
      else if (! CONST_STRNEQ (name, ".init")
              && s != htab->sgotplt
              && s != htab->splt)
       {
         /* It's not one of our sections, so don't allocate space.  */
         continue;
       }

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

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

      /* Allocate memory for this section last, since we may increase its
        size above.  */
      if (strcmp (name, MIPS_ELF_REL_DYN_NAME (info)) == 0)
       {
         sreldyn = s;
         continue;
       }

      /* Allocate memory for the section contents.  */
      s->contents = bfd_zalloc (dynobj, s->size);
      if (s->contents == NULL)
       {
         bfd_set_error (bfd_error_no_memory);
         return FALSE;
       }
    }

  /* Allocate memory for the .rel(a).dyn section.  */
  if (sreldyn != NULL)
    {
      sreldyn->contents = bfd_zalloc (dynobj, sreldyn->size);
      if (sreldyn->contents == NULL)
       {
         bfd_set_error (bfd_error_no_memory);
         return FALSE;
       }
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add some entries to the .dynamic section.  We fill in the
        values later, in _bfd_mips_elf_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.  */
      if (info->executable)
       {
         /* SGI object has the equivalence of DT_DEBUG in the
            DT_MIPS_RLD_MAP entry.  */
         if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
           return FALSE;
         if (!SGI_COMPAT (output_bfd))
           {
             if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
              return FALSE;
           }
       }

      if (reltext && (SGI_COMPAT (output_bfd) || htab->is_vxworks))
       info->flags |= DF_TEXTREL;

      if ((info->flags & DF_TEXTREL) != 0)
       {
         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
           return FALSE;

         /* Clear the DF_TEXTREL flag.  It will be set again if we
            write out an actual text relocation; we may not, because
            at this point we do not know whether e.g. any .eh_frame
            absolute relocations have been converted to PC-relative.  */
         info->flags &= ~DF_TEXTREL;
       }

      if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
       return FALSE;

      if (htab->is_vxworks)
       {
         /* VxWorks uses .rela.dyn instead of .rel.dyn.  It does not
            use any of the DT_MIPS_* tags.  */
         if (mips_elf_rel_dyn_section (info, FALSE))
           {
             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELA, 0))
              return FALSE;

             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELASZ, 0))
              return FALSE;

             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELAENT, 0))
              return FALSE;
           }
         if (htab->splt->size > 0)
           {
             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTREL, 0))
              return FALSE;

             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_JMPREL, 0))
              return FALSE;

             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTRELSZ, 0))
              return FALSE;
           }
       }
      else
       {
         if (mips_elf_rel_dyn_section (info, FALSE))
           {
             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
              return FALSE;

             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
              return FALSE;

             if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
              return FALSE;
           }

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_VERSION, 0))
           return FALSE;

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_FLAGS, 0))
           return FALSE;

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_BASE_ADDRESS, 0))
           return FALSE;

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LOCAL_GOTNO, 0))
           return FALSE;

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_SYMTABNO, 0))
           return FALSE;

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_UNREFEXTNO, 0))
           return FALSE;

         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_GOTSYM, 0))
           return FALSE;

         if (IRIX_COMPAT (dynobj) == ict_irix5
             && ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_HIPAGENO, 0))
           return FALSE;

         if (IRIX_COMPAT (dynobj) == ict_irix6
             && (bfd_get_section_by_name
                (dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
             && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
           return FALSE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

void _bfd_mips_elf_symbol_processing ( bfd abfd,
asymbol asym 
)

Definition at line 5095 of file elfxx-mips.c.

{
  elf_symbol_type *elfsym;

  elfsym = (elf_symbol_type *) asym;
  switch (elfsym->internal_elf_sym.st_shndx)
    {
    case SHN_MIPS_ACOMMON:
      /* This section is used in a dynamically linked executable file.
        It is an allocated common section.  The dynamic linker can
        either resolve these symbols to something in a shared
        library, or it can just leave them here.  For our purposes,
        we can consider these symbols to be in a new section.  */
      if (mips_elf_acom_section.name == NULL)
       {
         /* Initialize the acommon section.  */