bfd/
[deliverable/binutils-gdb.git] / bfd / elf32-m32r.c
index 14aec619ef3cc39e34edb71cf1af957435df4e3c..f929d7dec6daabb2209f8d8985bb8cd2924897a5 100644 (file)
@@ -669,7 +669,7 @@ static reloc_howto_type m32r_elf_howto_table[] =
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_M32R_RELATIVE",             /* name */
+        "R_M32R_RELATIVE",     /* name */
         FALSE,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
@@ -678,15 +678,15 @@ static reloc_howto_type m32r_elf_howto_table[] =
   HOWTO (R_M32R_GOTOFF,        /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
+        24,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_M32R_GOTOFF",               /* name */
+        "R_M32R_GOTOFF",       /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
-        0xffffffff,            /* dst_mask */
+        0xffffff,              /* src_mask */
+        0xffffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* An PC Relative 24-bit relocation used when setting PIC offset
@@ -803,6 +803,48 @@ static reloc_howto_type m32r_elf_howto_table[] =
         0x0000ffff,            /* src_mask */
         0x0000ffff,            /* dst_mask */
         TRUE),                 /* pcrel_offset */
+
+  HOWTO (R_M32R_GOTOFF_HI_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_GOTOFF_HI_ULO",/* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_M32R_GOTOFF_HI_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 */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_M32R_GOTOFF_HI_SLO",/* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_M32R_GOTOFF_LO,     /* 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_GOTOFF_LO",    /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 };
 \f
 /* Handle the R_M32R_10_PCREL reloc.  */
@@ -859,13 +901,11 @@ m32r_elf_do_10_pcrel_reloc (abfd, howto, input_section, data, offset,
      bfd_vma addend;
 {
   bfd_signed_vma relocation;
-  bfd_size_type sz;
   unsigned long x;
   bfd_reloc_status_type status;
 
   /* Sanity check the address (offset in section).  */
-  sz = input_section->rawsize ? input_section->rawsize : input_section->size;
-  if (offset > sz)
+  if (offset > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
   relocation = symbol_value + addend;
@@ -930,7 +970,6 @@ m32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
 {
   bfd_reloc_status_type ret;
   bfd_vma relocation;
-  bfd_size_type sz;
   struct m32r_hi16 *n;
 
   /* This part is from bfd_elf_generic_reloc.
@@ -945,8 +984,7 @@ m32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
     }
 
   /* Sanity check the address (offset in section).  */
-  sz = input_section->rawsize ? input_section->rawsize : input_section->size;
-  if (reloc_entry->address > sz)
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
   ret = bfd_reloc_ok;
@@ -1099,7 +1137,6 @@ m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
 {
   bfd_reloc_status_type ret;
   bfd_vma relocation;
-  bfd_size_type sz;
   bfd_byte *inplace_address;
 
   /* This part is from bfd_elf_generic_reloc.
@@ -1120,8 +1157,7 @@ m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
      a section relative addend which is wrong.  */
 
   /* Sanity check the address (offset in section).  */
-  sz = input_section->rawsize ? input_section->rawsize : input_section->size;
-  if (reloc_entry->address > sz)
+  if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
     return bfd_reloc_outofrange;
 
   ret = bfd_reloc_ok;
@@ -1269,6 +1305,9 @@ static const struct m32r_reloc_map m32r_reloc_map[] =
   { BFD_RELOC_M32R_GOTPC_HI_ULO, R_M32R_GOTPC_HI_ULO },
   { BFD_RELOC_M32R_GOTPC_HI_SLO, R_M32R_GOTPC_HI_SLO },
   { BFD_RELOC_M32R_GOTPC_LO, R_M32R_GOTPC_LO },
+  { BFD_RELOC_M32R_GOTOFF_HI_ULO, R_M32R_GOTOFF_HI_ULO },
+  { BFD_RELOC_M32R_GOTOFF_HI_SLO, R_M32R_GOTOFF_HI_SLO },
+  { BFD_RELOC_M32R_GOTOFF_LO, R_M32R_GOTOFF_LO },
 };
 
 static reloc_howto_type *
@@ -2533,6 +2572,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
   bfd *dynobj;
   bfd_vma *local_got_offsets;
   asection *sgot, *splt, *sreloc;
+  bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
 
   dynobj = htab->root.dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
@@ -2566,8 +2606,8 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type < 0 || r_type >= (int) R_M32R_max)
        {
-         (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
-                                bfd_archive_filename (input_bfd),
+         (*_bfd_error_handler) (_("%B: unknown relocation type %d"),
+                                input_bfd,
                                 (int) r_type);
          bfd_set_error (bfd_error_bad_value);
          ret = FALSE;
@@ -2650,7 +2690,6 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       else
        {
          bfd_vma relocation;
-         bfd_size_type sz;
 
          /* This is a final link.  */
          sym = NULL;
@@ -2785,10 +2824,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            }
 
          /* Sanity check the address.  */
-         sz = (input_section->rawsize
-               ? input_section->rawsize
-               : input_section->size);
-         if (offset > input_section->size)
+         if (offset > high_address)
            {
              r = bfd_reloc_outofrange;
              goto check_reloc;
@@ -2796,6 +2832,31 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
          switch ((int) r_type)
            {
+            case R_M32R_GOTOFF:
+              /* Relocation is relative to the start of the global offset
+                 table (for ld24 rx, #uimm24). eg access at label+addend
+                
+                 ld24 rx. #label@GOTOFF + addend
+                 sub  rx, r12.  */
+
+              BFD_ASSERT (sgot != NULL);
+
+              relocation = -(relocation - sgot->output_section->vma);
+              rel->r_addend = -rel->r_addend;
+              break;
+
+            case R_M32R_GOTOFF_HI_ULO:
+            case R_M32R_GOTOFF_HI_SLO:
+            case R_M32R_GOTOFF_LO:
+             BFD_ASSERT (sgot != NULL);
+
+             relocation -= sgot->output_section->vma;
+
+             if ((r_type == R_M32R_GOTOFF_HI_SLO)
+                 && ((relocation + rel->r_addend) & 0x8000))
+               rel->r_addend += 0x10000;
+             break;
+
             case R_M32R_GOTPC24:
               /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
                  ld24 rx,#_GLOBAL_OFFSET_TABLE_
@@ -3134,11 +3195,11 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                else
                  {
                    (*_bfd_error_handler)
-                     (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
-                      bfd_archive_filename (input_bfd),
+                     (_("%B: The target (%s) of an %s relocation is in the wrong section (%A)"),
+                      input_bfd,
+                      sec,
                       sym_name,
-                      m32r_elf_howto_table[(int) r_type].name,
-                      bfd_get_section_name (abfd, sec));
+                      m32r_elf_howto_table[(int) r_type].name);
                    /*bfd_set_error (bfd_error_bad_value); ??? why? */
                    ret = FALSE;
                    continue;
@@ -4201,8 +4262,7 @@ m32r_elf_merge_private_bfd_data (ibfd, obfd)
           || ((in_flags  & EF_M32R_ARCH) == E_M32R2_ARCH))
        {
          (*_bfd_error_handler)
-           (_("%s: Instruction set mismatch with previous modules"),
-            bfd_archive_filename (ibfd));
+           (_("%B: Instruction set mismatch with previous modules"), ibfd);
 
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
@@ -4306,6 +4366,10 @@ m32r_elf_gc_sweep_hook (abfd, info, sec, relocs)
       case R_M32R_GOT16_HI_ULO:
       case R_M32R_GOT16_HI_SLO:
       case R_M32R_GOT16_LO:
+      case R_M32R_GOTOFF:
+      case R_M32R_GOTOFF_HI_ULO:
+      case R_M32R_GOTOFF_HI_SLO:
+      case R_M32R_GOTOFF_LO:
       case R_M32R_GOT24:
       case R_M32R_GOTPC_HI_ULO:
       case R_M32R_GOTPC_HI_SLO:
@@ -4435,6 +4499,10 @@ m32r_elf_check_relocs (abfd, info, sec, relocs)
             {
             case R_M32R_GOT16_HI_ULO:
             case R_M32R_GOT16_HI_SLO:
+            case R_M32R_GOTOFF:
+            case R_M32R_GOTOFF_HI_ULO:
+            case R_M32R_GOTOFF_HI_SLO:
+            case R_M32R_GOTOFF_LO:
             case R_M32R_GOT16_LO:
             case R_M32R_GOTPC24:
             case R_M32R_GOTPC_HI_ULO:
This page took 0.026616 seconds and 4 git commands to generate.