From 12fdaaf821700a8a1317208f6778cb709afcfc74 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 25 Nov 1996 15:59:07 +0000 Subject: [PATCH] * elf32-mn10300.c (bfd_elf32_mn10300_reloc): New function. (enum reloc_type): Add more reloc types. (elf32_mn10300_howto_table): Update for new reloc types. (elf32_mn10300_reloc_map): Update for new reloc types. * reloc.c: Add some new relocs for the mn10300 series. * bfd-in2.h, libbfd.h: Rebuilt. Last week's reloc work. --- bfd/ChangeLog | 9 +++ bfd/elf32-mn10300.c | 192 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 184 insertions(+), 17 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2b5439e8af6..a96d00cac96 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +Mon Nov 25 08:52:29 1996 Jeffrey A Law (law@cygnus.com) + + * elf32-mn10300.c (bfd_elf32_mn10300_reloc): New function. + (enum reloc_type): Add more reloc types. + (elf32_mn10300_howto_table): Update for new reloc types. + (elf32_mn10300_reloc_map): Update for new reloc types. + * reloc.c: Add some new relocs for the mn10300 series. + * bfd-in2.h, libbfd.h: Rebuilt. + Sat Nov 23 13:26:18 1996 Jeffrey A Law (law@cygnus.com) * som.c (setup_sections): Don't lose for a space which has diff --git a/bfd/elf32-mn10300.c b/bfd/elf32-mn10300.c index 4fe8f7a9430..659a11dae04 100644 --- a/bfd/elf32-mn10300.c +++ b/bfd/elf32-mn10300.c @@ -26,6 +26,9 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); static void mn10300_info_to_howto_rel PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); +static bfd_reloc_status_type bfd_elf32_mn10300_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + /* Try to minimize the amount of space occupied by relocation tables on the ROM (not that the ROM won't be swamped by other ELF overhead). */ @@ -37,9 +40,13 @@ enum reloc_type R_MN10300_32, R_MN10300_16, R_MN10300_8, - R_MN10300_PCREL32, - R_MN10300_PCREL16, - R_MN10300_PCREL8, + R_MN10300_32B, + R_MN10300_16B, + R_MN10300_PCREL32_1BYTE, + R_MN10300_PCREL16_1BYTE, + R_MN10300_PCREL8_1BYTE, + R_MN10300_PCREL32_2BYTE, + R_MN10300_PCREL16_2BYTE, R_MN10300_MAX }; @@ -98,45 +105,97 @@ static reloc_howto_type elf_mn10300_howto_table[] = 0xff, 0xff, false), - HOWTO (R_MN10300_PCREL32, + HOWTO (R_MN10300_32B, 0, 2, 32, + false, + 0, + complain_overflow_bitfield, + bfd_elf32_mn10300_reloc, + "R_MN10300_32B", true, + 0xffffffff, + 0xffffffff, + false), + HOWTO (R_MN10300_16B, + 0, + 1, + 16, + false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, - "R_MN10300_PCREL32", + bfd_elf32_mn10300_reloc, + "R_MN10300_16B", + true, + 0xffff, + 0xffff, + false), + HOWTO (R_MN10300_PCREL32_1BYTE, + 0, + 2, + 32, + true, + 0, + complain_overflow_bitfield, + bfd_elf32_mn10300_reloc, + "R_MN10300_PCREL32_1BYTE", true, 0xffffffff, 0xffffffff, false), - HOWTO (R_MN10300_PCREL16, + HOWTO (R_MN10300_PCREL16_1BYTE, 0, 1, 16, true, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, - "R_MN10300_PCREL16", + bfd_elf32_mn10300_reloc, + "R_MN10300_PCREL16_1BYTE", true, 0xffff, 0xffff, false), - HOWTO (R_MN10300_PCREL8, + HOWTO (R_MN10300_PCREL8_1BYTE, 0, 0, 8, true, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, - "R_MN10300_PCREL8", + bfd_elf32_mn10300_reloc, + "R_MN10300_PCREL8_1BYTE", true, 0xff, 0xff, - false), + true), + HOWTO (R_MN10300_PCREL32_2BYTE, + 0, + 2, + 32, + true, + 0, + complain_overflow_bitfield, + bfd_elf32_mn10300_reloc, + "R_MN10300_PCREL32_2BYTE", + true, + 0xffffffff, + 0xffffffff, + true), + HOWTO (R_MN10300_PCREL16_2BYTE, + 0, + 1, + 16, + true, + 0, + complain_overflow_bitfield, + bfd_elf32_mn10300_reloc, + "R_MN10300_PCREL16_2BYTE", + true, + 0xffff, + 0xffff, + true), }; struct mn10300_reloc_map @@ -151,9 +210,13 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] = { BFD_RELOC_32, R_MN10300_32, }, { BFD_RELOC_16, R_MN10300_16, }, { BFD_RELOC_8, R_MN10300_8, }, - { BFD_RELOC_32_PCREL, R_MN10300_PCREL32, }, - { BFD_RELOC_16_PCREL, R_MN10300_PCREL16, }, - { BFD_RELOC_8_PCREL, R_MN10300_PCREL8, }, + { BFD_RELOC_MN10300_32B, R_MN10300_32B, }, + { BFD_RELOC_MN10300_16B, R_MN10300_16B, }, + { BFD_RELOC_32_PCREL, R_MN10300_PCREL32_1BYTE, }, + { BFD_RELOC_16_PCREL, R_MN10300_PCREL16_1BYTE, }, + { BFD_RELOC_8_PCREL, R_MN10300_PCREL8_1BYTE, }, + { BFD_RELOC_MN10300_32_PCREL, R_MN10300_PCREL32_2BYTE, }, + { BFD_RELOC_MN10300_16_PCREL, R_MN10300_PCREL16_2BYTE, }, }; static reloc_howto_type * @@ -174,7 +237,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) return NULL; } -/* Set the howto pointer for an V850 ELF reloc. */ +/* Set the howto pointer for an MN10300 ELF reloc. */ static void mn10300_info_to_howto_rel (abfd, cache_ptr, dst) @@ -189,6 +252,101 @@ mn10300_info_to_howto_rel (abfd, cache_ptr, dst) cache_ptr->howto = &elf_mn10300_howto_table[r_type]; } +static bfd_reloc_status_type +bfd_elf32_mn10300_reloc (abfd, reloc, symbol, data, isection, obfd, err) + bfd *abfd; + arelent *reloc; + asymbol *symbol; + PTR data; + asection *isection; + bfd *obfd; + char **err; +{ + if (obfd != (bfd *) NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && (! reloc->howto->partial_inplace + || reloc->addend == 0)) + { + reloc->address += isection->output_offset; + return bfd_reloc_ok; + } + else if (obfd != NULL) + { + return bfd_reloc_continue; + } + + /* Catch relocs involving undefined symbols. */ + if (bfd_is_und_section (symbol->section) + && (symbol->flags & BSF_WEAK) == 0 + && obfd == NULL) + return bfd_reloc_undefined; + + /* We handle final linking of some relocs ourselves. */ + { + long relocation, insn; + + /* Is the address of the relocation really within the section? */ + if (reloc->address > isection->_cooked_size) + return bfd_reloc_outofrange; + + /* Work out which section the relocation is targetted at and the + initial relocation command value. */ + + /* Get symbol value. (Common symbols are special.) */ + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + /* Convert input-section-relative symbol value to absolute + addend. */ + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + relocation += reloc->addend; + + if (reloc->howto->pc_relative == true) + { + /* Here the variable relocation holds the final address of the + symbol we are relocating against, plus any addend. */ + relocation -= isection->output_section->vma + isection->output_offset; + + /* Deal with pcrel_offset */ + relocation -= reloc->address; + + if (reloc->howto->type == R_MN10300_PCREL32_1BYTE + || reloc->howto->type == R_MN10300_PCREL16_1BYTE + || reloc->howto->type == R_MN10300_PCREL8_1BYTE) + relocation += 1; + else if (reloc->howto->type == R_MN10300_PCREL32_2BYTE + || reloc->howto->type == R_MN10300_PCREL16_2BYTE) + relocation += 2; + } + + /* I've got no clue... */ + reloc->addend = 0; + + if (reloc->howto->size == 0) + { + if (relocation > 0x7f || relocation < -0x80) + return bfd_reloc_overflow; + + bfd_put_8 (abfd, relocation & 0xff, + (bfd_byte *)data + reloc->address); + } + else if (reloc->howto->size == 1) + { + if (relocation > 0x7fff || relocation < -0x8000) + return bfd_reloc_overflow; + + bfd_putb16 (relocation & 0xffff, (bfd_byte *)data + reloc->address); + } + else if (reloc->howto->size == 2) + bfd_putb32 (relocation, (bfd_byte *)data + reloc->address); + return bfd_reloc_ok; + } + + return bfd_reloc_continue; +} + #define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec #define TARGET_LITTLE_NAME "elf32-mn10300" #define ELF_ARCH bfd_arch_mn10300 -- 2.30.2