mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 18:08:24 +08:00
* elf32-m68hc11.c (elf_m68hc11_howto_table): Add the new relocs;
fix masks for PC-rel relocs. (m68hc11_elf_ignore_reloc): New function. * elf32-m68hc12.c (m68hc12_elf_special_reloc): New to handle specific 68HC12 banked addressing relocs. (m68hc12_phys_addr): New to compute physical address of banked memory. (m68hc12_phys_page): Likewise for page. (m68hc12_addr_is_banked): New to see if address is in banked area. (elf_m68hc12_howto_table): Add new relocs and rename to xx12.
This commit is contained in:
@ -1,3 +1,16 @@
|
|||||||
|
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
|
||||||
|
|
||||||
|
* elf32-m68hc11.c (elf_m68hc11_howto_table): Add the new relocs;
|
||||||
|
fix masks for PC-rel relocs.
|
||||||
|
(m68hc11_elf_ignore_reloc): New function.
|
||||||
|
|
||||||
|
* elf32-m68hc12.c (m68hc12_elf_special_reloc): New to handle specific
|
||||||
|
68HC12 banked addressing relocs.
|
||||||
|
(m68hc12_phys_addr): New to compute physical address of banked memory.
|
||||||
|
(m68hc12_phys_page): Likewise for page.
|
||||||
|
(m68hc12_addr_is_banked): New to see if address is in banked area.
|
||||||
|
(elf_m68hc12_howto_table): Add new relocs and rename to xx12.
|
||||||
|
|
||||||
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
|
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
|
||||||
|
|
||||||
* reloc.c (BFD_RELOC_M68HC11_RL_JUMP, BFD_RELOC_M68HC11_RL_GROUP,
|
* reloc.c (BFD_RELOC_M68HC11_RL_JUMP, BFD_RELOC_M68HC11_RL_GROUP,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Motorola 68HC11-specific support for 32-bit ELF
|
/* Motorola 68HC11-specific support for 32-bit ELF
|
||||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
Contributed by Stephane Carrez (stcarrez@worldnet.fr)
|
Contributed by Stephane Carrez (stcarrez@nerim.fr)
|
||||||
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
|
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
@ -30,6 +30,11 @@ PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
|
|||||||
static void m68hc11_info_to_howto_rel
|
static void m68hc11_info_to_howto_rel
|
||||||
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
||||||
|
|
||||||
|
static bfd_reloc_status_type m68hc11_elf_ignore_reloc
|
||||||
|
PARAMS ((bfd *abfd, arelent *reloc_entry,
|
||||||
|
asymbol *symbol, PTR data, asection *input_section,
|
||||||
|
bfd *output_bfd, char **error_message));
|
||||||
|
|
||||||
/* Use REL instead of RELA to save space */
|
/* Use REL instead of RELA to save space */
|
||||||
#define USE_REL
|
#define USE_REL
|
||||||
|
|
||||||
@ -110,7 +115,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_PCREL_8", /* name */
|
"R_M68HC11_PCREL_8", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x0, /* src_mask */
|
0x00ff, /* src_mask */
|
||||||
0x00ff, /* dst_mask */
|
0x00ff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
@ -171,7 +176,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_PCREL_16", /* name */
|
"R_M68HC11_PCREL_16", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x0, /* src_mask */
|
0xffff, /* src_mask */
|
||||||
0xffff, /* dst_mask */
|
0xffff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
@ -204,6 +209,46 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* src_mask */
|
0, /* src_mask */
|
||||||
0, /* dst_mask */
|
0, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
EMPTY_HOWTO (11),
|
||||||
|
EMPTY_HOWTO (12),
|
||||||
|
EMPTY_HOWTO (13),
|
||||||
|
EMPTY_HOWTO (14),
|
||||||
|
EMPTY_HOWTO (15),
|
||||||
|
EMPTY_HOWTO (16),
|
||||||
|
EMPTY_HOWTO (17),
|
||||||
|
EMPTY_HOWTO (18),
|
||||||
|
EMPTY_HOWTO (19),
|
||||||
|
|
||||||
|
/* Mark beginning of a jump instruction (any form). */
|
||||||
|
HOWTO (R_M68HC11_RL_JUMP, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
0, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc11_elf_ignore_reloc, /* special_function */
|
||||||
|
"R_M68HC11_RL_JUMP", /* name */
|
||||||
|
true, /* partial_inplace */
|
||||||
|
0, /* src_mask */
|
||||||
|
0, /* dst_mask */
|
||||||
|
true), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* Mark beginning of Gcc relaxation group instruction. */
|
||||||
|
HOWTO (R_M68HC11_RL_GROUP, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
0, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc11_elf_ignore_reloc, /* special_function */
|
||||||
|
"R_M68HC11_RL_GROUP", /* name */
|
||||||
|
true, /* partial_inplace */
|
||||||
|
0, /* src_mask */
|
||||||
|
0, /* dst_mask */
|
||||||
|
true), /* pcrel_offset */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Map BFD reloc types to M68HC11 ELF reloc types. */
|
/* Map BFD reloc types to M68HC11 ELF reloc types. */
|
||||||
@ -225,9 +270,11 @@ static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
|
|||||||
{BFD_RELOC_32, R_M68HC11_32},
|
{BFD_RELOC_32, R_M68HC11_32},
|
||||||
{BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
|
{BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
|
||||||
|
|
||||||
/* The following relocs are defined but they probably don't work yet. */
|
|
||||||
{BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
|
{BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
|
||||||
{BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
|
{BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
|
||||||
|
|
||||||
|
{BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
|
||||||
|
{BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
|
||||||
};
|
};
|
||||||
|
|
||||||
static reloc_howto_type *
|
static reloc_howto_type *
|
||||||
@ -248,6 +295,25 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is used for relocs which are only used for relaxing,
|
||||||
|
which the linker should otherwise ignore. */
|
||||||
|
|
||||||
|
static bfd_reloc_status_type
|
||||||
|
m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
|
||||||
|
output_bfd, error_message)
|
||||||
|
bfd *abfd ATTRIBUTE_UNUSED;
|
||||||
|
arelent *reloc_entry;
|
||||||
|
asymbol *symbol ATTRIBUTE_UNUSED;
|
||||||
|
PTR data ATTRIBUTE_UNUSED;
|
||||||
|
asection *input_section;
|
||||||
|
bfd *output_bfd;
|
||||||
|
char **error_message ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
if (output_bfd != NULL)
|
||||||
|
reloc_entry->address += input_section->output_offset;
|
||||||
|
return bfd_reloc_ok;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the howto pointer for an M68HC11 ELF reloc. */
|
/* Set the howto pointer for an M68HC11 ELF reloc. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Motorola 68HC12-specific support for 32-bit ELF
|
/* Motorola 68HC12-specific support for 32-bit ELF
|
||||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||||
Contributed by Stephane Carrez (stcarrez@worldnet.fr)
|
Contributed by Stephane Carrez (stcarrez@nerim.fr)
|
||||||
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
|
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
@ -24,12 +24,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
#include "elf-bfd.h"
|
#include "elf-bfd.h"
|
||||||
#include "elf/m68hc11.h"
|
#include "elf/m68hc11.h"
|
||||||
|
#include "opcode/m68hc11.h"
|
||||||
|
|
||||||
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||||||
PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
|
PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
|
||||||
static void m68hc11_info_to_howto_rel
|
static void m68hc11_info_to_howto_rel
|
||||||
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
||||||
|
|
||||||
|
static bfd_reloc_status_type m68hc11_elf_ignore_reloc
|
||||||
|
PARAMS ((bfd *abfd, arelent *reloc_entry,
|
||||||
|
asymbol *symbol, PTR data, asection *input_section,
|
||||||
|
bfd *output_bfd, char **error_message));
|
||||||
|
static bfd_reloc_status_type m68hc12_elf_special_reloc
|
||||||
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||||
|
static int m68hc12_addr_is_banked PARAMS ((bfd_vma));
|
||||||
|
static bfd_vma m68hc12_phys_addr PARAMS ((bfd_vma));
|
||||||
|
static bfd_vma m68hc12_phys_page PARAMS ((bfd_vma));
|
||||||
|
|
||||||
/* Use REL instead of RELA to save space */
|
/* Use REL instead of RELA to save space */
|
||||||
#define USE_REL
|
#define USE_REL
|
||||||
|
|
||||||
@ -37,6 +48,68 @@ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
|||||||
We must handle 8 and 16-bit relocations. The 32-bit relocation
|
We must handle 8 and 16-bit relocations. The 32-bit relocation
|
||||||
is defined but not used except by gas when -gstabs is used (which
|
is defined but not used except by gas when -gstabs is used (which
|
||||||
is wrong).
|
is wrong).
|
||||||
|
|
||||||
|
The 68HC12 microcontroler has a memory bank switching system
|
||||||
|
with a 16Kb window in the 64Kb address space. The extended memory
|
||||||
|
is mapped in the 16Kb window (at 0x8000). The page register controls
|
||||||
|
which 16Kb bank is mapped. The call/rtc instructions take care of
|
||||||
|
bank switching in function calls/returns.
|
||||||
|
|
||||||
|
For GNU Binutils to work, we consider there is a physical memory
|
||||||
|
at 0..0x0ffff and a kind of virtual memory above that. Symbols
|
||||||
|
in virtual memory have their addresses treated in a special way
|
||||||
|
when disassembling and when linking.
|
||||||
|
|
||||||
|
For the linker to work properly, we must always relocate the virtual
|
||||||
|
memory as if it is mapped at 0x8000. When a 16-bit relocation is
|
||||||
|
made in the virtual memory, we check that it does not cross the
|
||||||
|
memory bank where it is used. This would involve a page change
|
||||||
|
which would be wrong. The 24-bit relocation is for that and it
|
||||||
|
treats the address as a physical address + page number.
|
||||||
|
|
||||||
|
|
||||||
|
Banked
|
||||||
|
Address Space
|
||||||
|
| | Page n
|
||||||
|
+---------------+ 0x1010000
|
||||||
|
| |
|
||||||
|
| jsr _foo |
|
||||||
|
| .. | Page 3
|
||||||
|
| _foo: |
|
||||||
|
+---------------+ 0x100C000
|
||||||
|
| |
|
||||||
|
| call _bar |
|
||||||
|
| .. | Page 2
|
||||||
|
| _bar: |
|
||||||
|
+---------------+ 0x1008000
|
||||||
|
/------>| |
|
||||||
|
| | call _foo | Page 1
|
||||||
|
| | |
|
||||||
|
| +---------------+ 0x1004000
|
||||||
|
Physical | | |
|
||||||
|
Address Space | | | Page 0
|
||||||
|
| | |
|
||||||
|
+-----------+ 0x00FFFF | +---------------+ 0x1000000
|
||||||
|
| | |
|
||||||
|
| call _foo | |
|
||||||
|
| | |
|
||||||
|
+-----------+ 0x00BFFF -+---/
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | 16K |
|
||||||
|
| | |
|
||||||
|
+-----------+ 0x008000 -+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
= =
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+-----------+ 0000
|
||||||
|
|
||||||
|
|
||||||
|
The 'call _foo' must be relocated with page 3 and 16-bit address
|
||||||
|
mapped at 0x8000.
|
||||||
|
|
||||||
The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
|
The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
|
||||||
static reloc_howto_type elf_m68hc11_howto_table[] = {
|
static reloc_howto_type elf_m68hc11_howto_table[] = {
|
||||||
/* This reloc does nothing. */
|
/* This reloc does nothing. */
|
||||||
@ -46,9 +119,9 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
32, /* bitsize */
|
32, /* bitsize */
|
||||||
false, /* pc_relative */
|
false, /* pc_relative */
|
||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_bitfield, /* complain_on_overflow */
|
complain_overflow_dont,/* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_NONE", /* name */
|
"R_M68HC12_NONE", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0, /* src_mask */
|
0, /* src_mask */
|
||||||
0, /* dst_mask */
|
0, /* dst_mask */
|
||||||
@ -63,7 +136,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_bitfield, /* complain_on_overflow */
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_8", /* name */
|
"R_M68HC12_8", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x00ff, /* src_mask */
|
0x00ff, /* src_mask */
|
||||||
0x00ff, /* dst_mask */
|
0x00ff, /* dst_mask */
|
||||||
@ -78,7 +151,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_bitfield, /* complain_on_overflow */
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_HI8", /* name */
|
"R_M68HC12_HI8", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x00ff, /* src_mask */
|
0x00ff, /* src_mask */
|
||||||
0x00ff, /* dst_mask */
|
0x00ff, /* dst_mask */
|
||||||
@ -93,7 +166,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_dont, /* complain_on_overflow */
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_LO8", /* name */
|
"R_M68HC12_LO8", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x00ff, /* src_mask */
|
0x00ff, /* src_mask */
|
||||||
0x00ff, /* dst_mask */
|
0x00ff, /* dst_mask */
|
||||||
@ -108,9 +181,9 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_bitfield, /* complain_on_overflow */
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_PCREL_8", /* name */
|
"R_M68HC12_PCREL_8", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x0, /* src_mask */
|
0x00ff, /* src_mask */
|
||||||
0x00ff, /* dst_mask */
|
0x00ff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
@ -122,8 +195,8 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
false, /* pc_relative */
|
false, /* pc_relative */
|
||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
|
complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
m68hc12_elf_special_reloc, /* special_function */
|
||||||
"R_M68HC11_16", /* name */
|
"R_M68HC12_16", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0xffff, /* src_mask */
|
0xffff, /* src_mask */
|
||||||
0xffff, /* dst_mask */
|
0xffff, /* dst_mask */
|
||||||
@ -139,7 +212,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_bitfield, /* complain_on_overflow */
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_32", /* name */
|
"R_M68HC12_32", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0xffffffff, /* src_mask */
|
0xffffffff, /* src_mask */
|
||||||
0xffffffff, /* dst_mask */
|
0xffffffff, /* dst_mask */
|
||||||
@ -154,7 +227,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_bitfield, /* complain_on_overflow */
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_4B", /* name */
|
"R_M68HC12_4B", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x003, /* src_mask */
|
0x003, /* src_mask */
|
||||||
0x003, /* dst_mask */
|
0x003, /* dst_mask */
|
||||||
@ -169,9 +242,9 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_dont, /* complain_on_overflow */
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_PCREL_16", /* name */
|
"R_M68HC12_PCREL_16", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x0, /* src_mask */
|
0xffff, /* src_mask */
|
||||||
0xffff, /* dst_mask */
|
0xffff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
@ -204,6 +277,88 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
0, /* src_mask */
|
0, /* src_mask */
|
||||||
0, /* dst_mask */
|
0, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* A 24 bit relocation */
|
||||||
|
HOWTO (R_M68HC11_24, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
24, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc12_elf_special_reloc, /* special_function */
|
||||||
|
"R_M68HC12_24", /* name */
|
||||||
|
false, /* partial_inplace */
|
||||||
|
0xffff, /* src_mask */
|
||||||
|
0xffff, /* dst_mask */
|
||||||
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* A 16-bit low relocation */
|
||||||
|
HOWTO (R_M68HC11_LO16, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
16, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc12_elf_special_reloc,/* special_function */
|
||||||
|
"R_M68HC12_LO16", /* name */
|
||||||
|
false, /* partial_inplace */
|
||||||
|
0xffff, /* src_mask */
|
||||||
|
0xffff, /* dst_mask */
|
||||||
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* A page relocation */
|
||||||
|
HOWTO (R_M68HC11_PAGE, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
8, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc12_elf_special_reloc,/* special_function */
|
||||||
|
"R_M68HC12_PAGE", /* name */
|
||||||
|
false, /* partial_inplace */
|
||||||
|
0x00ff, /* src_mask */
|
||||||
|
0x00ff, /* dst_mask */
|
||||||
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
EMPTY_HOWTO (14),
|
||||||
|
EMPTY_HOWTO (15),
|
||||||
|
EMPTY_HOWTO (16),
|
||||||
|
EMPTY_HOWTO (17),
|
||||||
|
EMPTY_HOWTO (18),
|
||||||
|
EMPTY_HOWTO (19),
|
||||||
|
|
||||||
|
/* Mark beginning of a jump instruction (any form). */
|
||||||
|
HOWTO (R_M68HC11_RL_JUMP, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
0, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc11_elf_ignore_reloc, /* special_function */
|
||||||
|
"R_M68HC12_RL_JUMP", /* name */
|
||||||
|
true, /* partial_inplace */
|
||||||
|
0, /* src_mask */
|
||||||
|
0, /* dst_mask */
|
||||||
|
true), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* Mark beginning of Gcc relaxation group instruction. */
|
||||||
|
HOWTO (R_M68HC11_RL_GROUP, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
0, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
m68hc11_elf_ignore_reloc, /* special_function */
|
||||||
|
"R_M68HC12_RL_GROUP", /* name */
|
||||||
|
true, /* partial_inplace */
|
||||||
|
0, /* src_mask */
|
||||||
|
0, /* dst_mask */
|
||||||
|
true), /* pcrel_offset */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Map BFD reloc types to M68HC11 ELF reloc types. */
|
/* Map BFD reloc types to M68HC11 ELF reloc types. */
|
||||||
@ -225,9 +380,15 @@ static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
|
|||||||
{BFD_RELOC_32, R_M68HC11_32},
|
{BFD_RELOC_32, R_M68HC11_32},
|
||||||
{BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
|
{BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
|
||||||
|
|
||||||
/* The following relocs are defined but they probably don't work yet. */
|
|
||||||
{BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
|
{BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
|
||||||
{BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
|
{BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
|
||||||
|
|
||||||
|
{BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
|
||||||
|
{BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
|
||||||
|
{BFD_RELOC_M68HC11_24, R_M68HC11_24},
|
||||||
|
|
||||||
|
{BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
|
||||||
|
{BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
|
||||||
};
|
};
|
||||||
|
|
||||||
static reloc_howto_type *
|
static reloc_howto_type *
|
||||||
@ -248,6 +409,158 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is used for relocs which are only used for relaxing,
|
||||||
|
which the linker should otherwise ignore. */
|
||||||
|
|
||||||
|
static bfd_reloc_status_type
|
||||||
|
m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
|
||||||
|
output_bfd, error_message)
|
||||||
|
bfd *abfd ATTRIBUTE_UNUSED;
|
||||||
|
arelent *reloc_entry;
|
||||||
|
asymbol *symbol ATTRIBUTE_UNUSED;
|
||||||
|
PTR data ATTRIBUTE_UNUSED;
|
||||||
|
asection *input_section;
|
||||||
|
bfd *output_bfd;
|
||||||
|
char **error_message ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
if (output_bfd != NULL)
|
||||||
|
reloc_entry->address += input_section->output_offset;
|
||||||
|
return bfd_reloc_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
m68hc12_addr_is_banked (addr)
|
||||||
|
bfd_vma addr;
|
||||||
|
{
|
||||||
|
return (addr >= M68HC12_BANK_VIRT) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the physical address seen by the processor, taking
|
||||||
|
into account banked memory. */
|
||||||
|
static bfd_vma
|
||||||
|
m68hc12_phys_addr (addr)
|
||||||
|
bfd_vma addr;
|
||||||
|
{
|
||||||
|
if (addr < M68HC12_BANK_VIRT)
|
||||||
|
return addr;
|
||||||
|
|
||||||
|
/* Map the address to the memory bank. */
|
||||||
|
addr -= M68HC12_BANK_VIRT;
|
||||||
|
addr &= M68HC12_BANK_MASK;
|
||||||
|
addr += M68HC12_BANK_BASE;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the page number corresponding to an address in banked memory. */
|
||||||
|
static bfd_vma
|
||||||
|
m68hc12_phys_page (addr)
|
||||||
|
bfd_vma addr;
|
||||||
|
{
|
||||||
|
if (addr < M68HC12_BANK_VIRT)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Map the address to the memory bank. */
|
||||||
|
addr -= M68HC12_BANK_VIRT;
|
||||||
|
addr >>= M68HC12_BANK_SHIFT;
|
||||||
|
addr &= M68HC12_BANK_PAGE_MASK;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bfd_reloc_status_type
|
||||||
|
m68hc12_elf_special_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 ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
reloc_howto_type *howto;
|
||||||
|
bfd_vma relocation;
|
||||||
|
bfd_vma phys_addr;
|
||||||
|
bfd_vma phys_page;
|
||||||
|
bfd_vma insn_page;
|
||||||
|
bfd_vma insn_addr;
|
||||||
|
|
||||||
|
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)
|
||||||
|
return bfd_reloc_continue;
|
||||||
|
|
||||||
|
if (reloc_entry->address > input_section->_cooked_size)
|
||||||
|
return bfd_reloc_outofrange;
|
||||||
|
|
||||||
|
/* Compute relocation. */
|
||||||
|
relocation = (symbol->value
|
||||||
|
+ symbol->section->output_section->vma
|
||||||
|
+ symbol->section->output_offset);
|
||||||
|
relocation += reloc_entry->addend;
|
||||||
|
relocation += bfd_get_16 (abfd, (bfd_byte*) data + reloc_entry->address);
|
||||||
|
|
||||||
|
/* Do the memory bank mapping. */
|
||||||
|
phys_addr = m68hc12_phys_addr (relocation);
|
||||||
|
phys_page = m68hc12_phys_page (relocation);
|
||||||
|
|
||||||
|
howto = reloc_entry->howto;
|
||||||
|
if (howto->complain_on_overflow != complain_overflow_dont
|
||||||
|
&& (phys_addr & (((bfd_vma) -1) << 16)))
|
||||||
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
|
switch (howto->type)
|
||||||
|
{
|
||||||
|
case R_M68HC11_16:
|
||||||
|
/* Get virtual address of instruction having the relocation. */
|
||||||
|
insn_addr = input_section->output_section->vma
|
||||||
|
+ input_section->output_offset
|
||||||
|
+ reloc_entry->address;
|
||||||
|
|
||||||
|
insn_page = m68hc12_phys_page (insn_addr);
|
||||||
|
|
||||||
|
if (m68hc12_addr_is_banked (relocation)
|
||||||
|
&& m68hc12_addr_is_banked (insn_addr)
|
||||||
|
&& phys_page != insn_page)
|
||||||
|
{
|
||||||
|
*error_message = _("address is not in the same bank");
|
||||||
|
return bfd_reloc_dangerous;
|
||||||
|
}
|
||||||
|
if (m68hc12_addr_is_banked (relocation)
|
||||||
|
&& !m68hc12_addr_is_banked (insn_addr))
|
||||||
|
{
|
||||||
|
*error_message = _("reference to a banked address in "
|
||||||
|
"the normal address space");
|
||||||
|
return bfd_reloc_dangerous;
|
||||||
|
}
|
||||||
|
|
||||||
|
case R_M68HC11_LO16:
|
||||||
|
bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_M68HC11_24:
|
||||||
|
bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
|
||||||
|
bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address + 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_M68HC11_PAGE:
|
||||||
|
bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bfd_reloc_ok;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the howto pointer for an M68HC11 ELF reloc. */
|
/* Set the howto pointer for an M68HC11 ELF reloc. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user