[ARC] Fixed issue with DTSOFF relocs.
[deliverable/binutils-gdb.git] / bfd / elf32-microblaze.c
index f1808bc4450d967eece94b18106ba3aafbfbbe4c..3d131bc668208d65d37670b1285d21c8bed0abb7 100644 (file)
@@ -251,6 +251,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
          0x0000ffff,           /* Dest Mask.  */
          TRUE),                /* PC relative offset?  */
 
+     /* A 64 bit TEXTPCREL relocation.  Table-entry not really used.  */
+   HOWTO (R_MICROBLAZE_TEXTPCREL_64,           /* Type.  */
+         0,                    /* Rightshift.  */
+         2,                    /* Size (0 = byte, 1 = short, 2 = long).  */
+         16,                   /* Bitsize.  */
+         TRUE,                 /* PC_relative.  */
+         0,                    /* Bitpos.  */
+         complain_overflow_dont, /* Complain on overflow.  */
+         bfd_elf_generic_reloc,        /* Special Function.  */
+         "R_MICROBLAZE_TEXTPCREL_64",  /* Name.  */
+         FALSE,                /* Partial Inplace.  */
+         0,                    /* Source Mask.  */
+         0x0000ffff,           /* Dest Mask.  */
+         TRUE),                /* PC relative offset?  */
+
    /* A 64 bit GOT relocation.  Table-entry not really used.  */
    HOWTO (R_MICROBLAZE_GOT_64,  /* Type.  */
          0,                    /* Rightshift.  */
@@ -266,6 +281,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
          0x0000ffff,           /* Dest Mask.  */
          FALSE),               /* PC relative offset?  */
 
+    /* A 64 bit TEXTREL relocation.  Table-entry not really used.  */
+   HOWTO (R_MICROBLAZE_TEXTREL_64,  /* 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_MICROBLAZE_TEXTREL_64",/* Name.  */
+         FALSE,                /* Partial Inplace.  */
+         0,                    /* Source Mask.  */
+         0x0000ffff,           /* Dest Mask.  */
+         FALSE),               /* PC relative offset?  */
+
    /* A 64 bit PLT relocation.  Table-entry not really used.  */
    HOWTO (R_MICROBLAZE_PLT_64,  /* Type.  */
          0,                    /* Rightshift.  */
@@ -578,6 +608,12 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
     case BFD_RELOC_MICROBLAZE_64_GOT:
       microblaze_reloc = R_MICROBLAZE_GOT_64;
       break;
+    case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
+      microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64;
+      break;
+    case BFD_RELOC_MICROBLAZE_64_TEXTREL:
+      microblaze_reloc = R_MICROBLAZE_TEXTREL_64;
+      break;
     case BFD_RELOC_MICROBLAZE_64_PLT:
       microblaze_reloc = R_MICROBLAZE_PLT_64;
       break;
@@ -638,8 +674,8 @@ microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Set the howto pointer for a RCE ELF reloc.  */
 
-static void
-microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+microblaze_elf_info_to_howto (bfd * abfd,
                              arelent * cache_ptr,
                              Elf_Internal_Rela * dst)
 {
@@ -653,13 +689,14 @@ microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
   if (r_type >= R_MICROBLAZE_max)
     {
       /* xgettext:c-format */
-      _bfd_error_handler (_("%B: unrecognised MicroBlaze reloc number: %d"),
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                          abfd, r_type);
       bfd_set_error (bfd_error_bad_value);
-      r_type = R_MICROBLAZE_NONE;
+      return FALSE;
     }
 
   cache_ptr->howto = microblaze_elf_howto_table [r_type];
+  return TRUE;
 }
 
 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'.  */
@@ -929,7 +966,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
       if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
        {
          /* xgettext:c-format */
-         _bfd_error_handler (_("%B: unknown relocation type %d"),
+         _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                              input_bfd, (int) r_type);
          bfd_set_error (bfd_error_bad_value);
          ret = FALSE;
@@ -1061,8 +1098,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
                      {
                        _bfd_error_handler
                          /* xgettext:c-format */
-                         (_("%B: The target (%s) of an %s relocation"
-                            " is in the wrong section (%A)"),
+                         (_("%pB: the target (%s) of an %s relocation"
+                            " is in the wrong section (%pA)"),
                           input_bfd,
                           sym_name,
                           microblaze_elf_howto_table[(int) r_type]->name,
@@ -1109,8 +1146,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
                      {
                        _bfd_error_handler
                          /* xgettext:c-format */
-                         (_("%B: The target (%s) of an %s relocation"
-                            " is in the wrong section (%A)"),
+                         (_("%pB: the target (%s) of an %s relocation"
+                            " is in the wrong section (%pA)"),
                           input_bfd,
                           sym_name,
                           microblaze_elf_howto_table[(int) r_type]->name,
@@ -1139,6 +1176,18 @@ microblaze_elf_relocate_section (bfd *output_bfd,
                          contents + offset + endian + INST_WORD_SIZE);
              break;
 
+           case (int) R_MICROBLAZE_TEXTPCREL_64:
+             relocation = input_section->output_section->vma;
+             relocation -= (input_section->output_section->vma
+                            + input_section->output_offset
+                            + offset + INST_WORD_SIZE);
+             relocation += addend;
+             bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+                         contents + offset + endian);
+             bfd_put_16 (input_bfd, relocation & 0xffff,
+                         contents + offset + endian + INST_WORD_SIZE);
+             break;
+
            case (int) R_MICROBLAZE_PLT_64:
              {
                bfd_vma immediate;
@@ -1389,6 +1438,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
              bfd_put_16 (input_bfd, relocation & 0xffff,
                          contents + offset + 2 + INST_WORD_SIZE);
              break;
+           case (int) R_MICROBLAZE_TEXTREL_64:
+           case (int) R_MICROBLAZE_TEXTREL_32_LO:
            case (int) R_MICROBLAZE_64_PCREL :
            case (int) R_MICROBLAZE_64:
            case (int) R_MICROBLAZE_32:
@@ -1407,11 +1458,22 @@ microblaze_elf_relocate_section (bfd *output_bfd,
                          relocation -= (input_section->output_section->vma
                                         + input_section->output_offset
                                         + offset + INST_WORD_SIZE);
-                       bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+                       else if (r_type == R_MICROBLAZE_TEXTREL_64
+                                || r_type == R_MICROBLAZE_TEXTREL_32_LO)
+                         relocation -= input_section->output_section->vma;
+
+                       if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
+                         bfd_put_16 (input_bfd, relocation & 0xffff,
+                                     contents + offset + endian);
+
+                       else
+                         {
+                           bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
                                    contents + offset + endian);
-                       bfd_put_16 (input_bfd, relocation & 0xffff,
+                           bfd_put_16 (input_bfd, relocation & 0xffff,
                                    contents + offset + endian + INST_WORD_SIZE);
                      }
+                   }
                    break;
                  }
 
@@ -1479,7 +1541,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
                          {
                            BFD_FAIL ();
                            _bfd_error_handler
-                             (_("%B: probably compiled without -fPIC?"),
+                             (_("%pB: probably compiled without -fPIC?"),
                               input_bfd);
                            bfd_set_error (bfd_error_bad_value);
                            return FALSE;
@@ -1502,11 +1564,24 @@ microblaze_elf_relocate_section (bfd *output_bfd,
                          relocation -= (input_section->output_section->vma
                                         + input_section->output_offset
                                         + offset + INST_WORD_SIZE);
-                       bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
-                                   contents + offset + endian);
-                       bfd_put_16 (input_bfd, relocation & 0xffff,
-                                   contents + offset + endian + INST_WORD_SIZE);
-                     }
+                       else if (r_type == R_MICROBLAZE_TEXTREL_64
+                                || r_type == R_MICROBLAZE_TEXTREL_32_LO)
+                         relocation -= input_section->output_section->vma;
+
+                       if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
+                         {
+                            bfd_put_16 (input_bfd, relocation & 0xffff,
+                                        contents + offset + endian);
+                         }
+                       else
+                         {
+                           bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+                                       contents + offset + endian);
+                           bfd_put_16 (input_bfd, relocation & 0xffff,
+                                       contents + offset + endian
+                                       + INST_WORD_SIZE);
+                         }
+                   }
                    break;
                  }
              }
@@ -1699,7 +1774,8 @@ microblaze_elf_relax_section (bfd *abfd,
     {
       bfd_vma symval;
       if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
-         && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
+         && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64)
+         && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
        continue; /* Can't delete this reloc.  */
 
       /* Get the section contents.  */
@@ -1769,6 +1845,10 @@ microblaze_elf_relax_section (bfd *abfd,
               + sec->output_section->vma
               + sec->output_offset);
        }
+      else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
+       {
+         symval = symval + irel->r_addend - (sec->output_section->vma);
+       }
       else
        symval += irel->r_addend;
 
@@ -1791,6 +1871,10 @@ microblaze_elf_relax_section (bfd *abfd,
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                                           (int) R_MICROBLAZE_32_LO);
              break;
+           case R_MICROBLAZE_TEXTREL_64:
+             irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                          (int) R_MICROBLAZE_TEXTREL_32_LO);
+             break;
            default:
              /* Cannot happen.  */
              BFD_ASSERT (FALSE);
@@ -1817,6 +1901,8 @@ microblaze_elf_relax_section (bfd *abfd,
              break;
            case R_MICROBLAZE_64_PCREL:
              break;
+           case R_MICROBLAZE_TEXTREL_64:
+           case R_MICROBLAZE_TEXTREL_32_LO:
            case R_MICROBLAZE_64:
            case R_MICROBLAZE_32_LO:
              /* If this reloc is against a symbol defined in this
@@ -1953,7 +2039,10 @@ microblaze_elf_relax_section (bfd *abfd,
                    }
                }
              else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
-                      || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
+                      || (ELF32_R_TYPE (irelscan->r_info)
+                                  == (int) R_MICROBLAZE_32_LO)
+                      || (ELF32_R_TYPE (irelscan->r_info)
+                                  == (int) R_MICROBLAZE_TEXTREL_32_LO))
                {
                  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
@@ -1997,7 +2086,9 @@ microblaze_elf_relax_section (bfd *abfd,
                    }
                }
 
-             if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
+             if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
+                 || (ELF32_R_TYPE (irelscan->r_info)
+                             == (int) R_MICROBLAZE_TEXTREL_64))
                {
                  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
This page took 0.027271 seconds and 4 git commands to generate.