* reloc.c: Add relocs BFD_RELOC_M32R_{HI16_[US]LO,LO16}.

* bfd-in2.h, libbfd.h: Regenerated.
	* elf32-m32r.c: Add support for them.
This commit is contained in:
David Edelsohn 1997-01-27 20:35:24 +00:00
parent 8f6c6a6549
commit 1d5c6cfdf0
5 changed files with 446 additions and 9 deletions

View File

@ -1,3 +1,11 @@
start-sanitize-m32r
Mon Jan 27 12:07:35 1997 Doug Evans <dje@seba.cygnus.com>
* reloc.c: Add relocs BFD_RELOC_M32R_{HI16_[US]LO,LO16}.
* bfd-in2.h, libbfd.h: Regenerated.
* elf32-m32r.c: Add support for them.
end-sanitize-m32r
Mon Jan 27 12:25:02 1997 Ian Lance Taylor <ian@cygnus.com>
* aout-arm.c (MY_swap_std_reloc_in): Remove unused r_length.

View File

@ -1866,8 +1866,19 @@ This is a 24 bit absolute address. */
/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */
BFD_RELOC_M32R_18_PCREL,
/* This is an 26-bit reloc with the right 2 bits assumed to be 0. */
/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */
BFD_RELOC_M32R_26_PCREL,
/* This is a 16-bit reloc containing the high 16 bits of an address
used when the lower 16 bits are treated as unsigned. */
BFD_RELOC_M32R_HI16_ULO,
/* This is a 16-bit reloc containing the high 16 bits of an address
used when the lower 16 bits are treated as signed. */
BFD_RELOC_M32R_HI16_SLO,
/* This is a 16-bit reloc containing the lower 16 bits of an address. */
BFD_RELOC_M32R_LO16,
/* end-sanitize-m32r */
/* start-sanitize-v850 */

383
bfd/elf32-m32r.c Normal file
View File

@ -0,0 +1,383 @@
/* M32R-specific support for 32-bit ELF.
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/m32r.h"
static bfd_reloc_status_type m32r_elf_10_pcrel_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static bfd_reloc_status_type m32r_elf_hi16_slo_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
static void m32r_info_to_howto_rel
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
/* Use REL instead of RELA to save space. */
#define USE_REL
static reloc_howto_type elf_m32r_howto_table[] =
{
/* This reloc does nothing. */
HOWTO (R_M32R_NONE, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_M32R_NONE", /* name */
false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
false), /* pcrel_offset */
/* A 16 bit absolute relocation. */
HOWTO (R_M32R_16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_M32R_16", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A 32 bit absolute relocation. */
HOWTO (R_M32R_32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_M32R_32", /* name */
false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
/* A 24 bit address. */
HOWTO (R_M32R_24, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
24, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_unsigned, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_M32R_24", /* name */
false, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
false), /* pcrel_offset */
/* An PC Relative 10-bit relocation, shifted by 2.
This reloc is complicated because relocations are relative to pc & -4.
i.e. branches in the right insn slot use the address of the left insn
slot for pc. */
HOWTO (R_M32R_10_PCREL, /* type */
2, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
m32r_elf_10_pcrel_reloc, /* special_function */
"R_M32R_10_PCREL", /* name */
false, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
true), /* pcrel_offset */
/* A relative 18 bit relocation, right shifted by 2. */
HOWTO (R_M32R_18_PCREL, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
18, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_M32R_18_PCREL", /* name */
false, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
true), /* pcrel_offset */
/* A relative 26 bit relocation, right shifted by 2. */
HOWTO (R_M32R_26_PCREL, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
26, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_M32R_26_PCREL", /* name */
false, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
true), /* pcrel_offset */
/* High 16 bits of address when lower 16 is or'd in. */
HOWTO (R_M32R_HI16_ULO, /* type */
16, /* 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_M32R_HI16_ULO", /* name */
false, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* High 16 bits of address when lower 16 is added in. */
HOWTO (R_M32R_HI16_SLO, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
m32r_elf_hi16_slo_reloc, /* special_function */
"R_M32R_HI16_SLO", /* name */
false, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
/* Lower 16 bits of address. */
HOWTO (R_M32R_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_M32R_LO16", /* name */
false, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
false), /* pcrel_offset */
};
/* Handle the R_M32R_10_PCREL reloc. */
static bfd_reloc_status_type
m32r_elf_10_pcrel_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
char **error_message;
{
bfd_vma relocation;
bfd_vma x;
reloc_howto_type *howto;
/* This part if from bfd_elf_generic_reloc. */
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
&& (! reloc_entry->howto->partial_inplace
|| reloc_entry->addend == 0))
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
if (output_bfd != NULL)
{
/* FIXME: See bfd_perform_relocation. Is this right? */
return bfd_reloc_continue;
}
/* The rest is copied from bfd_perform_relocation, modified to suit us. */
if (reloc_entry->address > input_section->_cooked_size)
return bfd_reloc_outofrange;
relocation = (symbol->value
+ symbol->section->output_section->vma
+ symbol->section->output_offset);
relocation += reloc_entry->addend;
relocation -= (input_section->output_section->vma
+ input_section->output_offset);
relocation -= (reloc_entry->address & -4L);
howto = reloc_entry->howto;
x = bfd_get_16 (abfd, (char *) data + reloc_entry->address);
relocation >>= howto->rightshift;
relocation <<= howto->bitpos;
x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask);
bfd_put_16 (abfd, x, (char *) data + reloc_entry->address);
if ((bfd_signed_vma) relocation < - 0x80
|| (bfd_signed_vma) relocation > 0x7f)
return bfd_reloc_overflow;
else
return bfd_reloc_ok;
}
/* Handle the R_M32R_HI16_SLO reloc.
This reloc is used in load/store with displacement instructions.
The lower 16 bits are sign extended when added to the high 16 bytes
so if the lower 16 bits are negative (bit 15 == 1) then we must add one
to the high 16 bytes (which will get subtracted off when the low 16 bits
are added. */
static bfd_reloc_status_type
m32r_elf_hi16_slo_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
char **error_message;
{
bfd_vma relocation;
unsigned long x;
int bit15;
reloc_howto_type *howto;
/* This part if from bfd_elf_generic_reloc. */
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
&& (! reloc_entry->howto->partial_inplace
|| reloc_entry->addend == 0))
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
if (output_bfd != NULL)
{
/* FIXME: See bfd_perform_relocation. Is this right? */
return bfd_reloc_continue;
}
/* The rest is copied from bfd_perform_relocation, modified to suit us. */
if (reloc_entry->address > input_section->_cooked_size)
return bfd_reloc_outofrange;
relocation = (symbol->value
+ symbol->section->output_section->vma
+ symbol->section->output_offset);
relocation += reloc_entry->addend;
howto = reloc_entry->howto;
x = bfd_get_32 (abfd, (char *) data + reloc_entry->address);
bit15 = relocation & 0x8000;
relocation >>= howto->rightshift;
if (bit15)
relocation += 1;
relocation <<= howto->bitpos;
x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask);
bfd_put_32 (abfd, x, (char *) data + reloc_entry->address);
return bfd_reloc_ok;
}
/* Map BFD reloc types to M32R ELF reloc types. */
struct m32r_reloc_map
{
unsigned char bfd_reloc_val;
unsigned char elf_reloc_val;
};
static const struct m32r_reloc_map m32r_reloc_map[] =
{
{ BFD_RELOC_NONE, R_M32R_NONE },
{ BFD_RELOC_16, R_M32R_16 },
{ BFD_RELOC_32, R_M32R_32 },
{ BFD_RELOC_M32R_24, R_M32R_24 },
{ BFD_RELOC_M32R_10_PCREL, R_M32R_10_PCREL },
{ BFD_RELOC_M32R_18_PCREL, R_M32R_18_PCREL },
{ BFD_RELOC_M32R_26_PCREL, R_M32R_26_PCREL },
{ BFD_RELOC_M32R_HI16_ULO, R_M32R_HI16_ULO },
{ BFD_RELOC_M32R_HI16_SLO, R_M32R_HI16_SLO },
{ BFD_RELOC_M32R_LO16, R_M32R_LO16 },
};
static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup (abfd, code)
bfd *abfd;
bfd_reloc_code_real_type code;
{
unsigned int i;
for (i = 0;
i < sizeof (m32r_reloc_map) / sizeof (struct m32r_reloc_map);
i++)
{
if (m32r_reloc_map[i].bfd_reloc_val == code)
return &elf_m32r_howto_table[m32r_reloc_map[i].elf_reloc_val];
}
return NULL;
}
/* Set the howto pointer for an M32R ELF reloc. */
static void
m32r_info_to_howto_rel (abfd, cache_ptr, dst)
bfd *abfd;
arelent *cache_ptr;
Elf32_Internal_Rel *dst;
{
unsigned int r_type;
r_type = ELF32_R_TYPE (dst->r_info);
BFD_ASSERT (r_type < (unsigned int) R_M32R_max);
cache_ptr->howto = &elf_m32r_howto_table[r_type];
}
#define ELF_ARCH bfd_arch_m32r
#define ELF_MACHINE_CODE EM_CYGNUS_M32R
#define ELF_MAXPAGESIZE 0x1000
#define TARGET_BIG_SYM bfd_elf32_m32r_vec
#define TARGET_BIG_NAME "elf32-m32r"
#define elf_info_to_howto 0
#define elf_info_to_howto_rel m32r_info_to_howto_rel
#define elf_backend_object_p 0
#define elf_backend_final_write_processing 0
#include "elf32-target.h"

View File

@ -753,6 +753,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_M32R_10_PCREL",
"BFD_RELOC_M32R_18_PCREL",
"BFD_RELOC_M32R_26_PCREL",
"BFD_RELOC_M32R_HI16_ULO",
"BFD_RELOC_M32R_HI16_SLO",
"BFD_RELOC_M32R_LO16",
/* end-sanitize-m32r */
/* start-sanitize-v850 */

View File

@ -1,5 +1,6 @@
/* BFD support for handling relocation entries.
Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94, 95, 1996, 1997
Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -1662,6 +1663,8 @@ ENUMX
BFD_RELOC_32
ENUMX
BFD_RELOC_26
ENUMX
BFD_RELOC_24
ENUMX
BFD_RELOC_16
ENUMX
@ -1953,6 +1956,11 @@ ENUMDOC
Bits 27..2 of the relocation address shifted right 2 bits;
simple reloc otherwise.
ENUM
BFD_RELOC_MIPS16_JMP
ENUMDOC
The MIPS16 jump instruction.
ENUM
BFD_RELOC_HI16
ENUMDOC
@ -2252,22 +2260,36 @@ COMMENT
COMMENT
{* start-sanitize-m32r *}
ENUM
BFD_RELOC_M32R_UIMM24
BFD_RELOC_M32R_24
ENUMDOC
Mitsubishi M32R relocs.
This is a 24 bit address.
This is a 24 bit absolute address.
ENUM
BFD_RELOC_M32R_DISP8
BFD_RELOC_M32R_10_PCREL
ENUMDOC
This is a 10-bit reloc with the right 2 bits assumed to be 0.
This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0.
ENUM
BFD_RELOC_M32R_DISP16
BFD_RELOC_M32R_18_PCREL
ENUMDOC
This is an 18-bit reloc with the right 2 bits assumed to be 0.
ENUM
BFD_RELOC_M32R_DISP24
BFD_RELOC_M32R_26_PCREL
ENUMDOC
This is an 26-bit reloc with the right 2 bits assumed to be 0.
This is a 26-bit reloc with the right 2 bits assumed to be 0.
ENUM
BFD_RELOC_M32R_HI16_ULO
ENUMDOC
This is a 16-bit reloc containing the high 16 bits of an address
used when the lower 16 bits are treated as unsigned.
ENUM
BFD_RELOC_M32R_HI16_SLO
ENUMDOC
This is a 16-bit reloc containing the high 16 bits of an address
used when the lower 16 bits are treated as signed.
ENUM
BFD_RELOC_M32R_LO16
ENUMDOC
This is a 16-bit reloc containing the lower 16 bits of an address.
COMMENT
{* end-sanitize-m32r *}
@ -2296,6 +2318,16 @@ ENUMDOC
COMMENT
{* end-sanitize-v850 *}
ENUM
BFD_RELOC_MN10300_32_PCREL
ENUMDOC
This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
instruction.
ENUM
BFD_RELOC_MN10300_16_PCREL
ENUMDOC
This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
instruction.
ENDSENUM
BFD_RELOC_UNUSED
CODE_FRAGMENT