/* MIPS-specific support for 32-bit ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005 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,
<ian@cygnus.com>.
Traditional MIPS targets support added by Koundinya.K, Dansk Data
Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* This file handles MIPS ELF targets. SGI Irix 5 uses a slightly
different MIPS ELF from other targets. This matters when linking.
This file supports both, switching at runtime. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "libbfd.h"
#include "bfdlink.h"
#include "genlink.h"
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
- /* A placeholder for MIPS16 reference to global offset table. */
- EMPTY_HOWTO (R_MIPS16_GOT16),
+ /* A MIPS16 reference to the global offset table. */
+ 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. */
- EMPTY_HOWTO (R_MIPS16_CALL16),
+ /* A MIPS16 call through the global offset table. */
+ 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. */
HOWTO (R_MIPS16_HI16, /* type */
0, /* dst_mask */
FALSE); /* 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
dangerous relocation. */
if (relocatable)
{
/* Make up a value. */
- *pgp = symbol->section->output_section->vma + 0x4000;
+ *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
_bfd_set_gp_value (output_bfd, *pgp);
}
else if (!mips_elf_assign_gp (output_bfd, pgp))
{ BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
{ BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
{ BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
+ { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
{ BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
{ BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
{ BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
{
{ BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - 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_LO16, R_MIPS16_LO16 - R_MIPS16_min },
};
return &elf_mips_gnu_vtentry_howto;
case BFD_RELOC_32_PCREL:
return &elf_mips_gnu_pcrel32;
+ case BFD_RELOC_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case BFD_RELOC_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
}
}
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf_mips_howto_table_rel)
+ / sizeof (elf_mips_howto_table_rel[0]));
+ i++)
+ if (elf_mips_howto_table_rel[i].name != NULL
+ && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
+ return &elf_mips_howto_table_rel[i];
+
+ for (i = 0;
+ i < (sizeof (elf_mips16_howto_table_rel)
+ / sizeof (elf_mips16_howto_table_rel[0]));
+ i++)
+ if (elf_mips16_howto_table_rel[i].name != NULL
+ && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
+ return &elf_mips16_howto_table_rel[i];
+
+ if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+ return &elf_mips_gnu_pcrel32;
+ if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
+ return &elf_mips_gnu_rel16_s2;
+ if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtinherit_howto;
+ if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtentry_howto;
+ 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;
+}
+
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
static reloc_howto_type *
return &elf_mips_gnu_rel16_s2;
case R_MIPS_PC32:
return &elf_mips_gnu_pcrel32;
+ case R_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case R_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
default:
if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
when we do the relocation, because the symbol manipulations done
by the linker may cause us to lose track of the input BFD. */
if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
- && (r_type == (unsigned int) R_MIPS_GPREL16
- || r_type == (unsigned int) R_MIPS_LITERAL))
+ && (gprel16_reloc_p (r_type) || r_type == (unsigned int) R_MIPS_LITERAL))
cache_ptr->addend = elf_gp (abfd);
}
if (SGI_COMPAT (abfd))
return (sym->flags & BSF_SECTION_SYM) == 0;
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_com_section (bfd_get_section (sym)));
}
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+ elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
/* pr_reg */
offset = 72;
};
\f
#define ELF_ARCH bfd_arch_mips
+#define ELF_TARGET_ID MIPS_ELF_DATA
#define ELF_MACHINE_CODE EM_MIPS
#define elf_backend_collect TRUE
#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
#define elf_backend_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 \
_bfd_mips_elf_adjust_dynamic_symbol
#define elf_backend_always_size_sections \
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
#define elf_backend_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_psinfo elf32_mips_grok_psinfo
#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
#define elf_backend_may_use_rela_p 0
#define elf_backend_default_use_rela_p 0
#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_ignore_discarded_relocs \
_bfd_mips_elf_ignore_discarded_relocs
+#define elf_backend_write_section _bfd_mips_elf_write_section
#define elf_backend_mips_irix_compat elf32_mips_irix_compat
#define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
#define bfd_elf32_bfd_is_local_label_name \
/* Include the target file again for this target. */
#include "elf32-target.h"
+/* FreeBSD support. */
-/* Specific to VxWorks. */
-static reloc_howto_type mips_vxworks_copy_howto_rela =
- HOWTO (R_MIPS_COPY, /* 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_COPY", /* name */
- FALSE, /* partial_inplace */
- 0x0, /* src_mask */
- 0x0, /* dst_mask */
- FALSE); /* pcrel_offset */
-
-/* Specific to VxWorks. */
-static reloc_howto_type mips_vxworks_jump_slot_howto_rela =
- 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 */
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
-/* Implement elf_backend_bfd_reloc_type_lookup for VxWorks. */
+#define TARGET_LITTLE_SYM bfd_elf32_tradlittlemips_freebsd_vec
+#define TARGET_LITTLE_NAME "elf32-tradlittlemips-freebsd"
+#define TARGET_BIG_SYM bfd_elf32_tradbigmips_freebsd_vec
+#define TARGET_BIG_NAME "elf32-tradbigmips-freebsd"
-static reloc_howto_type *
-mips_vxworks_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
-{
- switch (code)
- {
- case BFD_RELOC_MIPS_COPY:
- return &mips_vxworks_copy_howto_rela;
- case BFD_RELOC_MIPS_JUMP_SLOT:
- return &mips_vxworks_jump_slot_howto_rela;
- default:
- return bfd_elf32_bfd_reloc_type_lookup (abfd, code);
- }
-}
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
-/* Implement elf_backend_mips_rtype_to_lookup for VxWorks. */
+/* The kernel recognizes executables as valid only if they carry a
+ "FreeBSD" label in the ELF header. So we put this label on all
+ executables and (for simplicity) also all other object files. */
-static reloc_howto_type *
-mips_vxworks_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
+static void
+elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
{
- switch (r_type)
- {
- case R_MIPS_COPY:
- return &mips_vxworks_copy_howto_rela;
- case R_MIPS_JUMP_SLOT:
- return &mips_vxworks_jump_slot_howto_rela;
- default:
- return mips_elf32_rtype_to_howto (r_type, rela_p);
- }
+ _bfd_elf_set_osabi (abfd, info);
}
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers elf_fbsd_post_process_headers
+#undef elf32_bed
+#define elf32_bed elf32_fbsd_tradbed
+
+#include "elf32-target.h"
/* Implement elf_backend_final_write_processing for VxWorks. */
static void
#define elf_backend_want_got_plt 1
#undef elf_backend_want_plt_sym
#define elf_backend_want_plt_sym 1
-#undef elf_backend_got_symbol_offset
-#define elf_backend_got_symbol_offset 0
-#undef elf_backend_want_dynbss
-#define elf_backend_want_dynbss 1
#undef elf_backend_may_use_rel_p
#define elf_backend_may_use_rel_p 0
#undef elf_backend_may_use_rela_p
#define elf_backend_default_use_rela_p 1
#undef elf_backend_got_header_size
#define elf_backend_got_header_size (4 * 3)
-#undef elf_backend_plt_readonly
-#define elf_backend_plt_readonly 1
-
-#undef bfd_elf32_bfd_reloc_type_lookup
-#define bfd_elf32_bfd_reloc_type_lookup \
- mips_vxworks_bfd_reloc_type_lookup
-#undef elf_backend_mips_rtype_to_howto
-#define elf_backend_mips_rtype_to_howto \
- mips_vxworks_rtype_to_howto
-#undef elf_backend_adjust_dynamic_symbol
-#define elf_backend_adjust_dynamic_symbol \
- _bfd_mips_vxworks_adjust_dynamic_symbol
+#undef elf_backend_plt_sym_val
+
#undef elf_backend_finish_dynamic_symbol
#define elf_backend_finish_dynamic_symbol \
_bfd_mips_vxworks_finish_dynamic_symbol