/* V850-specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
static reloc_howto_type *v850_elf_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
static void v850_elf_info_to_howto_rel
- PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+ PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
static void v850_elf_info_to_howto_rela
- PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+ PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
static bfd_reloc_status_type v850_elf_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static boolean v850_elf_is_local_label_name
+static bfd_boolean v850_elf_is_local_label_name
PARAMS ((bfd *, const char *));
-static boolean v850_elf_relocate_section
+static bfd_boolean v850_elf_relocate_section
PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static bfd_reloc_status_type v850_elf_perform_relocation
PARAMS ((bfd *, unsigned int, bfd_vma, bfd_byte *));
-static boolean v850_elf_check_relocs
+static bfd_boolean v850_elf_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
static void remember_hi16s_reloc
PARAMS ((bfd *, bfd_vma, bfd_byte *));
static bfd_byte * find_remembered_hi16s_reloc
- PARAMS ((bfd_vma, boolean *));
+ PARAMS ((bfd_vma, bfd_boolean *));
static bfd_reloc_status_type v850_elf_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, bfd_vma,
bfd_vma, bfd_vma, struct bfd_link_info *, asection *, int));
-static boolean v850_elf_object_p
+static bfd_boolean v850_elf_object_p
PARAMS ((bfd *));
-static boolean v850_elf_fake_sections
- PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
+static bfd_boolean v850_elf_fake_sections
+ PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
static void v850_elf_final_write_processing
- PARAMS ((bfd *, boolean));
-static boolean v850_elf_set_private_flags
+ PARAMS ((bfd *, bfd_boolean));
+static bfd_boolean v850_elf_set_private_flags
PARAMS ((bfd *, flagword));
-static boolean v850_elf_merge_private_bfd_data
+static bfd_boolean v850_elf_merge_private_bfd_data
PARAMS ((bfd *, bfd *));
-static boolean v850_elf_print_private_bfd_data
+static bfd_boolean v850_elf_print_private_bfd_data
PARAMS ((bfd *, PTR));
-static boolean v850_elf_section_from_bfd_section
+static bfd_boolean v850_elf_section_from_bfd_section
PARAMS ((bfd *, asection *, int *));
static void v850_elf_symbol_processing
PARAMS ((bfd *, asymbol *));
-static boolean v850_elf_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+static bfd_boolean v850_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
-static boolean v850_elf_link_output_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const char *,
- Elf_Internal_Sym *, asection *));
-static boolean v850_elf_section_from_shdr
+static bfd_boolean v850_elf_link_output_symbol_hook
+ PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *));
+static bfd_boolean v850_elf_section_from_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
-static boolean v850_elf_gc_sweep_hook
+static bfd_boolean v850_elf_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
static asection * v850_elf_gc_mark_hook
Elf_Internal_Sym *));
static bfd_reloc_status_type v850_elf_ignore_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static boolean v850_elf_relax_delete_bytes
+static bfd_boolean v850_elf_relax_delete_bytes
PARAMS ((bfd *, asection *, bfd_vma, bfd_vma, int));
-static boolean v850_elf_relax_section
- PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+static bfd_boolean v850_elf_relax_section
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
/* Note: It is REQUIRED that the 'type' value of each entry
in this array match the index of the entry in the array. */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_NONE", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* A PC relative 9 bit branch. */
HOWTO (R_V850_9_PCREL, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
26, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_9_PCREL", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x00ffffff, /* src_mask */
0x00ffffff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
/* A PC relative 22 bit branch. */
HOWTO (R_V850_22_PCREL, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
22, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
7, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_22_PCREL", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x07ffff80, /* src_mask */
0x07ffff80, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
/* High 16 bits of symbol value. */
HOWTO (R_V850_HI16_S, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_HI16_S", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* High 16 bits of symbol value. */
HOWTO (R_V850_HI16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_HI16", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* Low 16 bits of symbol value. */
HOWTO (R_V850_LO16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_LO16", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* Simple 32bit reloc. */
- HOWTO (R_V850_32, /* type */
+ HOWTO (R_V850_ABS32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
- "R_V850_32", /* name */
- false, /* partial_inplace */
+ "R_V850_ABS32", /* name */
+ FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* Simple 16bit reloc. */
HOWTO (R_V850_16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_16", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* Simple 8bit reloc. */
HOWTO (R_V850_8, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_8", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 16 bit offset from the short data area pointer. */
HOWTO (R_V850_SDA_16_16_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_SDA_16_16_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 15 bit offset from the short data area pointer. */
HOWTO (R_V850_SDA_15_16_OFFSET, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
1, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_SDA_15_16_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xfffe, /* src_mask */
0xfffe, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 16 bit offset from the zero data area pointer. */
HOWTO (R_V850_ZDA_16_16_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_ZDA_16_16_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 15 bit offset from the zero data area pointer. */
HOWTO (R_V850_ZDA_15_16_OFFSET, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
1, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_ZDA_15_16_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xfffe, /* src_mask */
0xfffe, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 6 bit offset from the tiny data area pointer. */
HOWTO (R_V850_TDA_6_8_OFFSET, /* type */
2, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
1, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_TDA_6_8_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x7e, /* src_mask */
0x7e, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 8 bit offset from the tiny data area pointer. */
HOWTO (R_V850_TDA_7_8_OFFSET, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_TDA_7_8_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x7f, /* src_mask */
0x7f, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 7 bit offset from the tiny data area pointer. */
HOWTO (R_V850_TDA_7_7_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
7, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_TDA_7_7_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x7f, /* src_mask */
0x7f, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 16 bit offset from the tiny data area pointer! */
HOWTO (R_V850_TDA_16_16_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_TDA_16_16_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xfff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 5 bit offset from the tiny data area pointer. */
HOWTO (R_V850_TDA_4_5_OFFSET, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
5, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_TDA_4_5_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x0f, /* src_mask */
0x0f, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 4 bit offset from the tiny data area pointer. */
HOWTO (R_V850_TDA_4_4_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
4, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_TDA_4_4_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x0f, /* src_mask */
0x0f, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 16 bit offset from the short data area pointer. */
HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xfffe0020, /* src_mask */
0xfffe0020, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 16 bit offset from the zero data area pointer. */
HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xfffe0020, /* src_mask */
0xfffe0020, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 6 bit offset from the call table base pointer. */
HOWTO (R_V850_CALLT_6_7_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
7, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_CALLT_6_7_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0x3f, /* src_mask */
0x3f, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* 16 bit offset from the call table base pointer. */
HOWTO (R_V850_CALLT_16_16_OFFSET, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
v850_elf_reloc, /* special_function */
"R_V850_CALLT_16_16_OFFSET", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable hierarchy */
HOWTO (R_V850_GNU_VTINHERIT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
NULL, /* special_function */
"R_V850_GNU_VTINHERIT", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable member usage */
HOWTO (R_V850_GNU_VTENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_V850_GNU_VTENTRY", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* Indicates a .longcall pseudo-op. The compiler will generate a .longcall
pseudo-op when it finds a function call which can be relaxed. */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
v850_elf_ignore_reloc, /* special_function */
"R_V850_LONGCALL", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
/* Indicates a .longjump pseudo-op. The compiler will generate a
.longjump pseudo-op when it finds a branch which can be relaxed. */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
v850_elf_ignore_reloc, /* special_function */
"R_V850_LONGJUMP", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
HOWTO (R_V850_ALIGN, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_unsigned, /* complain_on_overflow */
v850_elf_ignore_reloc, /* special_function */
"R_V850_ALIGN", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
+
+ /* Simple pc-relative 32bit reloc. */
+ HOWTO (R_V850_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
/* Map BFD reloc types to V850 ELF reloc types. */
{ BFD_RELOC_HI16_S, R_V850_HI16_S },
{ BFD_RELOC_HI16, R_V850_HI16 },
{ BFD_RELOC_LO16, R_V850_LO16 },
- { BFD_RELOC_32, R_V850_32 },
+ { BFD_RELOC_32, R_V850_ABS32 },
+ { BFD_RELOC_32_PCREL, R_V850_REL32 },
{ BFD_RELOC_16, R_V850_16 },
{ BFD_RELOC_8, R_V850_8 },
{ BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
static reloc_howto_type *
v850_elf_reloc_type_lookup (abfd, code)
- bfd * abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ bfd_reloc_code_real_type code;
{
unsigned int i;
static void
v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
- bfd * abfd ATTRIBUTE_UNUSED;
- arelent * cache_ptr;
- Elf32_Internal_Rel * dst;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ arelent *cache_ptr;
+ Elf_Internal_Rela *dst;
{
unsigned int r_type;
/* Set the howto pointer for a V850 ELF reloc (type RELA). */
static void
v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)
- bfd * abfd ATTRIBUTE_UNUSED;
- arelent * cache_ptr;
- Elf32_Internal_Rela *dst;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ arelent * cache_ptr;
+ Elf_Internal_Rela *dst;
{
unsigned int r_type;
allocate space in the global offset table or procedure linkage
table. */
-static boolean
+static bfd_boolean
v850_elf_check_relocs (abfd, info, sec, relocs)
- bfd * abfd;
- struct bfd_link_info * info;
- asection * sec;
- const Elf_Internal_Rela * relocs;
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
{
- boolean ret = true;
+ bfd_boolean ret = TRUE;
bfd *dynobj;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
int other = 0;
const char *common = (const char *)0;
- if (info->relocateable)
- return true;
+ if (info->relocatable)
+ return TRUE;
#ifdef DEBUG
- fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
- bfd_get_section_name (abfd, sec),
- bfd_archive_filename (abfd));
+ _bfd_error_handler ("v850_elf_check_relocs called for section %A in %B",
+ sec, abfd);
#endif
dynobj = elf_hash_table (info)->dynobj;
case R_V850_HI16_S:
case R_V850_HI16:
case R_V850_LO16:
- case R_V850_32:
+ case R_V850_ABS32:
+ case R_V850_REL32:
case R_V850_16:
case R_V850_8:
case R_V850_CALLT_6_7_OFFSET:
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_V850_GNU_VTINHERIT:
- if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
- return false;
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
break;
/* This relocation describes which C++ vtable entries
are actually used. Record for later use during GC. */
case R_V850_GNU_VTENTRY:
- if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
- return false;
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
break;
case R_V850_SDA_16_16_SPLIT_OFFSET:
bfd_set_error (bfd_error_bad_value);
h->other |= V850_OTHER_ERROR;
- ret = false;
+ ret = FALSE;
}
}
more than once, as the second attempted retry failed.
In the current version, the entry is not deleted, instead we set
- the field 'found' to true. If a second lookup matches the same
+ the field 'found' to TRUE. If a second lookup matches the same
entry, then we know that the hi16s reloc has already been updated
and does not need to be updated a second time.
typedef struct hi16s_location
{
- bfd_vma addend;
- bfd_byte * address;
+ bfd_vma addend;
+ bfd_byte *address;
unsigned long counter;
- boolean found;
- struct hi16s_location * next;
+ bfd_boolean found;
+ struct hi16s_location *next;
}
hi16s_location;
-static hi16s_location * previous_hi16s;
-static hi16s_location * free_hi16s;
-static unsigned long hi16s_counter;
+static hi16s_location *previous_hi16s;
+static hi16s_location *free_hi16s;
+static unsigned long hi16s_counter;
static void
remember_hi16s_reloc (abfd, addend, address)
- bfd * abfd;
- bfd_vma addend;
- bfd_byte * address;
+ bfd *abfd;
+ bfd_vma addend;
+ bfd_byte *address;
{
hi16s_location * entry = NULL;
bfd_size_type amt = sizeof (* free_hi16s);
entry->addend = addend;
entry->address = address;
entry->counter = hi16s_counter ++;
- entry->found = false;
+ entry->found = FALSE;
entry->next = previous_hi16s;
previous_hi16s = entry;
static bfd_byte *
find_remembered_hi16s_reloc (addend, already_found)
- bfd_vma addend;
- boolean * already_found;
+ bfd_vma addend;
+ bfd_boolean *already_found;
{
- hi16s_location * match = NULL;
- hi16s_location * entry;
- hi16s_location * previous = NULL;
- hi16s_location * prev;
- bfd_byte * addr;
+ hi16s_location *match = NULL;
+ hi16s_location *entry;
+ hi16s_location *previous = NULL;
+ hi16s_location *prev;
+ bfd_byte *addr;
/* Search the table. Record the most recent entry that matches. */
for (entry = previous_hi16s; entry; entry = entry->next)
/* Extract the address. */
addr = match->address;
- /* Remeber if this entry has already been used before. */
+ /* Remember if this entry has already been used before. */
if (already_found)
* already_found = match->found;
/* Note that this entry has now been used. */
- match->found = true;
+ match->found = TRUE;
return addr;
}
/* FIXME: The code here probably ought to be removed and the code in reloc.c
- allowed to do its stuff instead. At least for most of the relocs, anwyay. */
+ allowed to do its stuff instead. At least for most of the relocs, anyway. */
static bfd_reloc_status_type
v850_elf_perform_relocation (abfd, r_type, addend, address)
/* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
return bfd_reloc_notsupported;
- case R_V850_32:
+ case R_V850_REL32:
+ case R_V850_ABS32:
bfd_put_32 (abfd, addend, address);
return bfd_reloc_ok;
|| (OVERFLOWS (addend, insn)
&& ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))
{
- boolean already_updated;
- bfd_byte * hi16s_address = find_remembered_hi16s_reloc
+ bfd_boolean already_updated;
+ bfd_byte *hi16s_address = find_remembered_hi16s_reloc
(addend, & already_updated);
/* Amend the matching HI16_S relocation. */
static bfd_reloc_status_type
v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
- bfd * abfd ATTRIBUTE_UNUSED;
- arelent * reloc;
- asymbol * symbol;
- PTR data ATTRIBUTE_UNUSED;
- asection * isection;
- bfd * obfd;
- char ** err ATTRIBUTE_UNUSED;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ arelent *reloc;
+ asymbol *symbol;
+ PTR data ATTRIBUTE_UNUSED;
+ asection *isection;
+ bfd *obfd;
+ char **err ATTRIBUTE_UNUSED;
{
long relocation;
/* We handle final linking of some relocs ourselves. */
/* Is the address of the relocation really within the section? */
- if (reloc->address > isection->_cooked_size)
+ if (reloc->address > bfd_get_section_limit (abfd, isection))
return bfd_reloc_outofrange;
- /* Work out which section the relocation is targetted at and the
+ /* Work out which section the relocation is targeted at and the
initial relocation command value. */
- if (reloc->howto->pc_relative == true)
+ if (reloc->howto->pc_relative)
return bfd_reloc_ok;
/* Get symbol value. (Common symbols are special.) */
static bfd_reloc_status_type
v850_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;
+ 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;
}
\f
-static boolean
+static bfd_boolean
v850_elf_is_local_label_name (abfd, name)
- bfd * abfd ATTRIBUTE_UNUSED;
- const char * name;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ const char *name;
{
return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
|| (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
input_section, contents, offset, value,
addend, info, sym_sec, is_local)
- reloc_howto_type * howto;
- bfd * input_bfd;
- bfd * output_bfd ATTRIBUTE_UNUSED;
- asection * input_section;
- bfd_byte * contents;
- bfd_vma offset;
- bfd_vma value;
- bfd_vma addend;
- struct bfd_link_info * info;
- asection * sym_sec;
- int is_local ATTRIBUTE_UNUSED;
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd *output_bfd ATTRIBUTE_UNUSED;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma offset;
+ bfd_vma value;
+ bfd_vma addend;
+ struct bfd_link_info *info;
+ asection *sym_sec;
+ int is_local ATTRIBUTE_UNUSED;
{
- unsigned int r_type = howto->type;
- bfd_byte * hit_data = contents + offset;
+ unsigned int r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
/* Adjust the value according to the relocation. */
switch (r_type)
value = SEXT24 (value);
break;
+ case R_V850_REL32:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+ break;
+
case R_V850_HI16_S:
case R_V850_HI16:
case R_V850_LO16:
case R_V850_16:
- case R_V850_32:
+ case R_V850_ABS32:
case R_V850_8:
break;
return bfd_reloc_undefined;
/* Get the value of __gp. */
- h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
+ h = bfd_link_hash_lookup (info->hash, "__gp", FALSE, FALSE, TRUE);
if (h == (struct bfd_link_hash_entry *) NULL
|| h->type != bfd_link_hash_defined)
return bfd_reloc_gp_not_found;
struct bfd_link_hash_entry * h;
/* Get the value of __ep. */
- h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
+ h = bfd_link_hash_lookup (info->hash, "__ep", FALSE, FALSE, TRUE);
if (h == (struct bfd_link_hash_entry *) NULL
|| h->type != bfd_link_hash_defined)
return bfd_reloc_ep_not_found;
struct bfd_link_hash_entry * h;
/* Get the value of __ctbp. */
- h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
+ h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
if (h == (struct bfd_link_hash_entry *) NULL
|| h->type != bfd_link_hash_defined)
return bfd_reloc_ctbp_not_found;
return bfd_reloc_undefined;
/* Get the value of __ctbp. */
- h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
+ h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
if (h == (struct bfd_link_hash_entry *) NULL
|| h->type != bfd_link_hash_defined)
return bfd_reloc_ctbp_not_found;
\f
/* Relocate an V850 ELF section. */
-static boolean
+static bfd_boolean
v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
contents, relocs, local_syms, local_sections)
- bfd * output_bfd;
- struct bfd_link_info * info;
- bfd * input_bfd;
- asection * input_section;
- bfd_byte * contents;
- Elf_Internal_Rela * relocs;
- Elf_Internal_Sym * local_syms;
- asection ** local_sections;
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
{
- Elf_Internal_Shdr * symtab_hdr;
- struct elf_link_hash_entry ** sym_hashes;
- Elf_Internal_Rela * rel;
- Elf_Internal_Rela * relend;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
- if (info->relocateable)
- return true;
+ if (info->relocatable)
+ return TRUE;
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
(info, "no hash table available",
NULL, input_bfd, input_section, (bfd_vma) 0);
- return false;
+ return FALSE;
}
/* Reset the list of remembered HI16S relocs to empty. */
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
{
- int r_type;
- reloc_howto_type * howto;
- unsigned long r_symndx;
- Elf_Internal_Sym * sym;
- asection * sec;
- struct elf_link_hash_entry * h;
- bfd_vma relocation;
- bfd_reloc_status_type r;
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
{
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
- relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
#if 0
{
char * name;
}
else
{
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ bfd_boolean unresolved_reloc, warned;
- if (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- {
- sec = h->root.u.def.section;
- relocation = (h->root.u.def.value
- + sec->output_section->vma
- + sec->output_offset);
-#if 0
- fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
- sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
-#endif
- }
- else if (h->root.type == bfd_link_hash_undefweak)
- {
-#if 0
- fprintf (stderr, "undefined: sec: %s, name: %s\n",
- sec->name, h->root.root.string);
-#endif
- relocation = 0;
- }
- else
- {
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, true)))
- return false;
-#if 0
- fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
-#endif
- relocation = 0;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
/* FIXME: We should use the addend, but the COFF relocations don't. */
{
case bfd_reloc_overflow:
if (! ((*info->callbacks->reloc_overflow)
- (info, name, howto->name, (bfd_vma) 0,
- input_bfd, input_section, rel->r_offset)))
- return false;
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
break;
case bfd_reloc_undefined:
if (! ((*info->callbacks->undefined_symbol)
(info, name, input_bfd, input_section,
- rel->r_offset, true)))
- return false;
+ rel->r_offset, TRUE)))
+ return FALSE;
break;
case bfd_reloc_outofrange:
if (!((*info->callbacks->warning)
(info, msg, name, input_bfd, input_section,
rel->r_offset)))
- return false;
+ return FALSE;
break;
}
}
}
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
v850_elf_gc_sweep_hook (abfd, info, sec, relocs)
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info ATTRIBUTE_UNUSED;
const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
{
/* No got and plt entries for v850-elf. */
- return true;
+ return TRUE;
}
static asection *
/* Set the right machine number. */
-static boolean
+static bfd_boolean
v850_elf_object_p (abfd)
bfd *abfd;
{
case E_V850E_ARCH:
bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e);
break;
+ case E_V850E1_ARCH:
+ bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e1);
+ break;
}
- return true;
+ return TRUE;
}
/* Store the machine number in the flags field. */
static void
v850_elf_final_write_processing (abfd, linker)
- bfd * abfd;
- boolean linker ATTRIBUTE_UNUSED;
+ bfd *abfd;
+ bfd_boolean linker ATTRIBUTE_UNUSED;
{
unsigned long val;
switch (bfd_get_mach (abfd))
{
- default:
+ default:
case bfd_mach_v850: val = E_V850_ARCH; break;
case bfd_mach_v850e: val = E_V850E_ARCH; break;
+ case bfd_mach_v850e1: val = E_V850E1_ARCH; break;
}
elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
/* Function to keep V850 specific file flags. */
-static boolean
+static bfd_boolean
v850_elf_set_private_flags (abfd, flags)
- bfd * abfd;
+ bfd *abfd;
flagword flags;
{
BFD_ASSERT (!elf_flags_init (abfd)
|| elf_elfheader (abfd)->e_flags == flags);
elf_elfheader (abfd)->e_flags = flags;
- elf_flags_init (abfd) = true;
- return true;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
}
/* Merge backend specific data from an object file
to the output object file when linking. */
-static boolean
+static bfd_boolean
v850_elf_merge_private_bfd_data (ibfd, obfd)
- bfd * ibfd;
- bfd * obfd;
+ bfd *ibfd;
+ bfd *obfd;
{
flagword out_flags;
flagword in_flags;
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return true;
+ return TRUE;
in_flags = elf_elfheader (ibfd)->e_flags;
out_flags = elf_elfheader (obfd)->e_flags;
unitialised values, which surprise surprise, correspond
to the default values. */
if (bfd_get_arch_info (ibfd)->the_default)
- return true;
+ return TRUE;
- elf_flags_init (obfd) = true;
+ elf_flags_init (obfd) = TRUE;
elf_elfheader (obfd)->e_flags = in_flags;
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
&& bfd_get_arch_info (obfd)->the_default)
return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
- return true;
+ return TRUE;
}
/* Check flag compatibility. */
if (in_flags == out_flags)
- return true;
+ return TRUE;
if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
&& (in_flags & EF_V850_ARCH) != E_V850_ARCH)
- _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),
- bfd_archive_filename (ibfd));
+ {
+ /* Allow v850e1 binaries to be linked with v850e binaries.
+ Set the output binary to v850e. */
+ if ((in_flags & EF_V850_ARCH) == E_V850E1_ARCH
+ && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
+ return TRUE;
+
+ if ((in_flags & EF_V850_ARCH) == E_V850E_ARCH
+ && (out_flags & EF_V850_ARCH) == E_V850E1_ARCH)
+ {
+ elf_elfheader (obfd)->e_flags =
+ ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
+ return TRUE;
+ }
+
+ _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
+ ibfd);
+ }
- return true;
+ return TRUE;
}
/* Display the flags field. */
-static boolean
+static bfd_boolean
v850_elf_print_private_bfd_data (abfd, ptr)
- bfd * abfd;
- PTR ptr;
+ bfd *abfd;
+ PTR ptr;
{
FILE * file = (FILE *) ptr;
default:
case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
+ case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
}
fputc ('\n', file);
- return true;
+ return TRUE;
}
/* V850 ELF uses four common sections. One is the usual one, and the
/* Given a BFD section, try to locate the
corresponding ELF section index. */
-static boolean
+static bfd_boolean
v850_elf_section_from_bfd_section (abfd, sec, retval)
- bfd * abfd ATTRIBUTE_UNUSED;
- asection * sec;
- int * retval;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ int *retval;
{
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
*retval = SHN_V850_SCOMMON;
else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
*retval = SHN_V850_ZCOMMON;
else
- return false;
+ return FALSE;
- return true;
+ return TRUE;
}
/* Handle the special V850 section numbers that a symbol may use. */
static void
v850_elf_symbol_processing (abfd, asym)
- bfd * abfd;
- asymbol * asym;
+ bfd *abfd;
+ asymbol *asym;
{
elf_symbol_type * elfsym = (elf_symbol_type *) asym;
unsigned int indx;
/* Hook called by the linker routine which adds symbols from an object
file. We must handle the special v850 section numbers here. */
-static boolean
+static bfd_boolean
v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
- bfd * abfd;
- struct bfd_link_info * info ATTRIBUTE_UNUSED;
- const Elf_Internal_Sym * sym;
- const char ** namep ATTRIBUTE_UNUSED;
- flagword * flagsp ATTRIBUTE_UNUSED;
- asection ** secp;
- bfd_vma * valp;
+ bfd *abfd;
+ struct bfd_link_info *info ATTRIBUTE_UNUSED;
+ Elf_Internal_Sym *sym;
+ const char **namep ATTRIBUTE_UNUSED;
+ flagword *flagsp ATTRIBUTE_UNUSED;
+ asection **secp;
+ bfd_vma *valp;
{
unsigned int indx = sym->st_shndx;
break;
}
- return true;
+ return TRUE;
}
-static boolean
-v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
- bfd * abfd ATTRIBUTE_UNUSED;
- struct bfd_link_info * info ATTRIBUTE_UNUSED;
- const char * name ATTRIBUTE_UNUSED;
- Elf_Internal_Sym * sym;
- asection * input_sec;
+static bfd_boolean
+v850_elf_link_output_symbol_hook (info, name, sym, input_sec, h)
+ struct bfd_link_info *info ATTRIBUTE_UNUSED;
+ const char *name ATTRIBUTE_UNUSED;
+ Elf_Internal_Sym *sym;
+ asection *input_sec;
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED;
{
/* If we see a common symbol, which implies a relocatable link, then
if a symbol was in a special common section in an input file, mark
sym->st_shndx = SHN_V850_ZCOMMON;
}
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
v850_elf_section_from_shdr (abfd, hdr, name)
- bfd * abfd;
- Elf_Internal_Shdr * hdr;
- const char * name;
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ const char *name;
{
/* There ought to be a place to keep ELF backend specific flags, but
at the moment there isn't one. We just keep track of the
sections by their name, instead. */
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
- return false;
+ return FALSE;
switch (hdr->sh_type)
{
(bfd_get_section_flags (abfd,
hdr->bfd_section)
| SEC_IS_COMMON)))
- return false;
+ return FALSE;
}
- return true;
+ return TRUE;
}
/* Set the correct type for a V850 ELF section. We do this
by the section name, which is a hack, but ought to work. */
-static boolean
+static bfd_boolean
v850_elf_fake_sections (abfd, hdr, sec)
- bfd * abfd ATTRIBUTE_UNUSED;
- Elf32_Internal_Shdr * hdr;
- asection * sec;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ Elf_Internal_Shdr *hdr;
+ asection *sec;
{
register const char * name;
else if (strcmp (name, ".zcommon") == 0)
hdr->sh_type = SHT_V850_ZCOMMON;
- return true;
+ return TRUE;
}
/* Delete some bytes from a section while relaxing. */
-static boolean
+static bfd_boolean
v850_elf_relax_delete_bytes (abfd, sec, addr, toaddr, count)
- bfd * abfd;
- asection * sec;
- bfd_vma addr;
- bfd_vma toaddr;
- int count;
+ bfd *abfd;
+ asection *sec;
+ bfd_vma addr;
+ bfd_vma toaddr;
+ int count;
{
- Elf_Internal_Shdr * symtab_hdr;
- Elf32_External_Sym * extsyms;
- Elf32_External_Sym * esym;
- Elf32_External_Sym * esymend;
- int index;
- unsigned int sec_shndx;
- bfd_byte * contents;
- Elf_Internal_Rela * irel;
- Elf_Internal_Rela * irelend;
- struct elf_link_hash_entry * sym_hash;
- Elf_Internal_Shdr * shndx_hdr;
- Elf_External_Sym_Shndx * shndx;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf32_External_Sym *extsyms;
+ Elf32_External_Sym *esym;
+ Elf32_External_Sym *esymend;
+ int index;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ struct elf_link_hash_entry *sym_hash;
+ Elf_Internal_Shdr *shndx_hdr;
+ Elf_External_Sym_Shndx *shndx;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
/* Get the new reloc address. */
raddr = irel->r_offset;
if ((raddr >= (addr + count) && raddr < toaddr))
- irel->r_offset -= count;
+ irel->r_offset -= count;
if (raddr >= addr && raddr < addr + count)
{
(int) R_V850_NONE);
continue;
}
-
+
if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
continue;
extsyms + ELF32_R_SYM (irel->r_info),
shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
& isym);
-
+
if (isym.st_shndx != sec_shndx)
continue;
sec->output_section->vma, sec->output_offset, irel->r_addend);
#endif
}
-
+
paddr = symval + irel->r_addend;
-
+
if ( (symval >= addr + count && symval < toaddr)
&& (paddr < addr + count || paddr >= toaddr))
irel->r_addend += count;
isym.st_value -= count;
if (isym.st_value + isym.st_size >= toaddr)
- isym.st_size += count;
-
+ isym.st_size += count;
+
bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
}
else if (isym.st_shndx == sec_shndx
++ shndx;
}
- return true;
+ return TRUE;
}
#define NOP_OPCODE (0x0000)
-#define MOVHI 0x0640 /* 4byte */
+#define MOVHI 0x0640 /* 4byte */
#define MOVHI_MASK 0x07e0
-#define MOVHI_R1(insn) ((insn) & 0x1f) /* 4byte */
+#define MOVHI_R1(insn) ((insn) & 0x1f) /* 4byte */
#define MOVHI_R2(insn) ((insn) >> 11)
#define MOVEA 0x0620 /* 2byte */
#define MOVEA_MASK 0x07e0
#define JMP_R_MASK 0xFFE0
#define JMP_R1(insn) ((insn) & 0x1f)
-static boolean
+static bfd_boolean
v850_elf_relax_section (abfd, sec, link_info, again)
- bfd * abfd;
- asection * sec;
- struct bfd_link_info * link_info;
- boolean * again;
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ bfd_boolean *again;
{
- Elf_Internal_Shdr * symtab_hdr;
- Elf_Internal_Rela * internal_relocs;
- Elf_Internal_Rela * irel;
- Elf_Internal_Rela * irelend;
- Elf_Internal_Rela * irelalign = NULL;
- Elf_Internal_Sym * isymbuf = NULL;
- bfd_byte * contents = NULL;
- bfd_vma addr = 0;
- bfd_vma toaddr;
- int align_pad_size = 0;
- boolean result = true;
-
- * again = false;
-
- if (link_info->relocateable
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Rela *irelalign = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ bfd_byte *contents = NULL;
+ bfd_vma addr = 0;
+ bfd_vma toaddr;
+ int align_pad_size = 0;
+ bfd_boolean result = TRUE;
+
+ *again = FALSE;
+
+ if (link_info->relocatable
|| (sec->flags & SEC_RELOC) == 0
|| sec->reloc_count == 0)
- return true;
-
- /* If this is the first time we have been called
- for this section, initialize the cooked size. */
- if (sec->_cooked_size == 0)
- sec->_cooked_size = sec->_raw_size;
+ return TRUE;
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
- internal_relocs = (_bfd_elf32_link_read_relocs
+ internal_relocs = (_bfd_elf_link_read_relocs
(abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
irelend = internal_relocs + sec->reloc_count;
-
- while (addr < sec->_cooked_size)
+
+ while (addr < sec->size)
{
- toaddr = sec->_cooked_size;
+ toaddr = sec->size;
for (irel = internal_relocs; irel < irelend; irel ++)
if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
&& irel->r_offset > addr
&& irel->r_offset < toaddr)
toaddr = irel->r_offset;
-
+
#ifdef DEBUG_RELAX
fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
addr, toaddr, align_pad_size);
#endif
if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
toaddr, align_pad_size))
- goto error_return;
+ goto error_return;
for (i = BFD_ALIGN (toaddr - align_pad_size, 1);
(i + 1) < toaddr; i += 2)
for (irel = internal_relocs; irel < irelend; irel++)
{
- bfd_vma laddr;
- bfd_vma addend;
- bfd_vma symval;
- int insn[5];
- int no_match = -1;
- Elf_Internal_Rela * hi_irelfn;
- Elf_Internal_Rela * lo_irelfn;
- Elf_Internal_Rela * irelcall;
- bfd_signed_vma foff;
+ bfd_vma laddr;
+ bfd_vma addend;
+ bfd_vma symval;
+ int insn[5];
+ int no_match = -1;
+ Elf_Internal_Rela *hi_irelfn;
+ Elf_Internal_Rela *lo_irelfn;
+ Elf_Internal_Rela *irelcall;
+ bfd_signed_vma foff;
if (! (irel->r_offset >= addr && irel->r_offset < toaddr
&& (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
contents = elf_section_data (sec)->this_hdr.contents;
else
{
- contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
- if (contents == NULL)
- goto error_return;
-
- if (! bfd_get_section_contents (abfd, sec, contents,
- (file_ptr) 0, sec->_raw_size))
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
goto error_return;
}
}
if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
{
/* Check code for -mlong-calls output. */
- if (laddr + 16 <= (bfd_vma) sec->_raw_size)
+ if (laddr + 16 <= (bfd_vma) sec->size)
{
insn[0] = bfd_get_16 (abfd, contents + laddr);
insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
-
+
if ((insn[0] & MOVHI_MASK) != MOVHI
|| MOVHI_R1 (insn[0]) != 0)
no_match = 0;
bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
continue;
- }
+ }
/* Get the reloc for the address from which the register is
being loaded. This reloc will tell us which function is
actually being called. */
for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
if (hi_irelfn->r_offset == laddr + 2
- && ELF32_R_TYPE (hi_irelfn->r_info)
+ && ELF32_R_TYPE (hi_irelfn->r_info)
== (int) R_V850_HI16_S)
break;
continue;
}
-
+
if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
{
Elf_Internal_Sym * isym;
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
{
- Elf_Internal_Sym * isym;
- asection * sym_sec;
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
/* A local symbol. */
isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
-
+
if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
else if (isym->st_shndx == SHN_ABS)
else
{
unsigned long indx;
- struct elf_link_hash_entry * h;
+ struct elf_link_hash_entry *h;
/* An external symbol. */
indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
elf_section_data (sec)->relocs = internal_relocs;
elf_section_data (sec)->this_hdr.contents = contents;
symtab_hdr->contents = (bfd_byte *) isymbuf;
-
+
/* Replace the long call with a jarl. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
contents + irel->r_offset);
- hi_irelfn->r_info =
+ hi_irelfn->r_info =
ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
lo_irelfn->r_info =
ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
{
/* Check code for -mlong-jumps output. */
- if (laddr + 10 <= (bfd_vma) sec->_raw_size)
+ if (laddr + 10 <= (bfd_vma) sec->size)
{
insn[0] = bfd_get_16 (abfd, contents + laddr);
insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
actually being called. */
for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
if (hi_irelfn->r_offset == laddr + 2
- && ELF32_R_TYPE (hi_irelfn->r_info) == (int) R_V850_HI16_S)
+ && ELF32_R_TYPE (hi_irelfn->r_info) == (int) R_V850_HI16_S)
break;
for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
continue;
}
-
+
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
{
/* Replace the long jump with a jr. */
irel->r_info =
- ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
-
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
+
irel->r_addend = addend;
addend = 0;
#ifdef DEBUG_RELAX
fprintf (stderr, "relax pad %d shorten %d -> %d\n",
align_pad_size,
- sec->_cooked_size,
- sec->_cooked_size - align_pad_size);
+ sec->size,
+ sec->size - align_pad_size);
#endif
- sec->_cooked_size -= align_pad_size;
+ sec->size -= align_pad_size;
}
finish:
return result;
error_return:
- result = false;
+ result = FALSE;
goto finish;
}
+
+static struct bfd_elf_special_section const v850_elf_special_sections[]=
+{
+ { ".sdata", 6, -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_GPREL) },
+ { ".rosdata", 8, -2, SHT_PROGBITS, (SHF_ALLOC
+ + SHF_V850_GPREL) },
+ { ".sbss", 5, -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_GPREL) },
+ { ".scommon", 8, -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_GPREL) },
+ { ".tdata", 6, -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_EPREL) },
+ { ".tbss", 5, -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_EPREL) },
+ { ".tcommon", 8, -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { ".zdata", 6, -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { ".rozdata", 8, -2, SHT_PROGBITS, (SHF_ALLOC
+ + SHF_V850_R0REL) },
+ { ".zbss", 5, -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { ".zcommon", 8, -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { ".call_table_data", 16, 0, SHT_PROGBITS, (SHF_ALLOC
+ + SHF_WRITE) },
+ { ".call_table_text", 16, 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_EXECINSTR) },
+ { NULL, 0, 0, 0, 0 }
+};
\f
#define TARGET_LITTLE_SYM bfd_elf32_v850_vec
#define TARGET_LITTLE_NAME "elf32-v850"
#define elf_backend_fake_sections v850_elf_fake_sections
#define elf_backend_gc_mark_hook v850_elf_gc_mark_hook
#define elf_backend_gc_sweep_hook v850_elf_gc_sweep_hook
+#define elf_backend_special_sections v850_elf_special_sections
#define elf_backend_can_gc_sections 1
#define elf_backend_rela_normal 1