#include "bfdlink.h"
#include "genlink.h"
#include "elf-bfd.h"
-
-#define START_RELOC_NUMBERS(name) enum name {
-#define RELOC_NUMBER(name, number) name = number ,
-#define END_RELOC_NUMBERS };
#include "elf/mips.h"
/* Get the ECOFF swapping routines. */
static boolean mips_elf_modify_segment_map PARAMS ((bfd *));
static INLINE int elf_mips_isa PARAMS ((flagword));
static INLINE int elf_mips_mach PARAMS ((flagword));
+static INLINE char* elf_mips_abi_name PARAMS ((flagword));
static boolean mips_elf32_section_from_shdr
PARAMS ((bfd *, Elf32_Internal_Shdr *, char *));
static boolean mips_elf32_section_processing
#define STUB_LI16 0x34180000 /* ori t8,zero,0 */
#define MIPS_FUNCTION_STUB_SIZE (16)
+#if 0
+/* We no longer try to identify particular sections for the .dynsym
+ section. When we do, we wind up crashing if there are other random
+ sections with relocations. */
+
/* Names of sections which appear in the .dynsym section in an Irix 5
executable. */
#define MIPS_TEXT_DYNSYM_SECNO (3)
+#endif /* 0 */
+
/* The names of the runtime procedure table symbols used on Irix 5. */
static const char * const mips_elf_dynsym_rtproc_names[] =
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
- /* start-sanitize-r5900 */
- HOWTO (R_MIPS15_S3, /* type */
- 3, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 15, /* bitsize */
- false, /* pc_relative */
- 6, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MIPS15_S3", /* name */
- true, /* partial_inplace */
- 0x001fffc0, /* src_mask */
- 0x001fffc0, /* dst_mask */
- false) /* pcrel_offset */
- /* end-sanitize-r5900 */
-
+ { R_MIPS_SCN_DISP },
+ { R_MIPS_REL16 },
+ { R_MIPS_ADD_IMMEDIATE },
+ { R_MIPS_PJUMP },
+ { R_MIPS_RELGOT }
};
/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
0xffff, /* dst_mask */
false); /* pcrel_offset */
+/* start-sanitize-r5900 */
+static reloc_howto_type elf_mips15_s3_howto =
+ HOWTO (R_MIPS15_S3, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS15_S3", /* name */
+ true, /* partial_inplace */
+ 0x001fffc0, /* src_mask */
+ 0x001fffc0, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* end-sanitize-r5900 */
/* start-sanitize-sky */
/* DVP relocations.
Note that partial_inplace and pcrel_offset are backwards from the
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
- NULL, /* special_function */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_MIPS_GNU_VTENTRY", /* name */
false, /* partial_inplace */
0, /* src_mask */
bfd *output_bfd;
char **error_message;
{
- boolean relocateable;
- bfd_reloc_status_type ret;
bfd_vma relocation;
bfd_vma x;
case E_MIPS_MACH_4100:
return bfd_mach_mips4100;
+ /* start-sanitize-vr4xxx */
+
+ case E_MIPS_MACH_4121:
+ return bfd_mach_mips4121;
+ /* end-sanitize-vr4xxx */
/* start-sanitize-vr4320 */
case E_MIPS_MACH_4320:
case E_MIPS_MACH_4900:
return bfd_mach_mips4900;
/* end-sanitize-tx49 */
- /* start-sanitize-vr5400 */
+ /* start-sanitize-cygnus */
case E_MIPS_MACH_5400:
return bfd_mach_mips5400;
- /* end-sanitize-vr5400 */
+ /* end-sanitize-cygnus */
/* start-sanitize-r5900 */
case E_MIPS_MACH_5900:
return 0;
}
+/* Return printable name for ABI from flagword. */
+
+static INLINE char*
+elf_mips_abi_name (flags)
+ flagword flags;
+{
+ switch (flags & EF_MIPS_ABI)
+ {
+ case 0:
+ return "none";
+ case E_MIPS_ABI_O32:
+ return "O32";
+ case E_MIPS_ABI_O64:
+ return "O64";
+ case E_MIPS_ABI_EABI32:
+ return "EABI32";
+ case E_MIPS_ABI_EABI64:
+ return "EABI64";
+ default:
+ return "unknown abi";
+ }
+}
+
/* A mapping from BFD reloc types to MIPS ELF reloc types. */
struct elf_reloc_map {
{ BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
{ BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
{ BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
- { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
- /* start-sanitize-r5900 */
- { BFD_RELOC_MIPS15_S3, R_MIPS15_S3 },
- /* end-sanitize-r5900 */
+ { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }
};
/* Given a BFD reloc type, return a howto structure. */
switch (code)
{
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+
case BFD_RELOC_CTOR:
/* We need to handle BFD_RELOC_CTOR specially.
Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
return &elf_mips16_jump_howto;
case BFD_RELOC_MIPS16_GPREL:
return &elf_mips16_gprel_howto;
+/* start-sanitize-r5900 */
+ case BFD_RELOC_MIPS15_S3:
+ return &elf_mips15_s3_howto;
+/* end-sanitize-r5900 */
/* start-sanitize-sky */
case BFD_RELOC_MIPS_DVP_11_PCREL:
return &elf_mips_dvp_11_pcrel_howto;
case BFD_RELOC_VTABLE_ENTRY:
return &elf_mips_gnu_vtentry_howto;
}
-
- return NULL;
}
/* Given a MIPS reloc type, fill in an arelent structure. */
case R_MIPS16_GPREL:
cache_ptr->howto = &elf_mips16_gprel_howto;
break;
+/* start-sanitize-r5900 */
+ case R_MIPS15_S3:
+ cache_ptr->howto = &elf_mips15_s3_howto;
+ break;
+/* end-sanitize-r5900 */
/* start-sanitize-sky */
case R_MIPS_DVP_11_PCREL:
cache_ptr->howto = &elf_mips_dvp_11_pcrel_howto;
break;
case bfd_mach_mips4000:
+ case bfd_mach_mips4300:
val = E_MIPS_ARCH_3;
break;
case bfd_mach_mips4100:
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4100;
break;
+ /* start-sanitize-vr4xxx */
+
+ case bfd_mach_mips4121:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4121;
+ break;
+ /* end-sanitize-vr4xxx */
/* start-sanitize-vr4320 */
case bfd_mach_mips4320:
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4900;
break;
/* end-sanitize-tx49 */
- /* start-sanitize-vr5400 */
+ /* start-sanitize-cygnus */
case bfd_mach_mips5400:
val = E_MIPS_ARCH_3 | E_MIPS_MACH_5400;
break;
- /* end-sanitize-vr5400 */
+ /* end-sanitize-cygnus */
/* start-sanitize-r5900 */
case bfd_mach_mips5900:
old_flags &= ~ (EF_MIPS_ARCH | EF_MIPS_MACH);
}
+ /* Compare ABI's */
+ if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI))
+ {
+ /* Only error if both are set (to different values). */
+ if ((new_flags & EF_MIPS_ABI)
+ && (old_flags & EF_MIPS_ABI))
+ {
+ (*_bfd_error_handler)
+ (_("%s: ABI mismatch: linking %s module with previous %s modules"),
+ bfd_get_filename (ibfd),
+ elf_mips_abi_name (new_flags),
+ elf_mips_abi_name (old_flags));
+ ok = false;
+ }
+ new_flags &= ~EF_MIPS_ABI;
+ old_flags &= ~EF_MIPS_ABI;
+ }
+
/* Warn about any other mismatches */
if (new_flags != old_flags)
{
switch (hdr->sh_type)
{
case SHT_MIPS_LIBLIST:
- if (strcmp (name, _(".liblist")) != 0)
+ if (strcmp (name, ".liblist") != 0)
return false;
break;
case SHT_MIPS_MSYM:
|| strcmp (name, ".dynstr") == 0))
{
hdr->sh_entsize = 0;
+#if 0
+ /* This isn't how the Irix 6 linker behaves. */
hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#endif
}
else if (strcmp (name, ".got") == 0
|| strcmp (name, ".sdata") == 0
{
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))
struct mips_elf_link_hash_table
{
struct elf_link_hash_table root;
+#if 0
+ /* We no longer use this. */
/* String section indices for the dynamic section symbols. */
bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES];
+#endif
/* The number of .rtproc entries. */
bfd_size_type procedure_count;
/* The size of the .compact_rel section (if SGI_COMPAT). */
bfd *abfd;
{
struct mips_elf_link_hash_table *ret;
- unsigned int i;
ret = ((struct mips_elf_link_hash_table *)
bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table)));
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;
|| r_type == R_MIPS_GNU_VTENTRY)
continue;
if ((r_type < 0 || r_type >= (int) R_MIPS_max)
+/* start-sanitize-r5900 */
+ && r_type != R_MIPS15_S3
+/* end-sanitize-r5900 */
/* start-sanitize-sky */
&& r_type != R_MIPS_DVP_11_PCREL
&& r_type != R_MIPS_DVP_27_S4
howto = &elf_mips16_jump_howto;
else if (r_type == R_MIPS16_GPREL)
howto = &elf_mips16_gprel_howto;
+/* start-sanitize-r5900 */
+ else if (r_type == R_MIPS15_S3)
+ howto = &elf_mips15_s3_howto;
+/* end-sanitize-r5900 */
/* start-sanitize-sky */
else if (r_type == R_MIPS_DVP_11_PCREL)
howto = &elf_mips_dvp_11_pcrel_howto;
case bfd_link_hash_common:
return h->root.u.c.p->section;
+
+ default:
+ break;
}
}
}
That means we must increment the dynamic symbol index of every
other dynamic symbol. */
{
- const char * const *namep;
unsigned int c, i;
- bfd_size_type strindex;
- struct bfd_strtab_hash *dynstr;
struct mips_got_info *g;
c = 0;
if (elf_hash_table (info)->dynamic_sections_created)
{
+#if 0
+ /* We no longer try to restrict the set of sections which get
+ dynamic symbol table entries, since it fails if we have
+ other random sections which need dynamic relocations. */
+ const char * const *namep;
+ bfd_size_type strindex;
+ struct bfd_strtab_hash *dynstr;
+
if (SGI_COMPAT (output_bfd))
{
c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1;
}
}
else
+#endif /* 0 */
{
c = bfd_count_sections (output_bfd);
elf_link_hash_traverse (elf_hash_table (info),
break;
case DT_MIPS_UNREFEXTNO:
- /* XXX FIXME: */
+#if 0
dyn.d_un.d_val = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#else
+ dyn.d_un.d_val = bfd_count_sections (output_bfd);
+#endif
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
{
asection *sdynsym;
asection *s;
- unsigned int i;
- bfd_vma last;
Elf_Internal_Sym sym;
- long dindx;
- const char *name;
- const char * const * namep = mips_elf_dynsym_sec_names;
Elf32_compact_rel cpt;
/* Set up the section symbols for the output sections. SGI sets
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
if (sdynsym != NULL)
{
+#if 0
+ const char *name;
+ const char * const * namep = mips_elf_dynsym_sec_names;
+ unsigned int i;
+ bfd_vma last;
+ long dindx;
+
+ /* We no longer try to restrict the set of sections which get
+ dynamic symbol table entries, since it fails if we have
+ other random sections which need dynamic relocations. */
if (SGI_COMPAT (output_bfd))
{
sym.st_size = 0;
SIZEOF_MIPS_DYNSYM_SECNAMES;
}
else
+#endif /* 0 */
{
sym.st_size = 0;
sym.st_name = 0;