]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[MicroBlaze] PIC data text relative
authorMichael Eager <eager@eagercon.com>
Tue, 17 Apr 2018 21:47:13 +0000 (14:47 -0700)
committerMichael Eager <eager@eagercon.com>
Tue, 17 Apr 2018 21:47:13 +0000 (14:47 -0700)
Andrew Sadek <andrew.sadek.se@gmail.com>

A new implemented feature in GCC Microblaze that allows Position
Independent Code to run using Data Text Relative addressing instead
of using Global Offset Table.

Its aim was to make 'PIC' more efficient and flexible as elf size
excess performance overhead were noticed when using GOT due to the
indirect addressing.

include/ChangeLog:
* bfdlink.h (Add flag): Add new flag @ 'bfd_link_info' struct.
* elf/microblaze.h (Add 3 new relocations):
R_MICROBLAZE_TEXTPCREL_64, R_MICROBLAZE_TEXTREL_64
and R_MICROBLAZE_TEXTREL_32_LO for relax function.
bfd/ChangeLog:
* bfd/reloc.c (2 new BFD relocations):
BFD_RELOC_MICROBLAZE_64_TEXTPCREL &
BFD_RELOC_MICROBLAZE_64_TEXTPCREL
* bfd/bfd-in2.h: Regenerate
* bfd/libbfd.h: Regenerate
* bfd/elf32-microblaze.c (Handle new relocs): define 'HOWTO' of 3
new relocs and handle them in both relocate and relax functions.
(microblaze_elf_reloc_type_lookup): add mapping between for new
bfd relocs.
(microblaze_elf_relocate_section): Handle new relocs in case of
elf relocation.
(microblaze_elf_relax_section): Handle new relocs for elf relaxation.
gas/ChangeLog:
* gas/config/tc-microblaze.c (Handle new relocs directives in
assembler): Handle new relocs from compiler output.
(imm_types): add new imm types for data text relative addressing
TEXT_OFFSET, TEXT_PC_OFFSET
(md_convert_frag): conversion for BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
BFD_RELOC_MICROBLAZE_64_TEXTPCREL
(md_apply_fix): apply fix for BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
BFD_RELOC_MICROBLAZE_64_TEXTPCREL
(md_estimate_size_before_relax): estimate size for
BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
BFD_RELOC_MICROBLAZE_64_TEXTPCREL
(tc_gen_reloc): generate relocations for
BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
BFD_RELOC_MICROBLAZE_64_TEXTPCREL
ld/ChangeLog:
* ld/lexsup.c (Add 2 ld options):
(ld_options): add disable-multiple-abs-defs @ 'ld_options' array
(parse_args): parse new option and pass flag to 'link_info' struct.
* ld/ldlex.h (Add enum): add new enum @ 'option_values' enum.
* ld/ld.texinfo (Add new option): Add description for
'disable-multiple-abs-defs'
* ld/main.c: Initialize flags with false @ 'main'. Handle
disable-multiple-abs-defs @ 'mutiple_definition'.

15 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-microblaze.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-microblaze.c
include/ChangeLog
include/bfdlink.h
include/elf/microblaze.h
ld/ChangeLog
ld/ld.texinfo
ld/ldlex.h
ld/ldmain.c
ld/lexsup.c

index 88365d0aa573e70fac32d2c359a5c43712cdf298..6e76defc84a073996d08d779ce3970da854b8a7a 100644 (file)
@@ -1,3 +1,20 @@
+2018-04-09 Andrew Sadek  <andrew.sadek.se@gmail.com>
+
+       Microblaze Target: PIC data text relative
+
+       * bfd/reloc.c (2 new BFD relocations):
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL &
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+       * bfd/bfd-in2.h: Regenerate
+       * bfd/libbfd.h: Regenerate
+       * bfd/elf32-microblaze.c (Handle new relocs): define 'HOWTO' of 3
+       new relocs and handle them in both relocate and relax functions.
+       (microblaze_elf_reloc_type_lookup): add mapping between for new
+       bfd relocs.
+       (microblaze_elf_relocate_section): Handle new relocs in case of
+       elf relocation.
+       (microblaze_elf_relax_section): Handle new relocs for elf relaxation.
+
 2018-04-17  Nick Clifton  <nickc@redhat.com>
 
        PR 23055
index 041b3b16d05b82111330850b3fae5352756060c6..97c37a07af9c2b8d8cb7470aed25951b2bc6fefc 100644 (file)
@@ -5831,6 +5831,16 @@ to two words (uses imm instruction).  */
 to two words (uses imm instruction).  */
   BFD_RELOC_MICROBLAZE_64_TLSTPREL,
 
+/* This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction).  The relocation is
+PC-relative offset from start of TEXT.  */
+  BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
+
+/* This is a 64 bit reloc that stores the 32 bit offset
+value in two words (with an imm instruction).  The relocation is
+relative offset from start of TEXT.  */
+  BFD_RELOC_MICROBLAZE_64_TEXTREL,
+
 /* AArch64 pseudo relocation code to mark the start of the AArch64
 relocation enumerators.  N.B. the order of the enumerators is
 important as several tables in the AArch64 bfd backend are indexed
index 3acf93a44fc329cae8a82550d63173fda8aefa47..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;
@@ -1140,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;
@@ -1390,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:
@@ -1408,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;
                  }
 
@@ -1503,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;
                  }
              }
@@ -1700,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.  */
@@ -1770,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;
 
@@ -1792,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);
@@ -1818,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
@@ -1954,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);
 
@@ -1998,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);
 
index f50cc03523f5c094385378534e5ae7c33b9fe747..6263ec443fb8e5aedf3b459bfd01c5cb7dbeb5be 100644 (file)
@@ -2822,6 +2822,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MICROBLAZE_64_TLSDTPREL",
   "BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL",
   "BFD_RELOC_MICROBLAZE_64_TLSTPREL",
+  "BFD_RELOC_MICROBLAZE_64_TEXTPCREL",
+  "BFD_RELOC_MICROBLAZE_64_TEXTREL",
   "BFD_RELOC_AARCH64_RELOC_START",
   "BFD_RELOC_AARCH64_NULL",
   "BFD_RELOC_AARCH64_NONE",
index 9d86dee667cffcd2b02c09d5b4e940028f2bc3fe..80db0c93902cd5c81fa79c13aad24b3a92f8a16a 100644 (file)
@@ -6906,6 +6906,18 @@ ENUM
 ENUMDOC
   This is a 64 bit reloc that stores 32-bit thread pointer relative offset
   to two words (uses imm instruction).
+ENUM
+  BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+ENUMDOC
+  This is a 64 bit reloc that stores the 32 bit pc relative
+  value in two words (with an imm instruction).  The relocation is
+  PC-relative offset from start of TEXT.
+ENUM
+  BFD_RELOC_MICROBLAZE_64_TEXTREL
+ENUMDOC
+  This is a 64 bit reloc that stores the 32 bit offset
+  value in two words (with an imm instruction).  The relocation is
+  relative offset from start of TEXT.
 
 ENUM
   BFD_RELOC_AARCH64_RELOC_START
index c16ea00655dd40e2eef8abd5256874dad94fac11..a12fb9e44b3b64acd1cd82bba4d3d6d67b8f8793 100644 (file)
@@ -1,3 +1,22 @@
+2018-04-09 Andrew Sadek  <andrew.sadek.se@gmail.com>
+
+       Microblaze Target: PIC data text relative
+
+       * gas/config/tc-microblaze.c (Handle new relocs directives in
+       assembler): Handle new relocs from compiler output.
+       (imm_types): add new imm types for data text relative addressing
+       TEXT_OFFSET, TEXT_PC_OFFSET
+       (md_convert_frag): conversion for BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+       (md_apply_fix): apply fix for BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+       (md_estimate_size_before_relax): estimate size for
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+       (tc_gen_reloc): generate relocations for
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
+       BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+
 2018-04-17  Igor Tsimbalist  <igor.v.tsimbalist@intel.com>
 
        * testsuite/gas/i386/nops.s: Revert back deleted lines and
index 0194cd925539a94121d1ae650c00138715ba4b6c..ba6eabb00030759a116d1b7b840050c533cf6c95 100644 (file)
@@ -87,6 +87,8 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
 #define TLSDTPREL_OFFSET     14
 #define TLSGOTTPREL_OFFSET   15
 #define TLSTPREL_OFFSET      16
+#define TEXT_OFFSET         17
+#define TEXT_PC_OFFSET       18
 
 /* Initialize the relax table.  */
 const relax_typeS md_relax_table[] =
@@ -107,7 +109,9 @@ const relax_typeS md_relax_table[] =
   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 },  /* 13: TLSDTPMOD_OFFSET.  */
   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 14: TLSDTPREL_OFFSET.  */
   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 15: TLSGOTTPREL_OFFSET.  */
-  { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }   /* 16: TLSTPREL_OFFSET.  */
+  { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 16: TLSTPREL_OFFSET.  */
+  { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 17: TEXT_OFFSET.  */
+  { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }   /* 18: TEXT_PC_OFFSET.  */
 };
 
 static struct hash_control * opcode_hash_control;      /* Opcode mnemonics.  */
@@ -624,7 +628,9 @@ parse_exp (char *s, expressionS *e)
 #define IMM_TLSDTPMOD 6
 #define IMM_TLSDTPREL 7
 #define IMM_TLSTPREL  8
-#define IMM_MAX    9
+#define IMM_TXTREL    9
+#define IMM_TXTPCREL  10
+#define IMM_MAX    11
 
 struct imm_type {
        const char *isuffix;     /* Suffix String */
@@ -643,7 +649,9 @@ static struct imm_type imm_types[] = {
        { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET },
        { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET },
        { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET },
-       { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET }
+       { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET },
+       { "TXTREL", IMM_TXTREL, TEXT_OFFSET },
+       { "TXTPCREL", IMM_TXTPCREL, TEXT_PC_OFFSET }
 };
 
 static int
@@ -1019,7 +1027,7 @@ md_assemble (char * str)
       if (check_spl_reg (& reg2))
        as_fatal (_("Cannot use special register with this instruction"));
 
-      if (exp.X_op != O_constant)
+      if (exp.X_op != O_constant || exp.X_md == IMM_TXTPCREL)
        {
           const char *opc;
          relax_substateT subtype;
@@ -1921,6 +1929,18 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
       fragP->fr_fix += INST_WORD_SIZE * 2;
       fragP->fr_var = 0;
       break;
+    case TEXT_OFFSET:
+      fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
+              fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TEXTREL);
+      fragP->fr_fix += INST_WORD_SIZE * 2;
+      fragP->fr_var = 0;
+      break;
+    case TEXT_PC_OFFSET:
+      fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
+              fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TEXTPCREL);
+      fragP->fr_fix += INST_WORD_SIZE * 2;
+      fragP->fr_var = 0;
+      break;
     case PLT_OFFSET:
       fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
                      fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
@@ -2097,6 +2117,7 @@ md_apply_fix (fixS *   fixP,
       break;
     case BFD_RELOC_64_PCREL:
     case BFD_RELOC_64:
+    case BFD_RELOC_MICROBLAZE_64_TEXTREL:
       /* Add an imm instruction.  First save the current instruction.  */
       for (i = 0; i < INST_WORD_SIZE; i++)
        buf[i + INST_WORD_SIZE] = buf[i];
@@ -2144,6 +2165,7 @@ md_apply_fix (fixS *   fixP,
     case BFD_RELOC_MICROBLAZE_64_GOT:
     case BFD_RELOC_MICROBLAZE_64_PLT:
     case BFD_RELOC_MICROBLAZE_64_GOTOFF:
+    case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
       /* Add an imm instruction.  First save the current instruction.  */
       for (i = 0; i < INST_WORD_SIZE; i++)
        buf[i + INST_WORD_SIZE] = buf[i];
@@ -2240,16 +2262,18 @@ md_estimate_size_before_relax (fragS * fragP,
       break;
 
     case INST_NO_OFFSET:
+    case TEXT_OFFSET:
       /* Used to be a reference to somewhere which was unknown.  */
       if (fragP->fr_symbol)
         {
          if (fragP->fr_opcode == NULL)
            {
-              /* Used as an absolute value.  */
-              fragP->fr_subtype = DEFINED_ABS_SEGMENT;
-              /* Variable part does not change.  */
-              fragP->fr_var = INST_WORD_SIZE*2;
-            }
+             /* Used as an absolute value.  */
+             if (fragP->fr_subtype == INST_NO_OFFSET)
+               fragP->fr_subtype = DEFINED_ABS_SEGMENT;
+             /* Variable part does not change.  */
+             fragP->fr_var = INST_WORD_SIZE*2;
+           }
          else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
            {
               /* It is accessed using the small data read only anchor.  */
@@ -2318,6 +2342,7 @@ md_estimate_size_before_relax (fragS * fragP,
     case GOT_OFFSET:
     case PLT_OFFSET:
     case GOTOFF_OFFSET:
+    case TEXT_PC_OFFSET:
     case TLSGD_OFFSET:
     case TLSLD_OFFSET:
     case TLSTPREL_OFFSET:
@@ -2418,6 +2443,8 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
     case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
     case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
     case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
+    case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
+    case BFD_RELOC_MICROBLAZE_64_TEXTREL:
       code = fixp->fx_r_type;
       break;
 
index 2c8d52681edbb666ef8cfa322240b8aaa86ae844..52ec0042ac14e46ebc7822e3bd2d4cfe5509f488 100644 (file)
@@ -1,3 +1,12 @@
+2018-04-09 Andrew Sadek  <andrew.sadek.se@gmail.com>
+
+       Microblaze Target: PIC data text relative
+
+       * bfdlink.h (Add flag): Add new flag @ 'bfd_link_info' struct.
+       * elf/microblaze.h (Add 3 new relocations):
+       R_MICROBLAZE_TEXTPCREL_64, R_MICROBLAZE_TEXTREL_64
+       and R_MICROBLAZE_TEXTREL_32_LO for relax function.
+
 2018-04-17  Alan Modra  <amodra@gmail.com>
 
        * elf/i370.h: Revert removal.
index 5d637acbabdab322d8b9e15035845fcad440b839..773407f8614d47e06d408e71eacad079affb8f7e 100644 (file)
@@ -439,6 +439,9 @@ struct bfd_link_info
   /* TRUE if ok to have multiple definition.  */
   unsigned int allow_multiple_definition: 1;
 
+  /* TRUE if ok to have prohibit multiple definition of absolute symbols.  */
+  unsigned int prohibit_multiple_definition_absolute: 1;
+
   /* TRUE if ok to have version with no definition.  */
   unsigned int allow_undefined_version: 1;
 
index ae98099d550c63b318a8b0b7d99c41e908a65775..dbaa16cb55ab00f6048b3462ac9ee0e385627d05 100644 (file)
@@ -58,7 +58,9 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
   RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27)   /* TLS Offset Within TLS Block */
   RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */
   RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29)    /* TLS Offset From Thread Pointer */
-   
+  RELOC_NUMBER (R_MICROBLAZE_TEXTPCREL_64, 30)  /* PC-relative TEXT offset.  */
+  RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31)    /* TEXT Entry offset 64-bit.  */
+  RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit.  */
 END_RELOC_NUMBERS (R_MICROBLAZE_max)
 
 /* Global base address names.  */
index bdf1e3fd540c5068819f6915c0a4f9492b5b3d07..580abafa3219a5de1f27071071b079988cde5d5d 100644 (file)
@@ -1,3 +1,16 @@
+2018-04-09 Andrew Sadek  <andrew.sadek.se@gmail.com>
+
+       Microblaze Target: PIC data text relative
+
+       * ld/lexsup.c (Add 2 ld options):
+       (ld_options): add disable-multiple-abs-defs @ 'ld_options' array
+       (parse_args): parse new option and pass flag to 'link_info' struct.
+       * ld/ldlex.h (Add enum): add new enum @ 'option_values' enum.
+       * ld/ld.texinfo (Add new option): Add description for
+       'disable-multiple-abs-defs'
+       * ld/main.c: Initialize flags with false @ 'main'. Handle
+       disable-multiple-abs-defs @ 'mutiple_definition'.
+
 2018-04-16  Alan Modra  <amodra@gmail.com>
 
        * emultempl/sunos.em: Delete.
index 9679afd3d0b7a18c80ebae74d0fe431417ff86a0..40d79ddf6242bddecab227f63a0622f54b310157 100644 (file)
@@ -1561,6 +1561,11 @@ that the relocs are stored in a target specific section.  This option
 is only supported by the @samp{BFIN}, @samp{CR16} and @emph{M68K}
 targets.
 
+@kindex --disable-multiple-abs-defs
+@item --disable-multiple-abs-defs
+Do not allow multiple definitions with symbols included
+in filename invoked by -R or --just-symbols
+
 @kindex --fatal-warnings
 @kindex --no-fatal-warnings
 @item --fatal-warnings
index 1ecb152be168d7b4c252220efa18d5ed538e738f..04d6fd5f96c7f4c9d4500f71a37765782a6ad68c 100644 (file)
@@ -143,6 +143,7 @@ enum option_values
   OPTION_IGNORE_UNRESOLVED_SYMBOL,
   OPTION_PUSH_STATE,
   OPTION_POP_STATE,
+  OPTION_DISABLE_MULTIPLE_DEFS_ABS,
   OPTION_PRINT_MEMORY_USAGE,
   OPTION_REQUIRE_DEFINED_SYMBOL,
   OPTION_ORPHAN_HANDLING,
index 43602fe85a46a12aa491c7db8f5b7deb5f39daf1..f31eeb29c3ceac62adb0df73c6f1d08fef8a23ea 100644 (file)
@@ -280,6 +280,7 @@ main (int argc, char **argv)
   link_info.keep_memory = TRUE;
   link_info.combreloc = TRUE;
   link_info.strip_discarded = TRUE;
+  link_info.prohibit_multiple_definition_absolute = FALSE;
   link_info.emit_hash = DEFAULT_EMIT_SYSV_HASH;
   link_info.emit_gnu_hash = DEFAULT_EMIT_GNU_HASH;
   link_info.callbacks = &link_callbacks;
@@ -968,12 +969,13 @@ multiple_definition (struct bfd_link_info *info,
      discarded, and this is not really a multiple definition at all.
      FIXME: It would be cleaner to somehow ignore symbols defined in
      sections which are being discarded.  */
-  if ((osec->output_section != NULL
-       && !bfd_is_abs_section (osec)
-       && bfd_is_abs_section (osec->output_section))
-      || (nsec->output_section != NULL
-         && !bfd_is_abs_section (nsec)
-         && bfd_is_abs_section (nsec->output_section)))
+  if (!info->prohibit_multiple_definition_absolute
+      && ((osec->output_section != NULL
+          && ! bfd_is_abs_section (osec)
+          && bfd_is_abs_section (osec->output_section))
+         || (nsec->output_section != NULL
+             && !bfd_is_abs_section (nsec)
+             && bfd_is_abs_section (nsec->output_section))))
     return;
 
   name = h->root.string;
index 636ce17bab1377bc8f1e2384c8a34278a782054b..a4bc7da67fabc06661c0083ecba7bbe2ad59078c 100644 (file)
@@ -314,6 +314,11 @@ static const struct ld_option ld_options[] =
   { {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
     '\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"),
     TWO_DASHES },
+  { {"disable-multiple-abs-defs", no_argument, NULL,
+     OPTION_DISABLE_MULTIPLE_DEFS_ABS},
+    '\0', NULL, N_("Do not allow multiple definitions with symbols included\n"
+                  "           in filename invoked by -R or --just-symbols"),
+    TWO_DASHES},
   { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
     '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
   { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
@@ -1159,6 +1164,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_NO_STRIP_DISCARDED:
          link_info.strip_discarded = FALSE;
          break;
+       case OPTION_DISABLE_MULTIPLE_DEFS_ABS:
+         link_info.prohibit_multiple_definition_absolute = TRUE;
+         break;
        case OPTION_SHARED:
          if (config.has_shared)
            {