aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-mips.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-06-02 10:20:16 +0000
committerMark Mitchell <mark@codesourcery.com>1999-06-02 10:20:16 +0000
commit3f830999e3fcf929d222d07baea857c1599055fe (patch)
tree5ab09868ec2a292b844862a814d1b77a61be7513 /bfd/elf32-mips.c
parent015985c9fcc34fb94b31c1bef0e20ef8e9aa2f19 (diff)
downloadgdb-3f830999e3fcf929d222d07baea857c1599055fe.zip
gdb-3f830999e3fcf929d222d07baea857c1599055fe.tar.gz
gdb-3f830999e3fcf929d222d07baea857c1599055fe.tar.bz2
* reloc.c (BFD_RELOC_MIPS_SUB): New relocation.
(BFD_RELOC_MIPS_GOT_PAGE): Likewise. (BFD_RELOC_MIPS_GOT_OFST): Likewise. (BFD_RELOC_MIPS_GOT_DISP): Likewise. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. * elf32-mips.c (mips_info_to_howto_rela): New function. (USE_REL): Adjust for new conventions. (MINUS_ONE): New macro. (elf_mips_howto_table): Add R_MIPS_SUB. (mips_r): Add entries for MIPS_SUB, MIPS_GOT_PAGE, MIPS_GOT_OFST, and MIPS_GOT_DISP. (mips_elf_final_write_processing): Set sh_link, not sh_info, for a .MIPS.content section. (_bfd_mips_elf_fake_sections): Treat all sections that begin with .MIPS.content as .MIPS.content sections. Set SHF_MNIPS_NOSTRIP for such section. (elf_info_to_howto): Define to mips_info_to_howto_rela. * elf64-mips.c (mips_r): Add entries for MIPS_SUB, MIPS_GOT_PAGE, MIPS_GOT_OFST, and MIPS_GOT_DISP.
Diffstat (limited to 'bfd/elf32-mips.c')
-rw-r--r--bfd/elf32-mips.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index 9f03262..6828ba0 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -47,6 +47,8 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type));
static void mips_info_to_howto_rel
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static void mips_info_to_howto_rela
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
static void bfd_mips_elf32_swap_gptab_in
PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *));
static void bfd_mips_elf32_swap_gptab_out
@@ -297,6 +299,10 @@ static void bfd_elf32_swap_crinfo_out
#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[] =
{
/* No relocation. */
@@ -634,8 +640,21 @@ static reloc_howto_type elf_mips_howto_table[] =
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
- /* 64 bit subtraction. Presumably not used in 32 bit ELF. */
- { R_MIPS_SUB },
+ /* 64 bit subtraction. Used in the N32 ABI. */
+ /* 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_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
/* Used to cause the linker to insert and delete instructions? */
{ R_MIPS_INSERT_A },
@@ -1607,7 +1626,11 @@ static CONST struct elf_reloc_map mips_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 }
+ { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
+ { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
+ { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
+ { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
+ { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
};
/* Given a BFD reloc type, return a howto structure. */
@@ -1651,7 +1674,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
}
}
-/* Given a MIPS reloc type, fill in an arelent structure. */
+/* Given a MIPS Elf32_Internal_Rel, fill in an arelent structure. */
static void
mips_info_to_howto_rel (abfd, cache_ptr, dst)
@@ -1692,6 +1715,23 @@ mips_info_to_howto_rel (abfd, cache_ptr, dst)
|| r_type == (unsigned int) R_MIPS_LITERAL))
cache_ptr->addend = elf_gp (abfd);
}
+
+/* Given a MIPS Elf32_Internal_Rela, fill in an arelent structure. */
+
+static void
+mips_info_to_howto_rela (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ /* Since an Elf32_Internal_Rel is an initial prefix of an
+ Elf32_Internal_Rela, we can just use mips_info_to_howto_rel
+ above. */
+ mips_info_to_howto_rel (abfd, cache_ptr, (Elf32_Internal_Rel *) dst);
+
+ /* If we ever need to do any extra processing with dst->r_addend
+ (the field omitted in an Elf32_Internal_Rel) we can do it here. */
+}
/* A .reginfo section holds a single Elf32_RegInfo structure. These
routines swap this structure in and out. They are used outside of
@@ -1992,7 +2032,7 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
sec = bfd_get_section_by_name (abfd,
name + sizeof ".MIPS.content" - 1);
BFD_ASSERT (sec != NULL);
- (*hdrpp)->sh_info = elf_section_data (sec)->this_idx;
+ (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
break;
case SHT_MIPS_SYMBOL_LIB:
@@ -2527,9 +2567,10 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
hdr->sh_type = SHT_MIPS_IFACE;
hdr->sh_flags |= SHF_MIPS_NOSTRIP;
}
- else if (strcmp (name, ".MIPS.content") == 0)
+ else if (strncmp (name, ".MIPS.content", strlen (".MIPS.content")) == 0)
{
hdr->sh_type = SHT_MIPS_CONTENT;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
/* The sh_info field is set in final_write_processing. */
}
else if (strcmp (name, ".options") == 0
@@ -7743,7 +7784,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap =
#define elf_backend_collect true
#define elf_backend_type_change_ok true
#define elf_backend_can_gc_sections true
-#define elf_info_to_howto 0
+#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 mips_elf32_object_p