From 3f830999e3fcf929d222d07baea857c1599055fe Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 2 Jun 1999 10:20:16 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 23 ++++++++++++++++++++ bfd/bfd-in2.h | 8 +++++-- bfd/elf32-mips.c | 55 ++++++++++++++++++++++++++++++++++++++++++------ bfd/elf64-mips.c | 6 +++++- bfd/libbfd.h | 4 ++++ bfd/reloc.c | 8 +++++++ 6 files changed, 94 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5f80d550b4..2fabdb1367 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,26 @@ +Tue Jun 1 17:57:58 1999 Mark P. Mitchell + + * 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. + Wed Jun 2 11:51:12 1999 Andreas Schwab * vms-misc.c (_bfd_vms_hash_newfunc): Fix use of uninitialized diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7e915e994f..248ab9dbbd 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -725,10 +725,10 @@ extern boolean bfd_arm_get_bfd_for_interworking /* ELF ARM Interworking support. Called from linker. */ extern boolean bfd_elf32_arm_allocate_interworking_sections - PARAMS ((struct bfd_link_info *)); + PARAMS ((struct bfd_link_info *, int)); extern boolean bfd_elf32_arm_process_before_allocation - PARAMS ((bfd *, struct bfd_link_info *, int)); + PARAMS ((bfd *, struct bfd_link_info *)); extern boolean bfd_elf32_arm_get_bfd_for_interworking PARAMS ((bfd *, struct bfd_link_info *)); @@ -1837,6 +1837,10 @@ to compensate for the borrow when the low bits are added. */ BFD_RELOC_MIPS_GOT_LO16, BFD_RELOC_MIPS_CALL_HI16, BFD_RELOC_MIPS_CALL_LO16, + BFD_RELOC_MIPS_SUB, + BFD_RELOC_MIPS_GOT_PAGE, + BFD_RELOC_MIPS_GOT_OFST, + BFD_RELOC_MIPS_GOT_DISP, /* i386/elf relocations */ diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 9f03262eb3..6828ba0004 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 diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 9fb8bb9c85..05001a6162 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -1255,7 +1255,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. */ diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c0bd974bad..e395f726af 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -680,6 +680,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MIPS_GOT_LO16", "BFD_RELOC_MIPS_CALL_HI16", "BFD_RELOC_MIPS_CALL_LO16", + "BFD_RELOC_MIPS_SUB", + "BFD_RELOC_MIPS_GOT_PAGE", + "BFD_RELOC_MIPS_GOT_OFST", + "BFD_RELOC_MIPS_GOT_DISP", "BFD_RELOC_386_GOT32", "BFD_RELOC_386_PLT32", diff --git a/bfd/reloc.c b/bfd/reloc.c index 5d141b1fe1..9e8735e5ed 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2028,6 +2028,14 @@ ENUMX BFD_RELOC_MIPS_CALL_HI16 ENUMX BFD_RELOC_MIPS_CALL_LO16 +ENUMX + BFD_RELOC_MIPS_SUB +ENUMX + BFD_RELOC_MIPS_GOT_PAGE +ENUMX + BFD_RELOC_MIPS_GOT_OFST +ENUMX + BFD_RELOC_MIPS_GOT_DISP COMMENT ENUMDOC MIPS ELF relocations.