Line 1... |
Line 1... |
/* MIPS-specific support for 32-bit ELF
|
/* MIPS-specific support for 32-bit ELF
|
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
2003, 2004, 2005, 2007 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
|
|
Most of the information added by Ian Lance Taylor, Cygnus Support,
|
Most of the information added by Ian Lance Taylor, Cygnus Support,
|
<ian@cygnus.com>.
|
<ian@cygnus.com>.
|
N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
|
N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
|
<mark@codesourcery.com>
|
<mark@codesourcery.com>
|
Line 1494... |
Line 1494... |
TRUE, /* partial_inplace */
|
TRUE, /* partial_inplace */
|
0x0000ffff, /* src_mask */
|
0x0000ffff, /* src_mask */
|
0x0000ffff, /* dst_mask */
|
0x0000ffff, /* dst_mask */
|
FALSE), /* pcrel_offset */
|
FALSE), /* pcrel_offset */
|
|
|
/* A placeholder for MIPS16 reference to global offset table. */
|
/* A MIPS16 reference to the global offset table. */
|
EMPTY_HOWTO (R_MIPS16_GOT16),
|
HOWTO (R_MIPS16_GOT16, /* type */
|
|
0, /* rightshift */
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
|
16, /* bitsize */
|
|
FALSE, /* pc_relative */
|
|
0, /* bitpos */
|
|
complain_overflow_dont, /* complain_on_overflow */
|
|
_bfd_mips_elf_got16_reloc, /* special_function */
|
|
"R_MIPS16_GOT16", /* name */
|
|
TRUE, /* partial_inplace */
|
|
0x0000ffff, /* src_mask */
|
|
0x0000ffff, /* dst_mask */
|
|
FALSE), /* pcrel_offset */
|
|
|
/* A placeholder for MIPS16 16 bit call through global offset table. */
|
/* A MIPS16 call through the global offset table. */
|
EMPTY_HOWTO (R_MIPS16_CALL16),
|
HOWTO (R_MIPS16_CALL16, /* type */
|
|
0, /* rightshift */
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
|
16, /* bitsize */
|
|
FALSE, /* pc_relative */
|
|
0, /* bitpos */
|
|
complain_overflow_dont, /* complain_on_overflow */
|
|
_bfd_mips_elf_generic_reloc, /* special_function */
|
|
"R_MIPS16_CALL16", /* name */
|
|
TRUE, /* partial_inplace */
|
|
0x0000ffff, /* src_mask */
|
|
0x0000ffff, /* dst_mask */
|
|
FALSE), /* pcrel_offset */
|
|
|
/* MIPS16 high 16 bits of symbol value. */
|
/* MIPS16 high 16 bits of symbol value. */
|
HOWTO (R_MIPS16_HI16, /* type */
|
HOWTO (R_MIPS16_HI16, /* type */
|
16, /* rightshift */
|
16, /* rightshift */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
Line 1566... |
Line 1590... |
FALSE, /* partial_inplace */
|
FALSE, /* partial_inplace */
|
0x0000ffff, /* src_mask */
|
0x0000ffff, /* src_mask */
|
0x0000ffff, /* dst_mask */
|
0x0000ffff, /* dst_mask */
|
FALSE), /* pcrel_offset */
|
FALSE), /* pcrel_offset */
|
|
|
/* A placeholder for MIPS16 reference to global offset table. */
|
/* A MIPS16 reference to the global offset table. */
|
EMPTY_HOWTO (R_MIPS16_GOT16),
|
HOWTO (R_MIPS16_GOT16, /* type */
|
|
0, /* rightshift */
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
|
16, /* bitsize */
|
|
FALSE, /* pc_relative */
|
|
0, /* bitpos */
|
|
complain_overflow_dont, /* complain_on_overflow */
|
|
_bfd_mips_elf_got16_reloc, /* special_function */
|
|
"R_MIPS16_GOT16", /* name */
|
|
FALSE, /* partial_inplace */
|
|
0x0000ffff, /* src_mask */
|
|
0x0000ffff, /* dst_mask */
|
|
FALSE), /* pcrel_offset */
|
|
|
/* A placeholder for MIPS16 16 bit call through global offset table. */
|
/* A MIPS16 call through the global offset table. */
|
EMPTY_HOWTO (R_MIPS16_CALL16),
|
HOWTO (R_MIPS16_CALL16, /* type */
|
|
0, /* rightshift */
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
|
16, /* bitsize */
|
|
FALSE, /* pc_relative */
|
|
0, /* bitpos */
|
|
complain_overflow_dont, /* complain_on_overflow */
|
|
_bfd_mips_elf_generic_reloc, /* special_function */
|
|
"R_MIPS16_CALL16", /* name */
|
|
FALSE, /* partial_inplace */
|
|
0x0000ffff, /* src_mask */
|
|
0x0000ffff, /* dst_mask */
|
|
FALSE), /* pcrel_offset */
|
|
|
/* MIPS16 high 16 bits of symbol value. */
|
/* MIPS16 high 16 bits of symbol value. */
|
HOWTO (R_MIPS16_HI16, /* type */
|
HOWTO (R_MIPS16_HI16, /* type */
|
16, /* rightshift */
|
16, /* rightshift */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
Line 1667... |
Line 1715... |
FALSE, /* partial_inplace */
|
FALSE, /* partial_inplace */
|
0, /* src_mask */
|
0, /* src_mask */
|
0x0000ffff, /* dst_mask */
|
0x0000ffff, /* dst_mask */
|
TRUE); /* pcrel_offset */
|
TRUE); /* pcrel_offset */
|
|
|
|
/* Originally a VxWorks extension, but now used for other systems too. */
|
|
static reloc_howto_type elf_mips_copy_howto =
|
|
HOWTO (R_MIPS_COPY, /* type */
|
|
0, /* rightshift */
|
|
0, /* this one is variable size */
|
|
0, /* bitsize */
|
|
FALSE, /* pc_relative */
|
|
0, /* bitpos */
|
|
complain_overflow_bitfield, /* complain_on_overflow */
|
|
bfd_elf_generic_reloc, /* special_function */
|
|
"R_MIPS_COPY", /* name */
|
|
FALSE, /* partial_inplace */
|
|
0x0, /* src_mask */
|
|
0x0, /* dst_mask */
|
|
FALSE); /* pcrel_offset */
|
|
|
|
/* Originally a VxWorks extension, but now used for other systems too. */
|
|
static reloc_howto_type elf_mips_jump_slot_howto =
|
|
HOWTO (R_MIPS_JUMP_SLOT, /* type */
|
|
0, /* rightshift */
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
|
32, /* bitsize */
|
|
FALSE, /* pc_relative */
|
|
0, /* bitpos */
|
|
complain_overflow_bitfield, /* complain_on_overflow */
|
|
bfd_elf_generic_reloc, /* special_function */
|
|
"R_MIPS_JUMP_SLOT", /* name */
|
|
FALSE, /* partial_inplace */
|
|
0x0, /* src_mask */
|
|
0x0, /* dst_mask */
|
|
FALSE); /* pcrel_offset */
|
|
|
/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
|
/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
|
dangerous relocation. */
|
dangerous relocation. */
|
|
|
static bfd_boolean
|
static bfd_boolean
|
mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
|
mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
|
Line 2039... |
Line 2119... |
|
|
static const struct elf_reloc_map mips16_reloc_map[] =
|
static const struct elf_reloc_map mips16_reloc_map[] =
|
{
|
{
|
{ BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
|
|
{ BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
|
|
{ BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
|
{ BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
|
};
|
};
|
|
|
/* Given a BFD reloc type, return a howto structure. */
|
/* Given a BFD reloc type, return a howto structure. */
|
Line 2075... |
Line 2157... |
{
|
{
|
case BFD_RELOC_VTABLE_INHERIT:
|
case BFD_RELOC_VTABLE_INHERIT:
|
return &elf_mips_gnu_vtinherit_howto;
|
return &elf_mips_gnu_vtinherit_howto;
|
case BFD_RELOC_VTABLE_ENTRY:
|
case BFD_RELOC_VTABLE_ENTRY:
|
return &elf_mips_gnu_vtentry_howto;
|
return &elf_mips_gnu_vtentry_howto;
|
|
case BFD_RELOC_MIPS_COPY:
|
|
return &elf_mips_copy_howto;
|
|
case BFD_RELOC_MIPS_JUMP_SLOT:
|
|
return &elf_mips_jump_slot_howto;
|
default:
|
default:
|
bfd_set_error (bfd_error_bad_value);
|
bfd_set_error (bfd_error_bad_value);
|
return NULL;
|
return NULL;
|
}
|
}
|
}
|
}
|
Line 2111... |
Line 2197... |
return &elf_mips_gnu_vtentry_howto;
|
return &elf_mips_gnu_vtentry_howto;
|
if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
|
if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
|
return &elf_mips_gnu_rel16_s2;
|
return &elf_mips_gnu_rel16_s2;
|
if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
|
if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
|
return &elf_mips_gnu_rela16_s2;
|
return &elf_mips_gnu_rela16_s2;
|
|
if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
|
|
return &elf_mips_copy_howto;
|
|
if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
|
|
return &elf_mips_jump_slot_howto;
|
|
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
|
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
|
Line 2131... |
Line 2221... |
case R_MIPS_GNU_REL16_S2:
|
case R_MIPS_GNU_REL16_S2:
|
if (rela_p)
|
if (rela_p)
|
return &elf_mips_gnu_rela16_s2;
|
return &elf_mips_gnu_rela16_s2;
|
else
|
else
|
return &elf_mips_gnu_rel16_s2;
|
return &elf_mips_gnu_rel16_s2;
|
|
case R_MIPS_COPY:
|
|
return &elf_mips_copy_howto;
|
|
case R_MIPS_JUMP_SLOT:
|
|
return &elf_mips_jump_slot_howto;
|
default:
|
default:
|
if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
|
if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
|
{
|
{
|
if (rela_p)
|
if (rela_p)
|
return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
|
return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
|
Line 2193... |
Line 2287... |
mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
|
mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
|
{
|
{
|
if (SGI_COMPAT (abfd))
|
if (SGI_COMPAT (abfd))
|
return (sym->flags & BSF_SECTION_SYM) == 0;
|
return (sym->flags & BSF_SECTION_SYM) == 0;
|
else
|
else
|
return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
|
return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
|
|| bfd_is_und_section (bfd_get_section (sym))
|
|| bfd_is_und_section (bfd_get_section (sym))
|
|| bfd_is_com_section (bfd_get_section (sym)));
|
|| bfd_is_com_section (bfd_get_section (sym)));
|
}
|
}
|
|
|
/* Set the right machine number for a MIPS ELF file. */
|
/* Set the right machine number for a MIPS ELF file. */
|
Line 2359... |
Line 2453... |
#define elf_backend_create_dynamic_sections \
|
#define elf_backend_create_dynamic_sections \
|
_bfd_mips_elf_create_dynamic_sections
|
_bfd_mips_elf_create_dynamic_sections
|
#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
|
#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
|
#define elf_backend_merge_symbol_attribute \
|
#define elf_backend_merge_symbol_attribute \
|
_bfd_mips_elf_merge_symbol_attribute
|
_bfd_mips_elf_merge_symbol_attribute
|
|
#define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
|
#define elf_backend_adjust_dynamic_symbol \
|
#define elf_backend_adjust_dynamic_symbol \
|
_bfd_mips_elf_adjust_dynamic_symbol
|
_bfd_mips_elf_adjust_dynamic_symbol
|
#define elf_backend_always_size_sections \
|
#define elf_backend_always_size_sections \
|
_bfd_mips_elf_always_size_sections
|
_bfd_mips_elf_always_size_sections
|
#define elf_backend_size_dynamic_sections \
|
#define elf_backend_size_dynamic_sections \
|
Line 2380... |
Line 2475... |
#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
|
#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
|
#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
|
#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
|
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
|
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
|
#define elf_backend_copy_indirect_symbol \
|
#define elf_backend_copy_indirect_symbol \
|
_bfd_mips_elf_copy_indirect_symbol
|
_bfd_mips_elf_copy_indirect_symbol
|
#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
|
|
#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
|
#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
|
#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
|
#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
|
#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
|
#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
|
|
|
#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
|
#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
|
Line 2392... |
Line 2486... |
/* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
|
/* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
|
work better/work only in RELA, so we default to this. */
|
work better/work only in RELA, so we default to this. */
|
#define elf_backend_may_use_rel_p 1
|
#define elf_backend_may_use_rel_p 1
|
#define elf_backend_may_use_rela_p 1
|
#define elf_backend_may_use_rela_p 1
|
#define elf_backend_default_use_rela_p 1
|
#define elf_backend_default_use_rela_p 1
|
|
#define elf_backend_rela_plts_and_copies_p 0
|
#define elf_backend_sign_extend_vma TRUE
|
#define elf_backend_sign_extend_vma TRUE
|
|
#define elf_backend_plt_readonly 1
|
|
#define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
|
|
|
#define elf_backend_discard_info _bfd_mips_elf_discard_info
|
#define elf_backend_discard_info _bfd_mips_elf_discard_info
|
#define elf_backend_ignore_discarded_relocs \
|
#define elf_backend_ignore_discarded_relocs \
|
_bfd_mips_elf_ignore_discarded_relocs
|
_bfd_mips_elf_ignore_discarded_relocs
|
#define elf_backend_write_section _bfd_mips_elf_write_section
|
#define elf_backend_write_section _bfd_mips_elf_write_section
|
Line 2406... |
Line 2503... |
#define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
|
#define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
|
#define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
|
#define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
|
#define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
|
#define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
|
#define bfd_elf32_bfd_get_relocated_section_contents \
|
#define bfd_elf32_bfd_get_relocated_section_contents \
|
_bfd_elf_mips_get_relocated_section_contents
|
_bfd_elf_mips_get_relocated_section_contents
|
|
#define bfd_elf32_mkobject _bfd_mips_elf_mkobject
|
#define bfd_elf32_bfd_link_hash_table_create \
|
#define bfd_elf32_bfd_link_hash_table_create \
|
_bfd_mips_elf_link_hash_table_create
|
_bfd_mips_elf_link_hash_table_create
|
#define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
|
#define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
|
#define bfd_elf32_bfd_merge_private_bfd_data \
|
#define bfd_elf32_bfd_merge_private_bfd_data \
|
_bfd_mips_elf_merge_private_bfd_data
|
_bfd_mips_elf_merge_private_bfd_data
|