/* Hitachi SH specific support for 32-bit ELF
- Copyright 1996, 97, 98, 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
Contributed by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
-static reloc_howto_type sh_elf_howto_table[] = {
+static reloc_howto_type sh_elf_howto_table[] =
+{
/* No relocation. */
HOWTO (R_SH_NONE, /* type */
0, /* rightshift */
/* This structure is used to map BFD reloc codes to SH ELF relocs. */
-struct elf_reloc_map {
+struct elf_reloc_map
+{
bfd_reloc_code_real_type bfd_reloc_val;
unsigned char elf_reloc_val;
};
/* An array mapping BFD reloc codes to SH ELF relocs. */
-static const struct elf_reloc_map sh_reloc_map[] = {
+static const struct elf_reloc_map sh_reloc_map[] =
+{
{ BFD_RELOC_NONE, R_SH_NONE },
{ BFD_RELOC_32, R_SH_DIR32 },
{ BFD_RELOC_CTOR, R_SH_DIR32 },
/* First entry in an absolute procedure linkage table look like this. */
-static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] =
+{
0xd0, 0x04, /* mov.l 1f,r0 */
0xd2, 0x05, /* mov.l 2f,r2 */
0x60, 0x02, /* mov.l @r0,r0 */
0, 0, 0, 0, /* 2: replaced with address of .got.plt + 4. */
};
-static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] =
+{
0x04, 0xd0, /* mov.l 1f,r0 */
0x05, 0xd2, /* mov.l 2f,r2 */
0x02, 0x60, /* mov.l @r0,r0 */
/* Sebsequent entries in an absolute procedure linkage table look like
this. */
-static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] =
+{
0xd0, 0x04, /* mov.l 1f,r0 */
0x60, 0x02, /* mov.l @r0,r0 */
0xd2, 0x02, /* mov.l 0f,r2 */
0, 0, 0, 0, /* 2: replaced with offset into relocation table. */
};
-static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] =
+{
0x04, 0xd0, /* mov.l 1f,r0 */
0x02, 0x60, /* mov.l @r0,r0 */
0x02, 0xd2, /* mov.l 0f,r2 */
/* Entries in a PIC procedure linkage table look like this. */
-static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] =
+{
0xd0, 0x04, /* mov.l 1f,r0 */
0x00, 0xce, /* mov.l @(r0,r12),r0 */
0x40, 0x2b, /* jmp @r0 */
0, 0, 0, 0 /* 2: replaced with offset into relocation table. */
};
-static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] =
+{
0x04, 0xd0, /* mov.l 1f,r0 */
0xce, 0x00, /* mov.l @(r0,r12),r0 */
0x2b, 0x40, /* jmp @r0 */
/* This structure keeps track of the number of PC relative relocs we
have copied for a given symbol. */
-struct elf_sh_pcrel_relocs_copied {
+struct elf_sh_pcrel_relocs_copied
+{
/* Next section. */
struct elf_sh_pcrel_relocs_copied *next;
/* A section in dynobj. */
/* sh ELF linker hash entry. */
-struct elf_sh_link_hash_entry {
+struct elf_sh_link_hash_entry
+{
struct elf_link_hash_entry root;
/* Number of PC relative relocs copied for this symbol. */
/* sh ELF linker hash table. */
-struct elf_sh_link_hash_table {
+struct elf_sh_link_hash_table
+{
struct elf_link_hash_table root;
};
return true;
}
-
\f
/* Relocate an SH ELF section. */
break;
case R_SH_IND12W:
+ relocation -= 4;
+ goto final_link_relocate;
+
case R_SH_DIR8WPN:
case R_SH_DIR8WPZ:
case R_SH_DIR8WPL:
- /* These should normally be handled by the assembler, but at
- least IND12W is generated by ourselves, so we must deal
- with it. */
- relocation -= 4;
- goto final_link_relocate;
+ /* If the reloc is against the start of this section, then
+ the assembler has already taken care of it and the reloc
+ is here only to assist in relaxing. If the reloc is not
+ against the start of this section, then it's against an
+ external symbol and we must deal with it ourselves. */
+ if (input_section->output_section->vma + input_section->output_offset
+ != relocation)
+ {
+ int disp = (relocation
+ - input_section->output_section->vma
+ - input_section->output_offset
+ - rel->r_offset);
+ int mask = 0;
+ switch (r_type)
+ {
+ case R_SH_DIR8WPN:
+ case R_SH_DIR8WPZ: mask = 1; break;
+ case R_SH_DIR8WPL: mask = 3; break;
+ default: mask = 0; break;
+ }
+ if (disp & mask)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
+ bfd_get_filename (input_section->owner),
+ (unsigned long) rel->r_offset));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ relocation -= 4;
+ goto final_link_relocate;
+ }
+ r = bfd_reloc_ok;
+ break;
default:
bfd_set_error (bfd_error_bad_value);
&& ELF_ST_BIND (sym->st_info) != STB_LOCAL)
&& ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
&& sym->st_shndx != SHN_COMMON))
- {
- return bfd_section_from_elf_index (abfd, sym->st_shndx);
- }
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
}
return NULL;
}
static boolean
sh_elf_copy_private_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
+ bfd * ibfd;
+ bfd * obfd;
{
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return true;