-l/* MIPS-specific support for 32-bit ELF
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+/* MIPS-specific support for 32-bit ELF
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Most of the information added by Ian Lance Taylor, Cygnus Support,
this symbol. */
unsigned int possibly_dynamic_relocs;
+ /* If the R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 reloc is against
+ a readonly section. */
+ boolean readonly_reloc;
+
/* The index of the first dynamic relocation (in the .rel.dyn
section) against this symbol. */
unsigned int min_dyn_reloc_index;
PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *,
struct ecoff_debug_info *));
static INLINE int elf_mips_isa PARAMS ((flagword));
-static INLINE int elf_mips_mach PARAMS ((flagword));
+static INLINE unsigned long elf_mips_mach PARAMS ((flagword));
static INLINE char* elf_mips_abi_name PARAMS ((bfd *));
static boolean mips_elf_is_local_label_name
PARAMS ((bfd *, const char *));
PARAMS ((bfd *, asection *));
static int sort_dynamic_relocs
PARAMS ((const void *, const void *));
+static void _bfd_mips_elf_hide_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static void _bfd_mips_elf_copy_indirect_symbol
+ PARAMS ((struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *));
+static boolean _bfd_elf32_mips_grok_prstatus
+ PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean _bfd_elf32_mips_grok_psinfo
+ PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean _bfd_elf32_mips_discard_info
+ PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *));
+static boolean _bfd_elf32_mips_ignore_discarded_relocs
+ PARAMS ((asection *));
+static boolean _bfd_elf32_mips_write_section
+ PARAMS ((bfd *, asection *, bfd_byte *));
extern const bfd_target bfd_elf32_tradbigmips_vec;
extern const bfd_target bfd_elf32_tradlittlemips_vec;
(abfd->xvec == &bfd_elf32_tradlittlemips_vec)) ? ict_none : \
((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5))
#endif
-/* Whether we are trying to be compatible with IRIX at all. */
+#define NEWABI_P(abfd) (ABI_N32_P(abfd) || ABI_64_P(abfd))
+
+/* Whether we are trying to be compatible with IRIX at all. */
#define SGI_COMPAT(abfd) \
(IRIX_COMPAT (abfd) != ict_none)
/* Add a dynamic symbol table-entry. */
#ifdef BFD64
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
- (ABI_64_P (elf_hash_table (info)->dynobj) \
- ? bfd_elf64_add_dynamic_entry (info, tag, val) \
- : bfd_elf32_add_dynamic_entry (info, tag, val))
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
+ (ABI_64_P (elf_hash_table (info)->dynobj) \
+ ? bfd_elf64_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val) \
+ : bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
#else
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
- (ABI_64_P (elf_hash_table (info)->dynobj) \
- ? (abort (), false) \
- : bfd_elf32_add_dynamic_entry (info, tag, val))
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
+ (ABI_64_P (elf_hash_table (info)->dynobj) \
+ ? (boolean) (abort (), false) \
+ : bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
#endif
/* The number of local .got entries we reserve. */
static void bfd_elf32_swap_crinfo_out
PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *));
-#define USE_REL 1 /* MIPS uses REL relocations instead of RELA */
-
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
from smaller values. Start with zero, widen, *then* decrement. */
#define MINUS_ONE (((bfd_vma)0) - 1)
-static reloc_howto_type elf_mips_howto_table[] =
+/* The relocation table used for SHT_REL sections. */
+
+static reloc_howto_type elf_mips_howto_table_rel[] =
{
/* No relocation. */
HOWTO (R_MIPS_NONE, /* type */
/* 16 bit relocation. */
HOWTO (R_MIPS_16, /* type */
0, /* rightshift */
- 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_16", /* name */
true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* 32 bit relocation. */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_32", /* name */
true, /* partial_inplace */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_REL32", /* name */
true, /* partial_inplace */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_26", /* name */
true, /* partial_inplace */
- 0x3ffffff, /* src_mask */
- 0x3ffffff, /* dst_mask */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
false), /* pcrel_offset */
/* High 16 bits of symbol value. */
_bfd_mips_elf_hi16_reloc, /* special_function */
"R_MIPS_HI16", /* name */
true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* Low 16 bits of symbol value. */
_bfd_mips_elf_lo16_reloc, /* special_function */
"R_MIPS_LO16", /* name */
true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* GP relative reference. */
_bfd_mips_elf_gprel16_reloc, /* special_function */
"R_MIPS_GPREL16", /* name */
true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* Reference to literal section. */
_bfd_mips_elf_gprel16_reloc, /* special_function */
"R_MIPS_LITERAL", /* name */
true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* Reference to global offset table. */
complain_overflow_signed, /* complain_on_overflow */
_bfd_mips_elf_got16_reloc, /* special_function */
"R_MIPS_GOT16", /* name */
- false, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* 16 bit PC relative reference. */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_PC16", /* name */
true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
true), /* pcrel_offset */
/* 16 bit call through global offset table. */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_CALL16", /* name */
- false, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* 32 bit GP relative reference. */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
_bfd_mips_elf_gprel32_reloc, /* special_function */
"R_MIPS_GPREL32", /* name */
true, /* partial_inplace */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
- /* The remaining relocs are defined on Irix 5, although they are
- not defined by the ABI. */
- EMPTY_HOWTO (13),
- EMPTY_HOWTO (14),
- EMPTY_HOWTO (15),
+ /* The remaining relocs are defined on Irix 5, although they are
+ not defined by the ABI. */
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
/* A 5 bit shift field. */
HOWTO (R_MIPS_SHIFT5, /* type */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
mips32_64bit_reloc, /* special_function */
"R_MIPS_64", /* name */
true, /* partial_inplace */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_GOT_DISP", /* name */
true, /* partial_inplace */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_GOT_PAGE", /* name */
true, /* partial_inplace */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_GOT_OFST", /* name */
true, /* partial_inplace */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_SUB", /* name */
true, /* partial_inplace */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_HIGHER", /* name */
true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ HOWTO (R_MIPS_HIGHEST, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHEST", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MIPS_CALL_HI16, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_HI16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MIPS_CALL_LO16, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_REL16),
+ EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+ EMPTY_HOWTO (R_MIPS_PJUMP),
+ EMPTY_HOWTO (R_MIPS_RELGOT),
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_JALR", /* name */
+ false, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ false), /* pcrel_offset */
+};
+
+/* The relocation table used for SHT_RELA sections. */
+
+static reloc_howto_type elf_mips_howto_table_rela[] =
+{
+ /* No relocation. */
+ HOWTO (R_MIPS_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit relocation. */
+ HOWTO (R_MIPS_16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit relocation. */
+ HOWTO (R_MIPS_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit symbol relative relocation. */
+ HOWTO (R_MIPS_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 26 bit jump address. */
+ HOWTO (R_MIPS_26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ /* This needs complex overflow
+ detection, because the upper 36
+ bits must match the PC + 4. */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for 64 bit REL. */
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_HI16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MIPS_LO16, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_LO16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MIPS_GPREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MIPS_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ /* FIXME: This is not handled correctly. */
+ HOWTO (R_MIPS_GOT16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. */
+ HOWTO (R_MIPS_PC16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ /* FIXME: This is not handled correctly. */
+ HOWTO (R_MIPS_CALL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit GP relative reference. */
+ HOWTO (R_MIPS_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+
+ /* A 5 bit shift field. */
+ HOWTO (R_MIPS_SHIFT5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT5", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000007c0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 6 bit shift field. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_SHIFT6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000007c4, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit relocation. */
+ HOWTO (R_MIPS_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_DISP", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_PAGE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_PAGE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_OFST, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_OFST", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_HI16, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_HI16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_LO16, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_LO16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit substraction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Insert the addend as an instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_INSERT_A, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Insert the addend as an instruction, and change all relocations
+ to refer to the old instruction at the address. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_INSERT_B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ HOWTO (R_MIPS_HIGHER, /* 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_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHER", /* name */
+ false, /* partial_inplace */
0, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* Get the highest value of a 64 bit addend. */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ bfd_elf_generic_reloc, /* special_function */
"R_MIPS_HIGHEST", /* name */
- true, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
- 0xffff, /* dst_mask */
+ 0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
HOWTO (R_MIPS_CALL_HI16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_CALL_HI16", /* name */
- true, /* partial_inplace */
- 0x0000ffff, /* src_mask */
+ false, /* partial_inplace */
+ 0, /* src_mask */
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
HOWTO (R_MIPS_CALL_LO16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_CALL_LO16", /* name */
- true, /* partial_inplace */
- 0x0000ffff, /* src_mask */
+ false, /* partial_inplace */
+ 0, /* src_mask */
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
- /* Section displacement. */
- HOWTO (R_MIPS_SCN_DISP, /* type */
+ /* Section displacement, used by an associated event location section. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_MIPS_SCN_DISP", /* name */
+ "R_MIPS_SCN_DISP", /* name */
false, /* partial_inplace */
- 0xffffffff, /* src_mask */
+ 0, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
- EMPTY_HOWTO (R_MIPS_REL16),
+ HOWTO (R_MIPS_REL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* These two are obsolete. */
EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
EMPTY_HOWTO (R_MIPS_PJUMP),
- EMPTY_HOWTO (R_MIPS_RELGOT),
+
+ /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
+ It must be used for multigot GOT's (and only there). */
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
/* Protected jump conversion. This is an optimization hint. No
relocation is required for correctness. */
HOWTO (R_MIPS_JALR, /* type */
0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MIPS_JALR", /* name */
false, /* partial_inplace */
- 0x00000000, /* src_mask */
- 0x00000000, /* dst_mask */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
false), /* pcrel_offset */
};
relocation += symbol->section->output_section->vma;
relocation += symbol->section->output_offset;
relocation += reloc_entry->addend;
+ if (reloc_entry->howto->pc_relative)
+ relocation -= reloc_entry->address;
if (reloc_entry->address > input_section->_cooked_size)
return bfd_reloc_outofrange;
/* Save the information, and let LO16 do the actual relocation. */
- n = (struct mips_hi16 *) bfd_malloc (sizeof *n);
+ n = (struct mips_hi16 *) bfd_malloc ((bfd_size_type) sizeof *n);
if (n == NULL)
return bfd_reloc_outofrange;
n->addr = (bfd_byte *) data + reloc_entry->address;
to know anything about the LO16 itself, except where to
find the low 16 bits of the addend needed by the LO16. */
insn = bfd_get_32 (abfd, l->addr);
- vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
- & 0xffff);
+ vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* The low order 16 bits are always treated as a signed
+ value. */
+ vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
val = ((insn & 0xffff) << 16) + vallo;
val += l->addend;
- /* The low order 16 bits are always treated as a signed
- value. Therefore, a negative value in the low order bits
- requires an adjustment in the high order bits. We need
- to make this adjustment in two ways: once for the bits we
- took from the data, and once for the bits we are putting
- back in to the data. */
- if ((vallo & 0x8000) != 0)
- val -= 0x10000;
- if ((val & 0x8000) != 0)
- val += 0x10000;
-
- insn = (insn & ~0xffff) | ((val >> 16) & 0xffff);
- bfd_put_32 (abfd, insn, l->addr);
+ /* At this point, "val" has the value of the combined HI/LO
+ pair. If the low order 16 bits (which will be used for
+ the LO16 insn) are negative, then we will need an
+ adjustment for the high order 16 bits. */
+ val += 0x8000;
+ val = (val >> 16) & 0xffff;
+
+ insn &= ~ (bfd_vma) 0xffff;
+ insn |= val;
+ bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
{
{
for (i = 0; i < count; i++, sym++)
{
- register CONST char *name;
+ register const char *name;
name = bfd_asymbol_name (*sym);
if (*name == '_' && strcmp (name, "_gp") == 0)
|| (symbol->flags & BSF_SECTION_SYM) != 0)
val += relocation - gp;
- bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+ bfd_put_32 (abfd, (bfd_vma) val, (bfd_byte *) data + reloc_entry->address);
if (relocateable)
reloc_entry->address += input_section->output_offset;
reloc32 = *reloc_entry;
if (bfd_big_endian (abfd))
reloc32.address += 4;
- reloc32.howto = &elf_mips_howto_table[R_MIPS_32];
+ reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
output_bfd, error_message);
addr = reloc_entry->address;
if (bfd_little_endian (abfd))
addr += 4;
- bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
+ bfd_put_32 (abfd, (bfd_vma) val, (bfd_byte *) data + addr);
return r;
}
/* Stuff the current addend back as a 32 bit value, do the usual
relocation, and then clean up. */
bfd_put_32 (abfd,
- (((extend & 0x1f) << 11)
- | (extend & 0x7e0)
- | (insn & 0x1f)),
+ (bfd_vma) (((extend & 0x1f) << 11)
+ | (extend & 0x7e0)
+ | (insn & 0x1f)),
(bfd_byte *) data + reloc_entry->address);
ret = gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
bfd_put_16 (abfd,
- ((extend & 0xf800)
- | ((final >> 11) & 0x1f)
- | (final & 0x7e0)),
+ (bfd_vma) ((extend & 0xf800)
+ | ((final >> 11) & 0x1f)
+ | (final & 0x7e0)),
(bfd_byte *) data + reloc_entry->address);
bfd_put_16 (abfd,
- ((insn & 0xffe0)
- | (final & 0x1f)),
+ (bfd_vma) ((insn & 0xffe0)
+ | (final & 0x1f)),
(bfd_byte *) data + reloc_entry->address + 2);
return ret;
/* Return the MACH for a MIPS e_flags value. */
-static INLINE int
+static INLINE unsigned long
elf_mips_mach (flags)
flagword flags;
{
case E_MIPS_MACH_4650:
return bfd_mach_mips4650;
- case E_MIPS_MACH_MIPS32_4K:
- return bfd_mach_mips32_4k;
-
case E_MIPS_MACH_SB1:
return bfd_mach_mips_sb1;
break;
case E_MIPS_ARCH_32:
- return bfd_mach_mips32;
+ return bfd_mach_mipsisa32;
break;
case E_MIPS_ARCH_64:
- return bfd_mach_mips64;
+ return bfd_mach_mipsisa64;
break;
}
}
{
flagword flags;
- if (ABI_N32_P (abfd))
- return "N32";
- else if (ABI_64_P (abfd))
- return "64";
-
flags = elf_elfheader (abfd)->e_flags;
switch (flags & EF_MIPS_ABI)
{
case 0:
- return "none";
+ if (ABI_N32_P (abfd))
+ return "N32";
+ else if (ABI_64_P (abfd))
+ return "64";
+ else
+ return "none";
case E_MIPS_ABI_O32:
return "O32";
case E_MIPS_ABI_O64:
enum elf_mips_reloc_type elf_reloc_val;
};
-static CONST struct elf_reloc_map mips_reloc_map[] =
+static const struct elf_reloc_map mips_reloc_map[] =
{
{ BFD_RELOC_NONE, R_MIPS_NONE, },
{ BFD_RELOC_16, R_MIPS_16 },
{ BFD_RELOC_MIPS_JMP, R_MIPS_26 },
{ BFD_RELOC_HI16_S, R_MIPS_HI16 },
{ BFD_RELOC_LO16, R_MIPS_LO16 },
- { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
+ { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
{ BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
{ BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
{ BFD_RELOC_16_PCREL, R_MIPS_PC16 },
{ BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
- { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
+ { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
{ 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 },
for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
{
if (mips_reloc_map[i].bfd_reloc_val == code)
- return &elf_mips_howto_table[(int) mips_reloc_map[i].elf_reloc_val];
+ return &elf_mips_howto_table_rel[(int) mips_reloc_map[i].elf_reloc_val];
}
switch (code)
Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
size of addresses on this architecture. */
if (bfd_arch_bits_per_address (abfd) == 32)
- return &elf_mips_howto_table[(int) R_MIPS_32];
+ return &elf_mips_howto_table_rel[(int) R_MIPS_32];
else
return &elf_mips_ctor64_howto;
default:
BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
- return &elf_mips_howto_table[r_type];
+ return &elf_mips_howto_table_rel[r_type];
break;
}
}
const Elf32_External_RegInfo *ex;
Elf32_RegInfo *in;
{
- in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
- in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
- in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
- in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
- in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
- in->ri_gp_value = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gp_value);
+ in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
+ in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
+ in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
+ in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
+ in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
+ in->ri_gp_value = H_GET_32 (abfd, ex->ri_gp_value);
}
void
const Elf32_RegInfo *in;
Elf32_External_RegInfo *ex;
{
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
- (bfd_byte *) ex->ri_gprmask);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
- (bfd_byte *) ex->ri_cprmask[0]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
- (bfd_byte *) ex->ri_cprmask[1]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
- (bfd_byte *) ex->ri_cprmask[2]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
- (bfd_byte *) ex->ri_cprmask[3]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_gp_value,
- (bfd_byte *) ex->ri_gp_value);
+ H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
+ H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
+ H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
+ H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
+ H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
+ H_PUT_32 (abfd, in->ri_gp_value, ex->ri_gp_value);
}
/* In the 64 bit ABI, the .MIPS.options section holds register
const Elf64_External_RegInfo *ex;
Elf64_Internal_RegInfo *in;
{
- in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
- in->ri_pad = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_pad);
- in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
- in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
- in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
- in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
- in->ri_gp_value = bfd_h_get_64 (abfd, (bfd_byte *) ex->ri_gp_value);
+ in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
+ in->ri_pad = H_GET_32 (abfd, ex->ri_pad);
+ in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
+ in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
+ in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
+ in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
+ in->ri_gp_value = H_GET_64 (abfd, ex->ri_gp_value);
}
void
const Elf64_Internal_RegInfo *in;
Elf64_External_RegInfo *ex;
{
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
- (bfd_byte *) ex->ri_gprmask);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_pad,
- (bfd_byte *) ex->ri_pad);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
- (bfd_byte *) ex->ri_cprmask[0]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
- (bfd_byte *) ex->ri_cprmask[1]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
- (bfd_byte *) ex->ri_cprmask[2]);
- bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
- (bfd_byte *) ex->ri_cprmask[3]);
- bfd_h_put_64 (abfd, (bfd_vma) in->ri_gp_value,
- (bfd_byte *) ex->ri_gp_value);
+ H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
+ H_PUT_32 (abfd, in->ri_pad, ex->ri_pad);
+ H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
+ H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
+ H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
+ H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
+ H_PUT_64 (abfd, in->ri_gp_value, ex->ri_gp_value);
}
/* Swap an entry in a .gptab section. Note that these routines rely
const Elf32_External_gptab *ex;
Elf32_gptab *in;
{
- in->gt_entry.gt_g_value = bfd_h_get_32 (abfd, ex->gt_entry.gt_g_value);
- in->gt_entry.gt_bytes = bfd_h_get_32 (abfd, ex->gt_entry.gt_bytes);
+ in->gt_entry.gt_g_value = H_GET_32 (abfd, ex->gt_entry.gt_g_value);
+ in->gt_entry.gt_bytes = H_GET_32 (abfd, ex->gt_entry.gt_bytes);
}
static void
const Elf32_gptab *in;
Elf32_External_gptab *ex;
{
- bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_g_value,
- ex->gt_entry.gt_g_value);
- bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_bytes,
- ex->gt_entry.gt_bytes);
+ H_PUT_32 (abfd, in->gt_entry.gt_g_value, ex->gt_entry.gt_g_value);
+ H_PUT_32 (abfd, in->gt_entry.gt_bytes, ex->gt_entry.gt_bytes);
}
static void
const Elf32_compact_rel *in;
Elf32_External_compact_rel *ex;
{
- bfd_h_put_32 (abfd, (bfd_vma) in->id1, ex->id1);
- bfd_h_put_32 (abfd, (bfd_vma) in->num, ex->num);
- bfd_h_put_32 (abfd, (bfd_vma) in->id2, ex->id2);
- bfd_h_put_32 (abfd, (bfd_vma) in->offset, ex->offset);
- bfd_h_put_32 (abfd, (bfd_vma) in->reserved0, ex->reserved0);
- bfd_h_put_32 (abfd, (bfd_vma) in->reserved1, ex->reserved1);
+ H_PUT_32 (abfd, in->id1, ex->id1);
+ H_PUT_32 (abfd, in->num, ex->num);
+ H_PUT_32 (abfd, in->id2, ex->id2);
+ H_PUT_32 (abfd, in->offset, ex->offset);
+ H_PUT_32 (abfd, in->reserved0, ex->reserved0);
+ H_PUT_32 (abfd, in->reserved1, ex->reserved1);
}
static void
| ((in->rtype & CRINFO_RTYPE) << CRINFO_RTYPE_SH)
| ((in->dist2to & CRINFO_DIST2TO) << CRINFO_DIST2TO_SH)
| ((in->relvaddr & CRINFO_RELVADDR) << CRINFO_RELVADDR_SH));
- bfd_h_put_32 (abfd, (bfd_vma) l, ex->info);
- bfd_h_put_32 (abfd, (bfd_vma) in->konst, ex->konst);
- bfd_h_put_32 (abfd, (bfd_vma) in->vaddr, ex->vaddr);
+ H_PUT_32 (abfd, l, ex->info);
+ H_PUT_32 (abfd, in->konst, ex->konst);
+ H_PUT_32 (abfd, in->vaddr, ex->vaddr);
}
/* Swap in an options header. */
const Elf_External_Options *ex;
Elf_Internal_Options *in;
{
- in->kind = bfd_h_get_8 (abfd, ex->kind);
- in->size = bfd_h_get_8 (abfd, ex->size);
- in->section = bfd_h_get_16 (abfd, ex->section);
- in->info = bfd_h_get_32 (abfd, ex->info);
+ in->kind = H_GET_8 (abfd, ex->kind);
+ in->size = H_GET_8 (abfd, ex->size);
+ in->section = H_GET_16 (abfd, ex->section);
+ in->info = H_GET_32 (abfd, ex->info);
}
/* Swap out an options header. */
const Elf_Internal_Options *in;
Elf_External_Options *ex;
{
- bfd_h_put_8 (abfd, in->kind, ex->kind);
- bfd_h_put_8 (abfd, in->size, ex->size);
- bfd_h_put_16 (abfd, in->section, ex->section);
- bfd_h_put_32 (abfd, in->info, ex->info);
+ H_PUT_8 (abfd, in->kind, ex->kind);
+ H_PUT_8 (abfd, in->size, ex->size);
+ H_PUT_16 (abfd, in->section, ex->section);
+ H_PUT_32 (abfd, in->info, ex->info);
}
#if 0
/* Swap in an MSYM entry. */
const Elf32_External_Msym *ex;
Elf32_Internal_Msym *in;
{
- in->ms_hash_value = bfd_h_get_32 (abfd, ex->ms_hash_value);
- in->ms_info = bfd_h_get_32 (abfd, ex->ms_info);
+ in->ms_hash_value = H_GET_32 (abfd, ex->ms_hash_value);
+ in->ms_info = H_GET_32 (abfd, ex->ms_info);
}
#endif
/* Swap out an MSYM entry. */
const Elf32_Internal_Msym *in;
Elf32_External_Msym *ex;
{
- bfd_h_put_32 (abfd, in->ms_hash_value, ex->ms_hash_value);
- bfd_h_put_32 (abfd, in->ms_info, ex->ms_info);
+ H_PUT_32 (abfd, in->ms_hash_value, ex->ms_hash_value);
+ H_PUT_32 (abfd, in->ms_info, ex->ms_info);
}
\f
/* Determine whether a symbol is global for the purposes of splitting
bfd *abfd ATTRIBUTE_UNUSED;
asymbol *sym;
{
- if (SGI_COMPAT(abfd))
- return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
+ if (SGI_COMPAT (abfd))
+ return (sym->flags & BSF_SECTION_SYM) == 0;
else
return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
- || bfd_is_und_section (bfd_get_section (sym))
- || bfd_is_com_section (bfd_get_section (sym)));
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)));
}
\f
/* Set the right machine number for a MIPS ELF file. This is used for
_bfd_mips_elf_object_p (abfd)
bfd *abfd;
{
- /* Irix 5 and 6 is broken. Object file symbol tables are not always
+ /* Irix 5 and 6 are broken. Object file symbol tables are not always
sorted correctly such that local symbols precede global symbols,
and the sh_info field in the symbol table is not always right. */
- elf_bad_symtab (abfd) = true;
+ if (SGI_COMPAT(abfd))
+ elf_bad_symtab (abfd) = true;
bfd_default_set_arch_mach (abfd, bfd_arch_mips,
elf_mips_mach (elf_elfheader (abfd)->e_flags));
case bfd_mach_mips4000:
case bfd_mach_mips4300:
+ case bfd_mach_mips4400:
+ case bfd_mach_mips4600:
val = E_MIPS_ARCH_3;
break;
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650;
break;
+ case bfd_mach_mips5000:
case bfd_mach_mips8000:
+ case bfd_mach_mips10000:
+ case bfd_mach_mips12000:
val = E_MIPS_ARCH_4;
break;
- case bfd_mach_mips32:
- val = E_MIPS_ARCH_32;
- break;
-
- case bfd_mach_mips32_4k:
- val = E_MIPS_ARCH_32 | E_MIPS_MACH_MIPS32_4K;
- break;
-
case bfd_mach_mips5:
val = E_MIPS_ARCH_5;
break;
- case bfd_mach_mips64:
- val = E_MIPS_ARCH_64;
- break;
-
case bfd_mach_mips_sb1:
val = E_MIPS_ARCH_64 | E_MIPS_MACH_SB1;
break;
+
+ case bfd_mach_mipsisa32:
+ val = E_MIPS_ARCH_32;
+ break;
+
+ case bfd_mach_mipsisa64:
+ val = E_MIPS_ARCH_64;
}
elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
/* 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_elfheader (abfd)->e_shnum;
+ i < elf_numsections (abfd);
i++, hdrpp++)
{
switch ((*hdrpp)->sh_type)
return true;
}
-/* Copy backend specific data from one object module to another */
-
-boolean
-_bfd_mips_elf_copy_private_bfd_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
-{
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
- || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return true;
-
- BFD_ASSERT (!elf_flags_init (obfd)
- || (elf_elfheader (obfd)->e_flags
- == elf_elfheader (ibfd)->e_flags));
-
- elf_gp (obfd) = elf_gp (ibfd);
- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
- elf_flags_init (obfd) = true;
- return true;
-}
-
/* Merge backend specific data from an object file to the output
object file when linking. */
old_flags &= ~EF_MIPS_PIC;
(*_bfd_error_handler)
(_("%s: linking PIC files with non-PIC files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
ok = false;
}
old_flags &= ~EF_MIPS_CPIC;
(*_bfd_error_handler)
(_("%s: linking abicalls files with non-abicalls files"),
- bfd_get_filename (ibfd));
+ bfd_archive_filename (ibfd));
ok = false;
}
{
(*_bfd_error_handler)
(_("%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"),
- bfd_get_filename (ibfd), new_isa, old_isa);
+ bfd_archive_filename (ibfd), new_isa, old_isa);
ok = false;
}
}
{
(*_bfd_error_handler)
(_("%s: ISA mismatch (%d) with previous modules (%d)"),
- bfd_get_filename (ibfd),
+ bfd_archive_filename (ibfd),
elf_mips_mach (new_flags),
elf_mips_mach (old_flags));
ok = false;
{
(*_bfd_error_handler)
(_("%s: ABI mismatch: linking %s module with previous %s modules"),
- bfd_get_filename (ibfd),
+ bfd_archive_filename (ibfd),
elf_mips_abi_name (ibfd),
elf_mips_abi_name (obfd));
ok = false;
{
(*_bfd_error_handler)
(_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
- bfd_get_filename (ibfd), (unsigned long) new_flags,
+ bfd_archive_filename (ibfd), (unsigned long) new_flags,
(unsigned long) old_flags);
ok = false;
}
Elf32_RegInfo s;
if (! bfd_get_section_contents (abfd, hdr->bfd_section, (PTR) &ext,
- (file_ptr) 0, sizeof ext))
+ (file_ptr) 0,
+ (bfd_size_type) sizeof ext))
return false;
bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
elf_gp (abfd) = s.ri_gp_value;
if ((sec->flags & SEC_RELOC) != 0)
{
struct bfd_elf_section_data *esd;
+ bfd_size_type amt = sizeof (Elf_Internal_Shdr);
esd = elf_section_data (sec);
BFD_ASSERT (esd->rel_hdr2 == NULL);
- esd->rel_hdr2
- = (Elf_Internal_Shdr *) bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
+ esd->rel_hdr2 = (Elf_Internal_Shdr *) bfd_zalloc (abfd, amt);
if (!esd->rel_hdr2)
return false;
_bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
the .scommon section. */
boolean
-_bfd_mips_elf_section_from_bfd_section (abfd, hdr, sec, retval)
- bfd *abfd;
- Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED;
+_bfd_mips_elf_section_from_bfd_section (abfd, sec, retval)
+ bfd *abfd ATTRIBUTE_UNUSED;
asection *sec;
int *retval;
{
if (elf_section_data (section) == NULL)
{
- section->used_by_bfd =
- (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data));
+ bfd_size_type amt = sizeof (struct bfd_elf_section_data);
+ section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
if (elf_section_data (section) == NULL)
return false;
}
elf_section_data (section)->tdata = (PTR) c;
}
- memcpy (c + offset, location, count);
+ memcpy (c + offset, location, (size_t) count);
}
return _bfd_elf_set_section_contents (abfd, section, location, offset,
if (bfd_seek (abfd,
hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4,
- SEEK_SET) == -1)
+ SEEK_SET) != 0)
return false;
- bfd_h_put_32 (abfd, (bfd_vma) elf_gp (abfd), buf);
- if (bfd_write (buf, (bfd_size_type) 1, (bfd_size_type) 4, abfd) != 4)
+ H_PUT_32 (abfd, elf_gp (abfd), buf);
+ if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
return false;
}
+ (l - contents)
+ sizeof (Elf_External_Options)
+ (sizeof (Elf64_External_RegInfo) - 8)),
- SEEK_SET) == -1)
+ SEEK_SET) != 0)
return false;
- bfd_h_put_64 (abfd, elf_gp (abfd), buf);
- if (bfd_write (buf, 1, 8, abfd) != 8)
+ H_PUT_64 (abfd, elf_gp (abfd), buf);
+ if (bfd_bwrite (buf, (bfd_size_type) 8, abfd) != 8)
return false;
}
else if (intopt.kind == ODK_REGINFO)
+ (l - contents)
+ sizeof (Elf_External_Options)
+ (sizeof (Elf32_External_RegInfo) - 4)),
- SEEK_SET) == -1)
+ SEEK_SET) != 0)
return false;
- bfd_h_put_32 (abfd, elf_gp (abfd), buf);
- if (bfd_write (buf, 1, 4, abfd) != 4)
+ H_PUT_32 (abfd, elf_gp (abfd), buf);
+ if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
return false;
}
l += intopt.size;
{
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. */
break;
if (m == NULL)
{
- m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+ amt = sizeof *m;
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
return false;
table. */
if (IRIX_COMPAT (abfd) == ict_irix6)
{
- asection *s;
-
for (s = abfd->sections; s; s = s->next)
if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
break;
if ((*pm)->p_type == PT_PHDR)
break;
- options_segment = bfd_zalloc (abfd,
- sizeof (struct elf_segment_map));
+ 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;
break;
if (m == NULL)
{
- m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+ amt = sizeof *m;
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL)
return false;
if ((*pm)->p_type == PT_DYNAMIC)
break;
m = *pm;
- if (IRIX_COMPAT (abfd) == ict_none)
+ 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
0 ? s->_cooked_size : s->_raw_size)) <= high))
++c;
- n = ((struct elf_segment_map *)
- bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *)));
+ amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *);
+ n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (n == NULL)
return false;
*n = *m;
const RPDR *in;
struct rpdr_ext *ex;
{
- /* ecoff_put_off was defined in ecoffswap.h. */
- ecoff_put_off (abfd, in->adr, (bfd_byte *) ex->p_adr);
- bfd_h_put_32 (abfd, in->regmask, (bfd_byte *) ex->p_regmask);
- bfd_h_put_32 (abfd, in->regoffset, (bfd_byte *) ex->p_regoffset);
- bfd_h_put_32 (abfd, in->fregmask, (bfd_byte *) ex->p_fregmask);
- bfd_h_put_32 (abfd, in->fregoffset, (bfd_byte *) ex->p_fregoffset);
- bfd_h_put_32 (abfd, in->frameoffset, (bfd_byte *) ex->p_frameoffset);
-
- bfd_h_put_16 (abfd, in->framereg, (bfd_byte *) ex->p_framereg);
- bfd_h_put_16 (abfd, in->pcreg, (bfd_byte *) ex->p_pcreg);
-
- bfd_h_put_32 (abfd, in->irpss, (bfd_byte *) ex->p_irpss);
+ /* ECOFF_PUT_OFF was defined in ecoffswap.h. */
+ ECOFF_PUT_OFF (abfd, in->adr, ex->p_adr);
+ H_PUT_32 (abfd, in->regmask, ex->p_regmask);
+ H_PUT_32 (abfd, in->regoffset, ex->p_regoffset);
+ H_PUT_32 (abfd, in->fregmask, ex->p_fregmask);
+ H_PUT_32 (abfd, in->fregoffset, ex->p_fregoffset);
+ H_PUT_32 (abfd, in->frameoffset, ex->p_frameoffset);
+
+ H_PUT_16 (abfd, in->framereg, ex->p_framereg);
+ H_PUT_16 (abfd, in->pcreg, ex->p_pcreg);
+
+ H_PUT_32 (abfd, in->irpss, ex->p_irpss);
#if 0 /* FIXME */
- ecoff_put_off (abfd, in->exception_info, (bfd_byte *) ex->p_exception_info);
+ ECOFF_PUT_OFF (abfd, in->exception_info, ex->p_exception_info);
#endif
}
\f
swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
memset (debug, 0, sizeof (*debug));
- ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size);
+ ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
if (ext_hdr == NULL && swap->external_hdr_size != 0)
goto error_return;
debug->ptr = NULL; \
else \
{ \
- debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \
+ bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
+ debug->ptr = (type) bfd_malloc (amt); \
if (debug->ptr == NULL) \
goto error_return; \
if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
- || (bfd_read (debug->ptr, size, symhdr->count, \
- abfd) != size * symhdr->count)) \
+ || bfd_bread (debug->ptr, amt, abfd) != amt) \
goto error_return; \
}
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
filename_ptr, functionname_ptr,
line_ptr,
- ABI_64_P (abfd) ? 8 : 0,
+ (unsigned) (ABI_64_P (abfd) ? 8 : 0),
&elf_tdata (abfd)->dwarf2_find_line_info))
return true;
char *fraw_src;
char *fraw_end;
struct fdr *fdr_ptr;
+ bfd_size_type amt = sizeof (struct mips_elf_find_line);
- fi = ((struct mips_elf_find_line *)
- bfd_zalloc (abfd, sizeof (struct mips_elf_find_line)));
+ fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
if (fi == NULL)
{
msec->flags = origflags;
}
/* Swap in the FDR information. */
- fi->d.fdr = ((struct fdr *)
- bfd_alloc (abfd,
- (fi->d.symbolic_header.ifdMax *
- sizeof (struct fdr))));
+ amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
+ fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
if (fi->d.fdr == NULL)
{
msec->flags = origflags;
not been set. -1 means there is no associated ifd. */
ret->esym.ifd = -2;
ret->possibly_dynamic_relocs = 0;
+ ret->readonly_reloc = false;
ret->min_dyn_reloc_index = 0;
ret->no_fn_stub = false;
ret->fn_stub = NULL;
return (struct bfd_hash_entry *) ret;
}
-void
-_bfd_mips_elf_hide_symbol (info, h)
+static void
+_bfd_mips_elf_hide_symbol (info, entry)
struct bfd_link_info *info;
- struct mips_elf_link_hash_entry *h;
+ struct elf_link_hash_entry *entry;
{
bfd *dynobj;
asection *got;
struct mips_got_info *g;
+ struct mips_elf_link_hash_entry *h;
+ h = (struct mips_elf_link_hash_entry *) entry;
dynobj = elf_hash_table (info)->dynobj;
got = bfd_get_section_by_name (dynobj, ".got");
g = (struct mips_got_info *) elf_section_data (got)->tdata;
bfd *abfd;
{
struct mips_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct mips_elf_link_hash_table);
- ret = ((struct mips_elf_link_hash_table *)
- bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table)));
+ ret = (struct mips_elf_link_hash_table *) bfd_alloc (abfd, amt);
if (ret == (struct mips_elf_link_hash_table *) NULL)
return NULL;
{
asymbol *elf_text_symbol;
asection *elf_text_section;
+ bfd_size_type amt = sizeof (asection);
- elf_text_section = bfd_zalloc (abfd, sizeof (asection));
+ elf_text_section = bfd_zalloc (abfd, amt);
if (elf_text_section == NULL)
return false;
- elf_text_symbol = bfd_zalloc (abfd, sizeof (asymbol));
+ amt = sizeof (asymbol);
+ elf_text_symbol = bfd_zalloc (abfd, amt);
if (elf_text_symbol == NULL)
return false;
{
asymbol *elf_data_symbol;
asection *elf_data_section;
+ bfd_size_type amt = sizeof (asection);
- elf_data_section = bfd_zalloc (abfd, sizeof (asection));
+ elf_data_section = bfd_zalloc (abfd, amt);
if (elf_data_section == NULL)
return false;
- elf_data_symbol = bfd_zalloc (abfd, sizeof (asymbol));
+ amt = sizeof (asymbol);
+ elf_data_symbol = bfd_zalloc (abfd, amt);
if (elf_data_symbol == NULL)
return false;
struct sym_ext *esym;
char *ss, **sv;
char *str;
- unsigned long size, count;
+ bfd_size_type size;
+ bfd_size_type count;
unsigned long sindex;
unsigned long i;
PDR pdr;
if (rpdr == NULL)
goto error_return;
- sv = (char **) bfd_malloc (sizeof (char *) * count);
+ size = sizeof (char *);
+ sv = (char **) bfd_malloc (size * count);
if (sv == NULL)
goto error_return;
goto error_return;
count = hdr->ipdMax;
- for (i = 0; i < count; i++, rp++)
+ for (i = 0; i < (unsigned long) count; i++, rp++)
{
(*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr);
(*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym);
strcpy (str, sv[i]);
str += strlen (sv[i]) + 1;
}
- ecoff_put_off (abfd, (bfd_vma) -1, (bfd_byte *) (erp + count)->p_adr);
+ ECOFF_PUT_OFF (abfd, -1, (erp + count)->p_adr);
/* Set the size and contents of .rtproc section. */
s->_raw_size = size;
PTR mdebug_handle = NULL;
asection *s;
EXTR esym;
- bfd_vma last;
unsigned int i;
- static const char * const name[] =
+ bfd_size_type amt;
+
+ static const char * const secname[] =
{
".text", ".init", ".fini", ".data",
".rodata", ".sdata", ".sbss", ".bss"
if (p->type == bfd_indirect_link_order)
p->u.indirect.section->flags &= ~SEC_HAS_CONTENTS;
(*secpp)->link_order_head = NULL;
- *secpp = (*secpp)->next;
+ bfd_section_list_remove (abfd, secpp);
--abfd->section_count;
break;
if (! bfd_get_section_contents (input_bfd, input_section,
(PTR) &ext,
(file_ptr) 0,
- sizeof ext))
+ (bfd_size_type) sizeof ext))
return false;
bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);
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
esym.asym.reserved = 0;
esym.asym.index = indexNil;
last = 0;
- for (i = 0; i < 8; i++)
+ for (i = 0; i < sizeof (secname) / sizeof (secname[0]); i++)
{
esym.asym.sc = sc[i];
- s = bfd_get_section_by_name (abfd, name[i]);
+ s = bfd_get_section_by_name (abfd, secname[i]);
if (s != NULL)
{
esym.asym.value = s->vma;
else
esym.asym.value = last;
if (!bfd_ecoff_debug_one_external (abfd, &debug, swap,
- name[i], &esym))
+ secname[i], &esym))
return false;
}
unsigned int c;
Elf32_gptab *tab;
Elf32_External_gptab *ext_tab;
- unsigned int i;
+ unsigned int j;
/* The .gptab.sdata and .gptab.sbss sections hold
information describing how the small data area would
not used in executables files. */
if (! info->relocateable)
{
- asection **secpp;
-
for (p = o->link_order_head;
p != (struct bfd_link_order *) NULL;
p = p->next)
*secpp != o;
secpp = &(*secpp)->next)
;
- *secpp = (*secpp)->next;
+ bfd_section_list_remove (abfd, secpp);
--abfd->section_count;
continue;
/* Set up the first entry. */
c = 1;
- tab = (Elf32_gptab *) bfd_malloc (c * sizeof (Elf32_gptab));
+ amt = c * sizeof (Elf32_gptab);
+ tab = (Elf32_gptab *) bfd_malloc (amt);
if (tab == NULL)
return false;
tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
if (! (bfd_get_section_contents
(input_bfd, input_section, (PTR) &ext_gptab,
- gpentry, sizeof (Elf32_External_gptab))))
+ (file_ptr) gpentry,
+ (bfd_size_type) sizeof (Elf32_External_gptab))))
{
free (tab);
return false;
unsigned int max;
/* We need a new table entry. */
- new_tab = ((Elf32_gptab *)
- bfd_realloc ((PTR) tab,
- (c + 1) * sizeof (Elf32_gptab)));
+ amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab);
+ new_tab = (Elf32_gptab *) bfd_realloc ((PTR) tab, amt);
if (new_tab == NULL)
{
free (tab);
qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare);
/* Swap out the table. */
- ext_tab = ((Elf32_External_gptab *)
- bfd_alloc (abfd, c * sizeof (Elf32_External_gptab)));
+ amt = (bfd_size_type) c * sizeof (Elf32_External_gptab);
+ ext_tab = (Elf32_External_gptab *) bfd_alloc (abfd, amt);
if (ext_tab == NULL)
{
free (tab);
return false;
}
- for (i = 0; i < c; i++)
- bfd_mips_elf32_swap_gptab_out (abfd, tab + i, ext_tab + i);
+ for (j = 0; j < c; j++)
+ bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j);
free (tab);
o->_raw_size = c * sizeof (Elf32_External_gptab);
bfd_mips_elf32_swap_reginfo_out (abfd, ®info, &ext);
if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext,
- (file_ptr) 0, sizeof ext))
+ (file_ptr) 0, (bfd_size_type) sizeof ext))
return false;
}
&& !bfd_elf32_link_record_dynamic_symbol (info, h))
return false;
- /* If we've already marked this entry as need GOT space, we don't
+ /* If we've already marked this entry as needing GOT space, we don't
need to do it again. */
- if (h->got.offset != (bfd_vma) - 1)
+ if (h->got.offset != (bfd_vma) -1)
return true;
/* By setting this to a value other than -1, we are indicating that
- there needs to be a GOT entry for H. */
- h->got.offset = 0;
+ there needs to be a GOT entry for H. Avoid using zero, as the
+ generic ELF copy_indirect_symbol tests for <= 0. */
+ h->got.offset = 1;
return true;
}
if (h->root.dynindx == -1)
return true;
- if (h->root.got.offset != 0)
+ if (h->root.got.offset != 1)
h->root.dynindx = hsd->max_non_got_dynindx++;
else
{
mips_elf_sort_hash_table_f,
&hsd);
- /* There shoud have been enough room in the symbol table to
+ /* There should have been enough room in the symbol table to
accomodate both the GOT and non-GOT symbols. */
BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
MIPS_ELF_REL_DYN_SECTION_NAME (output_bfd));
BFD_ASSERT (sreloc != NULL);
BFD_ASSERT (sreloc->contents != NULL);
+ BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
+ < sreloc->_raw_size);
skip = false;
-
- /* We begin by assuming that the offset for the dynamic relocation
- is the same as for the original relocation. We'll adjust this
- later to reflect the correct output offsets. */
- if (elf_section_data (input_section)->stab_info == NULL)
- outrel.r_offset = rel->r_offset;
- else
- {
- /* Except that in a stab section things are more complex.
- Because we compress stab information, the offset given in the
- relocation may not be the one we want; we must let the stabs
- machinery tell us the offset. */
- outrel.r_offset
- = (_bfd_stab_section_offset
- (output_bfd, &elf_hash_table (info)->stab_info,
- input_section,
- &elf_section_data (input_section)->stab_info,
- rel->r_offset));
- /* If we didn't need the relocation at all, this value will be
- -1. */
- if (outrel.r_offset == (bfd_vma) -1)
- skip = true;
- }
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = true;
/* If we've decided to skip this relocation, just output an empty
record. Note that R_MIPS_NONE == 0, so that this call to memset
and check to see if they exist by looking at their
addresses. */
symbol = 0;
- else if (info->shared && !info->symbolic && !info->no_undefined
+ else if (info->shared
+ && (!info->symbolic || info->allow_shlib_undefined)
+ && !info->no_undefined
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
symbol = 0;
else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 ||
/* Calls from 16-bit code to 32-bit code and vice versa require the
special jalx instruction. */
*require_jalxp = (!info->relocateable
- && ((r_type == R_MIPS16_26) != target_is_16_bit_code_p));
+ && (((r_type == R_MIPS16_26) != target_is_16_bit_code_p
+ || ((r_type == R_MIPS_26) == target_is_16_bit_code_p))));
local_p = mips_elf_local_relocation_p (input_bfd, relocation,
local_sections, true);
case R_MIPS_HI16:
case R_MIPS_LO16:
+ case R_MIPS16_GPREL:
case R_MIPS_GPREL16:
case R_MIPS_GPREL32:
case R_MIPS_LITERAL:
if ((info->shared
|| (elf_hash_table (info)->dynamic_sections_created
&& h != NULL
- && ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
- != 0)))
+ && ((h->root.elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
+ && ((h->root.elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+ && r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0)
{
/* If we're creating a shared library, or this relocation is
case R_MIPS_PC16:
value = mips_elf_sign_extend (addend, 16) + symbol - p;
- value = (bfd_vma) ((bfd_signed_vma) value / 4);
overflowed_p = mips_elf_overflow_p (value, 16);
+ value = (bfd_vma) ((bfd_signed_vma) value / 4);
break;
case R_MIPS_GOT_HI16:
bfd_byte *location = contents + relocation->r_offset;
/* Obtain the bytes. */
- x = bfd_get (8 * bfd_get_reloc_size (howto), input_bfd, location);
+ x = bfd_get (((bfd_vma)(8 * bfd_get_reloc_size (howto))), input_bfd, location);
if ((ELF32_R_TYPE (relocation->r_info) == R_MIPS16_26
|| ELF32_R_TYPE (relocation->r_info) == R_MIPS16_GPREL)
{
(*_bfd_error_handler)
(_("%s: %s+0x%lx: jump to stub routine which is not jal"),
- bfd_get_filename (input_bfd),
+ bfd_archive_filename (input_bfd),
input_section->name,
(unsigned long) relocation->r_offset);
bfd_set_error (bfd_error_bad_value);
/* True if the relocation is a RELA relocation, rather than a
REL relocation. */
boolean rela_relocation_p = true;
- int r_type = ELF32_R_TYPE (rel->r_info);
+ unsigned int r_type = ELF32_R_TYPE (rel->r_info);
const char * msg = (const char *) NULL;
/* Find the relocation howto for this relocation. */
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 = elf_mips_howto_table + R_MIPS_32;
+ howto = elf_mips_howto_table_rel + R_MIPS_32;
/* On big-endian systems, we need to lie about the position
of the reloc. */
REL_HDR is read before its REL_HDR2. */
rel_hdr = &elf_section_data (input_section)->rel_hdr;
if ((size_t) (rel - relocs)
- >= (rel_hdr->sh_size / rel_hdr->sh_entsize
- * bed->s->int_rels_per_ext_rel))
+ >= (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_vma l;
const Elf_Internal_Rela *lo16_relocation;
reloc_howto_type *lo16_howto;
- int lo;
+ unsigned int lo;
/* The combined value is the sum of the HI16 addend,
left-shifted by sixteen bits, and the LO16
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 (!mips_elf_perform_relocation (info, howto, rel, addend,
- input_bfd, input_section,
+ input_bfd, input_section,
contents, false))
return false;
}
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;
{
s = bfd_make_section (abfd, ".rld_map");
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags & ~SEC_READONLY)
+ || ! bfd_set_section_flags (abfd, s, flags &~ (flagword) SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s,
MIPS_ELF_LOG_FILE_ALIGN (abfd)))
return false;
register asection *s;
struct elf_link_hash_entry *h;
struct mips_got_info *g;
+ bfd_size_type amt;
/* This function may be called more than once. */
if (mips_elf_got_section (abfd))
/* The first several global offset table entries are reserved. */
s->_raw_size = MIPS_RESERVED_GOTNO * MIPS_ELF_GOT_SIZE (abfd);
- g = (struct mips_got_info *) bfd_alloc (abfd,
- sizeof (struct mips_got_info));
+ amt = sizeof (struct mips_got_info);
+ g = (struct mips_got_info *) bfd_alloc (abfd, amt);
if (g == NULL)
return false;
g->global_gotsym = NULL;
g->assigned_gotno = MIPS_RESERVED_GOTNO;
if (elf_section_data (s) == NULL)
{
- s->used_by_bfd =
- (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data));
+ amt = sizeof (struct bfd_elf_section_data);
+ s->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
if (elf_section_data (s) == NULL)
return false;
}
{
unsigned long symcount;
asection **n;
+ bfd_size_type amt;
if (elf_bad_symtab (abfd))
- symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
+ symcount = NUM_SHDR_ENTRIES (symtab_hdr);
else
symcount = symtab_hdr->sh_info;
- n = (asection **) bfd_zalloc (abfd,
- symcount * sizeof (asection *));
+ amt = symcount * sizeof (asection *);
+ n = (asection **) bfd_zalloc (abfd, amt);
if (n == NULL)
return false;
elf_tdata (abfd)->local_stubs = n;
for (rel = relocs; rel < rel_end; ++rel)
{
unsigned long r_symndx;
- int r_type;
+ unsigned int r_type;
struct elf_link_hash_entry *h;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < extsymoff)
h = NULL;
- else if (r_symndx >= extsymoff + (symtab_hdr->sh_size / symtab_hdr->sh_entsize))
+ else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
{
(*_bfd_error_handler)
- (_("Malformed reloc detected for section %s"), name);
+ (_("%s: Malformed reloc detected for section %s"),
+ bfd_archive_filename (abfd), name);
bfd_set_error (bfd_error_bad_value);
return false;
}
{
(*_bfd_error_handler)
(_("%s: CALL16 reloc at 0x%lx not against global symbol"),
- bfd_get_filename (abfd), (unsigned long) rel->r_offset);
+ bfd_archive_filename (abfd), (unsigned long) rel->r_offset);
bfd_set_error (bfd_error_bad_value);
return false;
}
{
if (sreloc == NULL)
{
- const char *name = MIPS_ELF_REL_DYN_SECTION_NAME (dynobj);
+ const char *dname = MIPS_ELF_REL_DYN_SECTION_NAME (dynobj);
- sreloc = bfd_get_section_by_name (dynobj, name);
+ sreloc = bfd_get_section_by_name (dynobj, dname);
if (sreloc == NULL)
{
- sreloc = bfd_make_section (dynobj, name);
+ sreloc = bfd_make_section (dynobj, dname);
if (sreloc == NULL
|| ! bfd_set_section_flags (dynobj, sreloc,
(SEC_ALLOC
return false;
}
}
+#define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
if (info->shared)
- /* When creating a shared object, we must copy these
- reloc types into the output file as R_MIPS_REL32
- relocs. We make room for this reloc in the
- .rel.dyn reloc section. */
- mips_elf_allocate_dynamic_relocations (dynobj, 1);
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file as R_MIPS_REL32
+ relocs. We make room for this reloc in the
+ .rel.dyn reloc section. */
+ mips_elf_allocate_dynamic_relocations (dynobj, 1);
+ if ((sec->flags & MIPS_READONLY_SECTION)
+ == MIPS_READONLY_SECTION)
+ /* 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;
defined in a dynamic object. */
hmips = (struct mips_elf_link_hash_entry *) h;
++hmips->possibly_dynamic_relocs;
+ if ((sec->flags & MIPS_READONLY_SECTION)
+ == MIPS_READONLY_SECTION)
+ /* 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
}
else
{
- if (!(elf_bad_symtab (abfd)
- && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
- && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
- && sym->st_shndx != SHN_COMMON))
- {
- return bfd_section_from_elf_index (abfd, sym->st_shndx);
- }
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
}
return NULL;
/* Copy data from a MIPS ELF indirect symbol to its direct symbol,
hiding the old indirect symbol. Process additional relocation
- information. */
+ information. Also called for weakdefs, in which case we just let
+ _bfd_elf_link_hash_copy_indirect copy the flags for us. */
-void
+static void
_bfd_mips_elf_copy_indirect_symbol (dir, ind)
struct elf_link_hash_entry *dir, *ind;
{
_bfd_elf_link_hash_copy_indirect (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 (dirmips->min_dyn_reloc_index == 0
|| (indmips->min_dyn_reloc_index != 0
&& indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index))
hmips = (struct mips_elf_link_hash_entry *) h;
if (! info->relocateable
&& hmips->possibly_dynamic_relocs != 0
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
- mips_elf_allocate_dynamic_relocations (dynobj,
- hmips->possibly_dynamic_relocs);
+ && (h->root.type == bfd_link_hash_defweak
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ {
+ mips_elf_allocate_dynamic_relocations (dynobj,
+ 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
/* 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));
+ bfd_set_section_size (output_bfd, ri,
+ (bfd_size_type) sizeof (Elf32_External_RegInfo));
if (info->relocateable
|| ! mips_elf_hash_table (info)->mips16_stubs_seen)
int i;
bfd_size_type loadable_size = 0;
bfd_size_type local_gotno;
- struct _bfd *sub;
+ bfd *sub;
BFD_ASSERT (elf_section_data (s) != NULL);
g = (struct mips_got_info *) elf_section_data (s)->tdata;
{
if ((subsection->flags & SEC_ALLOC) == 0)
continue;
- loadable_size += (subsection->_raw_size + 0xf) & ~0xf;
+ loadable_size += ((subsection->_raw_size + 0xf)
+ &~ (bfd_size_type) 0xf);
}
}
loadable_size += MIPS_FUNCTION_STUB_SIZE;
return false;
}
}
+
if (reltext && SGI_COMPAT (output_bfd))
+ info->flags |= DF_TEXTREL;
+
+ if ((info->flags & DF_TEXTREL) != 0)
{
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
return false;
- info->flags |= DF_TEXTREL;
}
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
/* Fill the stub. */
p = stub;
- bfd_put_32 (output_bfd, STUB_LW (output_bfd), p);
+ bfd_put_32 (output_bfd, (bfd_vma) STUB_LW (output_bfd), p);
p += 4;
- bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), p);
+ bfd_put_32 (output_bfd, (bfd_vma) STUB_MOVE (output_bfd), p);
p += 4;
/* FIXME: Can h->dynindex be more than 64K? */
if (h->dynindx & 0xffff0000)
return false;
- bfd_put_32 (output_bfd, STUB_JALR, p);
+ bfd_put_32 (output_bfd, (bfd_vma) STUB_JALR, p);
p += 4;
- bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, p);
+ bfd_put_32 (output_bfd, (bfd_vma) STUB_LI16 (output_bfd) + h->dynindx, p);
BFD_ASSERT (h->plt.offset <= s->_raw_size);
memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
case DT_STRSZ:
/* Rewrite DT_STRSZ. */
dyn.d_un.d_val =
- _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+ _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
break;
case DT_PLTGOT:
case DT_MIPS_BASE_ADDRESS:
s = output_bfd->sections;
BFD_ASSERT (s != NULL);
- dyn.d_un.d_ptr = s->vma & ~(0xffff);
+ dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
break;
case DT_MIPS_LOCAL_GOTNO:
return true;
}
\f
+/* Support for core dump NOTE sections */
+static boolean
+_bfd_elf32_mips_grok_prstatus (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ int offset;
+ unsigned int raw_size;
+
+ switch (note->descsz)
+ {
+ default:
+ return false;
+
+ case 256: /* Linux/MIPS */
+ /* pr_cursig */
+ 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);
+
+ /* pr_reg */
+ offset = 72;
+ raw_size = 180;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ raw_size, note->descpos + offset);
+}
+
+static boolean
+_bfd_elf32_mips_grok_psinfo (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ switch (note->descsz)
+ {
+ default:
+ return false;
+
+ case 128: /* Linux/MIPS elf_prpsinfo */
+ elf_tdata (abfd)->core_program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core_command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ }
+
+ /* Note that for some reason, a spurious space is tacked
+ onto the end of the args in some (at least one anyway)
+ implementations, so strip it off if it exists. */
+
+ {
+ char *command = elf_tdata (abfd)->core_command;
+ int n = strlen (command);
+
+ if (0 < n && command[n - 1] == ' ')
+ command[n - 1] = '\0';
+ }
+
+ return true;
+}
+\f
+#define PDR_SIZE 32
+
+static boolean
+_bfd_elf32_mips_discard_info (abfd, cookie, info)
+ bfd *abfd;
+ struct elf_reloc_cookie *cookie;
+ struct bfd_link_info *info;
+{
+ asection *o;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ boolean ret = false;
+ unsigned char *tdata;
+ size_t i, skip;
+
+ o = bfd_get_section_by_name (abfd, ".pdr");
+ if (! o)
+ return false;
+ if (o->_raw_size == 0)
+ return false;
+ if (o->_raw_size % PDR_SIZE != 0)
+ return false;
+ if (o->output_section != NULL
+ && bfd_is_abs_section (o->output_section))
+ return false;
+
+ tdata = bfd_zmalloc (o->_raw_size / PDR_SIZE);
+ if (! tdata)
+ return false;
+
+ cookie->rels = _bfd_elf32_link_read_relocs (abfd, o, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory);
+ if (!cookie->rels)
+ {
+ free (tdata);
+ return false;
+ }
+
+ cookie->rel = cookie->rels;
+ cookie->relend =
+ cookie->rels + o->reloc_count * bed->s->int_rels_per_ext_rel;
+
+ for (i = 0, skip = 0; i < o->_raw_size; i ++)
+ {
+ if (_bfd_elf32_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
+ {
+ tdata[i] = 1;
+ skip ++;
+ }
+ }
+
+ if (skip != 0)
+ {
+ elf_section_data (o)->tdata = tdata;
+ o->_cooked_size = o->_raw_size - skip * PDR_SIZE;
+ ret = true;
+ }
+ else
+ free (tdata);
+
+ if (! info->keep_memory)
+ free (cookie->rels);
+
+ return ret;
+}
+
+static boolean
+_bfd_elf32_mips_ignore_discarded_relocs (sec)
+ asection *sec;
+{
+ if (strcmp (sec->name, ".pdr") == 0)
+ return true;
+ return false;
+}
+
+static boolean
+_bfd_elf32_mips_write_section (output_bfd, sec, contents)
+ bfd *output_bfd;
+ asection *sec;
+ bfd_byte *contents;
+{
+ bfd_byte *to, *from, *end;
+ int i;
+
+ if (strcmp (sec->name, ".pdr") != 0)
+ return false;
+
+ if (elf_section_data (sec)->tdata == NULL)
+ return false;
+
+ to = contents;
+ end = contents + sec->_raw_size;
+ for (from = contents, i = 0;
+ from < end;
+ from += PDR_SIZE, i++)
+ {
+ if (((unsigned char *)elf_section_data (sec)->tdata)[i] == 1)
+ continue;
+ if (to != from)
+ memcpy (to, from, PDR_SIZE);
+ to += PDR_SIZE;
+ }
+ bfd_set_section_contents (output_bfd, sec->output_section, contents,
+ (file_ptr) sec->output_offset,
+ sec->_cooked_size);
+ return true;
+}
+\f
/* This is almost identical to bfd_generic_get_... except that some
MIPS relocations need to be handled specially. Sigh. */
if (reloc_size < 0)
goto error_return;
- reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
if (reloc_vector == NULL && reloc_size != 0)
goto error_return;
if (!bfd_get_section_contents (input_bfd,
input_section,
(PTR) data,
- 0,
+ (file_ptr) 0,
input_section->_raw_size))
goto error_return;
_bfd_mips_elf_read_ecoff_info
};
\f
-#define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec
-#define TARGET_LITTLE_NAME "elf32-littlemips"
-#define TARGET_BIG_SYM bfd_elf32_bigmips_vec
-#define TARGET_BIG_NAME "elf32-bigmips"
#define ELF_ARCH bfd_arch_mips
#define ELF_MACHINE_CODE EM_MIPS
#define elf_backend_collect true
#define elf_backend_type_change_ok true
#define elf_backend_can_gc_sections true
-#define elf_backend_sign_extend_vma true
#define elf_info_to_howto mips_info_to_howto_rela
#define elf_info_to_howto_rel mips_info_to_howto_rel
#define elf_backend_sym_is_global mips_elf_sym_is_global
#define elf_backend_object_p _bfd_mips_elf_object_p
+#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
+#define elf_backend_section_processing _bfd_mips_elf_section_processing
#define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
#define elf_backend_section_from_bfd_section \
_bfd_mips_elf_section_from_bfd_section
-#define elf_backend_section_processing _bfd_mips_elf_section_processing
-#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
-#define elf_backend_additional_program_headers \
- _bfd_mips_elf_additional_program_headers
-#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
-#define elf_backend_final_write_processing \
- _bfd_mips_elf_final_write_processing
-#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
#define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ _bfd_mips_elf_link_output_symbol_hook
#define elf_backend_create_dynamic_sections \
_bfd_mips_elf_create_dynamic_sections
#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
#define elf_backend_size_dynamic_sections \
_bfd_mips_elf_size_dynamic_sections
#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
-#define elf_backend_link_output_symbol_hook \
- _bfd_mips_elf_link_output_symbol_hook
#define elf_backend_finish_dynamic_symbol \
_bfd_mips_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
_bfd_mips_elf_finish_dynamic_sections
+#define elf_backend_final_write_processing \
+ _bfd_mips_elf_final_write_processing
+#define elf_backend_additional_program_headers \
+ _bfd_mips_elf_additional_program_headers
+#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_sweep_hook _bfd_mips_elf_gc_sweep_hook
-
-#define elf_backend_got_header_size (4*MIPS_RESERVED_GOTNO)
-#define elf_backend_plt_header_size 0
-
#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 _bfd_elf32_mips_grok_prstatus
+#define elf_backend_grok_psinfo _bfd_elf32_mips_grok_psinfo
+#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
+
+#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
+#define elf_backend_plt_header_size 0
+#define elf_backend_may_use_rel_p 1
+#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_discard_info _bfd_elf32_mips_discard_info
+#define elf_backend_ignore_discarded_relocs \
+ _bfd_elf32_mips_ignore_discarded_relocs
+#define elf_backend_write_section _bfd_elf32_mips_write_section
#define bfd_elf32_bfd_is_local_label_name \
mips_elf_is_local_label_name
#define bfd_elf32_bfd_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_copy_private_bfd_data \
- _bfd_mips_elf_copy_private_bfd_data
#define bfd_elf32_bfd_merge_private_bfd_data \
_bfd_mips_elf_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
#define bfd_elf32_bfd_print_private_bfd_data \
_bfd_mips_elf_print_private_bfd_data
-#include "elf32-target.h"
-/* Support for traditional mips targets */
+/* Support for SGI-ish mips targets. */
+#define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec
+#define TARGET_LITTLE_NAME "elf32-littlemips"
+#define TARGET_BIG_SYM bfd_elf32_bigmips_vec
+#define TARGET_BIG_NAME "elf32-bigmips"
+
+#include "elf32-target.h"
-#define INCLUDED_TARGET_FILE /* More a type of flag */
+/* Support for traditional mips targets. */
+#define INCLUDED_TARGET_FILE /* More a type of flag. */
#undef TARGET_LITTLE_SYM
#undef TARGET_LITTLE_NAME