Add x86 size relocation support to gas
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 17 Jan 2013 04:28:48 +0000 (04:28 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 17 Jan 2013 04:28:48 +0000 (04:28 +0000)
gas/

* config/tc-i386.c (reloc): Support BFD_RELOC_SIZE32.
(tc_i386_fix_adjustable): Keep symbol for BFD_RELOC_32_SIZE and
BFD_RELOC_64_SIZE relocations.
(lex_got): Support "symbol@SIZE" and don't create GOT symbol
for it.
(tc_gen_reloc): Resolve BFD_RELOC_SIZE32 and BFD_RELOC_SIZE64
relocations against local symbols.

gas/testsuite/

* gas/i386/i386.exp: Run size-1, size-2, size-3, size-4,
x86-64-size-1, x86-64-size-2, x86-64-size-3, x86-64-size-4,
x86-64-size-5 and x86-64-size-inval-1.

* gas/i386/size-1.d: New file.
* gas/i386/size-1.s: Likewise.
* gas/i386/size-2.d: Likewise.
* gas/i386/size-2.s: Likewise.
* gas/i386/size-3.d: Likewise.
* gas/i386/size-3.s: Likewise.
* gas/i386/size-4.d: Likewise.
* gas/i386/size-4.s: Likewise.
* gas/i386/x86-64-size-1.d: Likewise.
* gas/i386/x86-64-size-2.d: Likewise.
* gas/i386/x86-64-size-3.d: Likewise.
* gas/i386/x86-64-size-4.d: Likewise.
* gas/i386/x86-64-size-5.d: Likewise.
* gas/i386/x86-64-size-5.s: Likewise.
* gas/i386/x86-64-size-inval-1.l: Likewise.
* gas/i386/x86-64-size-inval-1.s: Likewise.
* gas/i386/ilp32/x86-64-size-1.d: Likewise.
* gas/i386/ilp32/x86-64-size-2.d: Likewise.
* gas/i386/ilp32/x86-64-size-3.d: Likewise.
* gas/i386/ilp32/x86-64-size-4.d: Likewise.
* gas/i386/ilp32/x86-64-size-5.d: Likewise.

ld/testsuite/

* ld-size/size.exp: New file.
* ld-size/size32-1-i386.d: Likewise.
* ld-size/size32-1-x32.d: Likewise.
* ld-size/size32-1-x86-64.d: Likewise.
* ld-size/size32-1.s: Likewise.
* ld-size/size32-2-i386.d: Likewise.
* ld-size/size32-2-x32.d: Likewise.
* ld-size/size32-2-x86-64.d: Likewise.
* ld-size/size32-2.s: Likewise.
* ld-size/size64-1-x32.d: Likewise.
* ld-size/size64-1-x86-64.d: Likewise.
* ld-size/size64-1.s: Likewise.
* ld-size/size64-2-x32.d: Likewise.
* ld-size/size64-2-x86-64.d: Likewise.
* ld-size/size64-2.s: Likewise.
* ld-size/size-3.c: Likewise.
* ld-size/size-3.out: Likewise.
* ld-size/size-3a.c: Likewise.
* ld-size/size-3b.c: Likewise.
* ld-size/size-3c.c: Likewise.
* ld-size/size-4.out: Likewise.
* ld-size/size-4a.c: Likewise.
* ld-size/size-4b.c: Likewise.
* ld-size/size-5.out: Likewise.
* ld-size/size-5a.c: Likewise.
* ld-size/size-5b.c: Likewise.
* ld-size/size-6.out: Likewise.
* ld-size/size-6a.c: Likewise.
* ld-size/size-6b.c: Likewise.
* ld-size/size-7.rd: Likewise.
* ld-size/size-7a.c: Likewise.
* ld-size/size-7b.c: Likewise.
* ld-size/size-8.rd: Likewise.
* ld-size/size-8a.c: Likewise.
* ld-size/size-8b.c: Likewise.

61 files changed:
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/ilp32/x86-64-size-1.d [new file with mode: 0644]
gas/testsuite/gas/i386/ilp32/x86-64-size-2.d [new file with mode: 0644]
gas/testsuite/gas/i386/ilp32/x86-64-size-3.d [new file with mode: 0644]
gas/testsuite/gas/i386/ilp32/x86-64-size-4.d [new file with mode: 0644]
gas/testsuite/gas/i386/ilp32/x86-64-size-5.d [new file with mode: 0644]
gas/testsuite/gas/i386/size-1.d [new file with mode: 0644]
gas/testsuite/gas/i386/size-1.s [new file with mode: 0644]
gas/testsuite/gas/i386/size-2.d [new file with mode: 0644]
gas/testsuite/gas/i386/size-2.s [new file with mode: 0644]
gas/testsuite/gas/i386/size-3.d [new file with mode: 0644]
gas/testsuite/gas/i386/size-3.s [new file with mode: 0644]
gas/testsuite/gas/i386/size-4.d [new file with mode: 0644]
gas/testsuite/gas/i386/size-4.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-1.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-2.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-3.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-4.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-5.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-5.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-inval-1.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-size-inval-1.s [new file with mode: 0644]
ld/testsuite/ChangeLog
ld/testsuite/ld-size/size-3.c [new file with mode: 0644]
ld/testsuite/ld-size/size-3.out [new file with mode: 0644]
ld/testsuite/ld-size/size-3a.c [new file with mode: 0644]
ld/testsuite/ld-size/size-3b.c [new file with mode: 0644]
ld/testsuite/ld-size/size-3c.c [new file with mode: 0644]
ld/testsuite/ld-size/size-4.out [new file with mode: 0644]
ld/testsuite/ld-size/size-4a.c [new file with mode: 0644]
ld/testsuite/ld-size/size-4b.c [new file with mode: 0644]
ld/testsuite/ld-size/size-5.out [new file with mode: 0644]
ld/testsuite/ld-size/size-5a.c [new file with mode: 0644]
ld/testsuite/ld-size/size-5b.c [new file with mode: 0644]
ld/testsuite/ld-size/size-6.out [new file with mode: 0644]
ld/testsuite/ld-size/size-6a.c [new file with mode: 0644]
ld/testsuite/ld-size/size-6b.c [new file with mode: 0644]
ld/testsuite/ld-size/size-7.rd [new file with mode: 0644]
ld/testsuite/ld-size/size-7a.c [new file with mode: 0644]
ld/testsuite/ld-size/size-7b.c [new file with mode: 0644]
ld/testsuite/ld-size/size-8.rd [new file with mode: 0644]
ld/testsuite/ld-size/size-8a.c [new file with mode: 0644]
ld/testsuite/ld-size/size-8b.c [new file with mode: 0644]
ld/testsuite/ld-size/size.exp [new file with mode: 0644]
ld/testsuite/ld-size/size32-1-i386.d [new file with mode: 0644]
ld/testsuite/ld-size/size32-1-x32.d [new file with mode: 0644]
ld/testsuite/ld-size/size32-1-x86-64.d [new file with mode: 0644]
ld/testsuite/ld-size/size32-1.s [new file with mode: 0644]
ld/testsuite/ld-size/size32-2-i386.d [new file with mode: 0644]
ld/testsuite/ld-size/size32-2-x32.d [new file with mode: 0644]
ld/testsuite/ld-size/size32-2-x86-64.d [new file with mode: 0644]
ld/testsuite/ld-size/size32-2.s [new file with mode: 0644]
ld/testsuite/ld-size/size64-1-x32.d [new file with mode: 0644]
ld/testsuite/ld-size/size64-1-x86-64.d [new file with mode: 0644]
ld/testsuite/ld-size/size64-1.s [new file with mode: 0644]
ld/testsuite/ld-size/size64-2-x32.d [new file with mode: 0644]
ld/testsuite/ld-size/size64-2-x86-64.d [new file with mode: 0644]
ld/testsuite/ld-size/size64-2.s [new file with mode: 0644]

index 2c64f68825c37164fa6a8811f06afc2dbb989e3a..a011624c2750b2e8dcdf74fc90f882ee47bca78c 100644 (file)
@@ -1,3 +1,13 @@
+2013-01-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-i386.c (reloc): Support BFD_RELOC_SIZE32.
+       (tc_i386_fix_adjustable): Keep symbol for BFD_RELOC_32_SIZE and
+       BFD_RELOC_64_SIZE relocations.
+       (lex_got): Support "symbol@SIZE" and don't create GOT symbol
+       for it.
+       (tc_gen_reloc): Resolve BFD_RELOC_SIZE32 and BFD_RELOC_SIZE64
+       relocations against local symbols.
+
 2013-01-16  Alan Modra  <amodra@gmail.com>
 
        * config/tc-ppc.c (md_assemble <TE_PE>): Ignore line after
index 641af39a15cbcc5aece1c274ed6a419da4b21740..c96229e9bf86305ba2e9a9f28cfc1bd2e4f0ff5d 100644 (file)
@@ -2686,6 +2686,14 @@ reloc (unsigned int size,
            break;
          }
 
+      if (other == BFD_RELOC_SIZE32)
+       {
+         if (size == 8)
+           return BFD_RELOC_SIZE64;
+         if (pcrel)
+           as_bad (_("there are no pc-relative size relocations"));
+       }
+
       /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless.  */
       if (size == 4 && (flag_code != CODE_64BIT || disallow_64bit_reloc))
        sign = -1;
@@ -2769,8 +2777,11 @@ tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED)
       && fixP->fx_r_type == BFD_RELOC_32_PCREL)
     return 0;
 
-  /* adjust_reloc_syms doesn't know about the GOT.  */
-  if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
+  /* Adjust_reloc_syms doesn't know about the GOT.  Need to keep symbol
+     for size relocations.  */
+  if (fixP->fx_r_type == BFD_RELOC_SIZE32
+      || fixP->fx_r_type == BFD_RELOC_SIZE64
+      || fixP->fx_r_type == BFD_RELOC_386_GOTOFF
       || fixP->fx_r_type == BFD_RELOC_386_PLT32
       || fixP->fx_r_type == BFD_RELOC_386_GOT32
       || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
@@ -6708,6 +6719,9 @@ lex_got (enum bfd_reloc_code_real *rel,
     const enum bfd_reloc_code_real rel[2];
     const i386_operand_type types64;
   } gotrel[] = {
+    { STRING_COMMA_LEN ("SIZE"),      { BFD_RELOC_SIZE32,
+                                       BFD_RELOC_SIZE32 },
+      OPERAND_TYPE_IMM32_64 },
     { STRING_COMMA_LEN ("PLTOFF"),   { _dummy_first_bfd_reloc_code_real,
                                       BFD_RELOC_X86_64_PLTOFF64 },
       OPERAND_TYPE_IMM64 },
@@ -6795,7 +6809,7 @@ lex_got (enum bfd_reloc_code_real *rel,
                    *types = gotrel[j].types64;
                }
 
-             if (GOT_symbol == NULL)
+             if (j != 0 && GOT_symbol == NULL)
                GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
 
              /* The length of the first part of our input line.  */
@@ -9231,6 +9245,24 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 
   switch (fixp->fx_r_type)
     {
+    case BFD_RELOC_SIZE32:
+    case BFD_RELOC_SIZE64:
+      if (S_IS_DEFINED (fixp->fx_addsy)
+         && !S_IS_EXTERNAL (fixp->fx_addsy))
+       {
+         /* Resolve size relocation against local symbol to size of
+            the symbol plus addend.  */
+         valueT value = S_GET_SIZE (fixp->fx_addsy) + fixp->fx_offset;
+         if (fixp->fx_r_type == BFD_RELOC_SIZE32
+             && !fits_in_unsigned_long (value))
+           as_bad_where (fixp->fx_file, fixp->fx_line,
+                         _("symbol size computation overflow"));
+         fixp->fx_addsy = NULL;
+         fixp->fx_subsy = NULL;
+         md_apply_fix (fixp, (valueT *) &value, NULL);
+         return NULL;
+       }
+
     case BFD_RELOC_X86_64_PLT32:
     case BFD_RELOC_X86_64_GOT32:
     case BFD_RELOC_X86_64_GOTPCREL:
index 622d266a731f2999b1392841aacc98492f577013..9bbead969cd8d4533679d9d4f49a9509dd0862c2 100644 (file)
@@ -1,3 +1,31 @@
+2013-01-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * gas/i386/i386.exp: Run size-1, size-2, size-3, size-4,
+       x86-64-size-1, x86-64-size-2, x86-64-size-3, x86-64-size-4,
+       x86-64-size-5 and x86-64-size-inval-1.
+
+       * gas/i386/size-1.d: New file.
+       * gas/i386/size-1.s: Likewise.
+       * gas/i386/size-2.d: Likewise.
+       * gas/i386/size-2.s: Likewise.
+       * gas/i386/size-3.d: Likewise.
+       * gas/i386/size-3.s: Likewise.
+       * gas/i386/size-4.d: Likewise.
+       * gas/i386/size-4.s: Likewise.
+       * gas/i386/x86-64-size-1.d: Likewise.
+       * gas/i386/x86-64-size-2.d: Likewise.
+       * gas/i386/x86-64-size-3.d: Likewise.
+       * gas/i386/x86-64-size-4.d: Likewise.
+       * gas/i386/x86-64-size-5.d: Likewise.
+       * gas/i386/x86-64-size-5.s: Likewise.
+       * gas/i386/x86-64-size-inval-1.l: Likewise.
+       * gas/i386/x86-64-size-inval-1.s: Likewise.
+       * gas/i386/ilp32/x86-64-size-1.d: Likewise.
+       * gas/i386/ilp32/x86-64-size-2.d: Likewise.
+       * gas/i386/ilp32/x86-64-size-3.d: Likewise.
+       * gas/i386/ilp32/x86-64-size-4.d: Likewise.
+       * gas/i386/ilp32/x86-64-size-5.d: Likewise.
+
 2013-01-16  Alan Modra  <amodra@gmail.com>
 
        * gas/ppc/htm.d: Ignore padding at end of section.
index 70f1c371970bea1d6ad8f529974750088435cac1..6daf5598edb52353b767f185b6ae882ffe5cfb6d 100644 (file)
@@ -289,6 +289,11 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
        run_dump_test "dw2-compress-2"
 
        run_dump_test "bad-size"
+
+       run_dump_test "size-1"
+       run_dump_test "size-2"
+       run_dump_test "size-3"
+       run_dump_test "size-4"
     }
 
     # This is a PE specific test.
@@ -531,6 +536,13 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
        run_dump_test "debug1"
 
        run_dump_test "x86-64-dw2-compress-2"
+
+       run_dump_test "x86-64-size-1"
+       run_dump_test "x86-64-size-2"
+       run_dump_test "x86-64-size-3"
+       run_dump_test "x86-64-size-4"
+       run_dump_test "x86-64-size-5"
+       run_list_test "x86-64-size-inval-1" "-al"
     }
 
     set ASFLAGS "$old_ASFLAGS"
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-size-1.d b/gas/testsuite/gas/i386/ilp32/x86-64-size-1.d
new file mode 100644 (file)
index 0000000..7b0884f
--- /dev/null
@@ -0,0 +1,23 @@
+#name: x32 size 1
+#source: ../size-1.s
+#readelf: -r
+
+
+Relocation section '.rela.text' at offset 0x2e0 contains 9 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+0+1  00000420 R_X86_64_SIZE32   00000000   xxx \+ 0
+0+6  00000420 R_X86_64_SIZE32   00000000   xxx - 8
+0+b  00000420 R_X86_64_SIZE32   00000000   xxx \+ 8
+0+10  00000520 R_X86_64_SIZE32   00000000   yyy \+ 0
+0+15  00000520 R_X86_64_SIZE32   00000000   yyy - 10
+0+1a  00000520 R_X86_64_SIZE32   00000000   yyy \+ 10
+0+1f  00000620 R_X86_64_SIZE32   00000020   zzz \+ 0
+0+24  00000620 R_X86_64_SIZE32   00000020   zzz - 20
+0+29  00000620 R_X86_64_SIZE32   00000020   zzz \+ 20
+
+Relocation section '.rela.data' at offset 0x34c contains 3 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+0+50  00000420 R_X86_64_SIZE32   00000000   xxx - 1
+0+54  00000520 R_X86_64_SIZE32   00000000   yyy \+ 2
+0+58  00000620 R_X86_64_SIZE32   00000020   zzz \+ 0
+#pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-size-2.d b/gas/testsuite/gas/i386/ilp32/x86-64-size-2.d
new file mode 100644 (file)
index 0000000..8b210bf
--- /dev/null
@@ -0,0 +1,20 @@
+#name: x32 size 2
+#source: ../size-2.s
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:    b8 50 00 00 00          mov    \$0x50,%eax
+[      ]*[a-f0-9]+:    b8 48 00 00 00          mov    \$0x48,%eax
+[      ]*[a-f0-9]+:    b8 58 00 00 00          mov    \$0x58,%eax
+[      ]*[a-f0-9]+:    b8 1e 00 00 00          mov    \$0x1e,%eax
+[      ]*[a-f0-9]+:    b8 0e 00 00 00          mov    \$0xe,%eax
+[      ]*[a-f0-9]+:    b8 2e 00 00 00          mov    \$0x2e,%eax
+[      ]*[a-f0-9]+:    b8 90 99 99 19          mov    \$0x19999990,%eax
+[      ]*[a-f0-9]+:    b8 70 99 99 19          mov    \$0x19999970,%eax
+[      ]*[a-f0-9]+:    b8 b0 99 99 19          mov    \$0x199999b0,%eax
+#pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-size-3.d b/gas/testsuite/gas/i386/ilp32/x86-64-size-3.d
new file mode 100644 (file)
index 0000000..044c1e2
--- /dev/null
@@ -0,0 +1,19 @@
+#name: x32 size 3
+#source: ../size-3.s
+#readelf: -r
+
+
+Relocation section '.rela.text' at offset 0x334 contains 6 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+0+1  00000620 R_X86_64_SIZE32   00000000   xxx \+ 0
+0+6  00000620 R_X86_64_SIZE32   00000000   xxx - 8
+0+b  00000620 R_X86_64_SIZE32   00000000   xxx \+ 8
+0+10  00000720 R_X86_64_SIZE32   00000000   yyy \+ 0
+0+15  00000720 R_X86_64_SIZE32   00000000   yyy - 10
+0+1a  00000720 R_X86_64_SIZE32   00000000   yyy \+ 10
+
+Relocation section '.rela.tdata' at offset 0x37c contains 2 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+0+50  00000620 R_X86_64_SIZE32   00000000   xxx - 1
+0+54  00000720 R_X86_64_SIZE32   00000000   yyy \+ 2
+#pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-size-4.d b/gas/testsuite/gas/i386/ilp32/x86-64-size-4.d
new file mode 100644 (file)
index 0000000..8d9ae19
--- /dev/null
@@ -0,0 +1,18 @@
+#name: x32 size 4
+#source: ../size-4.s
+#objdump: -dwr
+
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:    b8 50 00 00 00          mov    \$0x50,%eax
+[      ]*[a-f0-9]+:    b8 48 00 00 00          mov    \$0x48,%eax
+[      ]*[a-f0-9]+:    b8 58 00 00 00          mov    \$0x58,%eax
+[      ]*[a-f0-9]+:    b8 1e 00 00 00          mov    \$0x1e,%eax
+[      ]*[a-f0-9]+:    b8 0e 00 00 00          mov    \$0xe,%eax
+[      ]*[a-f0-9]+:    b8 2e 00 00 00          mov    \$0x2e,%eax
+#pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-size-5.d b/gas/testsuite/gas/i386/ilp32/x86-64-size-5.d
new file mode 100644 (file)
index 0000000..1c420fa
--- /dev/null
@@ -0,0 +1,17 @@
+#name: x32 size 5
+#source: ../x86-64-size-5.s
+#readelf: -r
+
+
+Relocation section '.rela.text' at offset 0x2dc contains 3 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+0+2  00000421 R_X86_64_SIZE64   00000000   xxx \+ 0
+0+c  00000421 R_X86_64_SIZE64   00000000   xxx - 8
+0+16  00000421 R_X86_64_SIZE64   00000000   xxx \+ 8
+
+Relocation section '.rela.data' at offset 0x300 contains 3 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+0+50  00000421 R_X86_64_SIZE64   00000000   xxx - 1
+0+58  00000621 R_X86_64_SIZE64   00000000   yyy \+ c8
+0+60  00000521 R_X86_64_SIZE64   00000020   zzz \+ 0
+#pass
diff --git a/gas/testsuite/gas/i386/size-1.d b/gas/testsuite/gas/i386/size-1.d
new file mode 100644 (file)
index 0000000..ae10fdf
--- /dev/null
@@ -0,0 +1,22 @@
+#name: i386 size 1
+#readelf: -r
+
+
+Relocation section '.rel.text' at offset 0x2dc contains 9 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+0+1  00000426 R_386_SIZE32      00000000   xxx
+0+6  00000426 R_386_SIZE32      00000000   xxx
+0+b  00000426 R_386_SIZE32      00000000   xxx
+0+10  00000526 R_386_SIZE32      00000000   yyy
+0+15  00000526 R_386_SIZE32      00000000   yyy
+0+1a  00000526 R_386_SIZE32      00000000   yyy
+0+1f  00000626 R_386_SIZE32      00000020   zzz
+0+24  00000626 R_386_SIZE32      00000020   zzz
+0+29  00000626 R_386_SIZE32      00000020   zzz
+
+Relocation section '.rel.data' at offset 0x324 contains 3 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+0+50  00000426 R_386_SIZE32      00000000   xxx
+0+54  00000526 R_386_SIZE32      00000000   yyy
+0+58  00000626 R_386_SIZE32      00000020   zzz
+#pass
diff --git a/gas/testsuite/gas/i386/size-1.s b/gas/testsuite/gas/i386/size-1.s
new file mode 100644 (file)
index 0000000..2a19dbd
--- /dev/null
@@ -0,0 +1,27 @@
+# Test SIZE32 relocations against global symbols
+       .text
+       movl    $xxx@SIZE, %eax
+       movl    $xxx@SIZE - 8, %eax
+       movl    $xxx@SIZE + 8, %eax
+       movl    $yyy@SIZE, %eax
+       movl    $yyy@SIZE - 16, %eax
+       movl    $yyy@SIZE + 16, %eax
+       movl    $zzz@SIZE, %eax
+       movl    $zzz@SIZE - 32, %eax
+       movl    $zzz@SIZE + 32, %eax
+       .comm   zzz,429496729,32
+       .bss
+       .global yyy
+       .type   yyy,%object
+       .size   yyy,30
+yyy:
+       .zero   30
+       .data
+       .global xxx
+       .type   xxx,%object
+       .size   xxx,80
+xxx:
+       .zero   80
+       .long   xxx@SIZE - 1
+       .long   yyy@SIZE + 2
+       .long   zzz@SIZE
diff --git a/gas/testsuite/gas/i386/size-2.d b/gas/testsuite/gas/i386/size-2.d
new file mode 100644 (file)
index 0000000..685720b
--- /dev/null
@@ -0,0 +1,20 @@
+#name: i386 size 2
+#objdump: -dwr
+
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:    b8 50 00 00 00          mov    \$0x50,%eax
+[      ]*[a-f0-9]+:    b8 48 00 00 00          mov    \$0x48,%eax
+[      ]*[a-f0-9]+:    b8 58 00 00 00          mov    \$0x58,%eax
+[      ]*[a-f0-9]+:    b8 1e 00 00 00          mov    \$0x1e,%eax
+[      ]*[a-f0-9]+:    b8 0e 00 00 00          mov    \$0xe,%eax
+[      ]*[a-f0-9]+:    b8 2e 00 00 00          mov    \$0x2e,%eax
+[      ]*[a-f0-9]+:    b8 90 99 99 19          mov    \$0x19999990,%eax
+[      ]*[a-f0-9]+:    b8 70 99 99 19          mov    \$0x19999970,%eax
+[      ]*[a-f0-9]+:    b8 b0 99 99 19          mov    \$0x199999b0,%eax
+#pass
diff --git a/gas/testsuite/gas/i386/size-2.s b/gas/testsuite/gas/i386/size-2.s
new file mode 100644 (file)
index 0000000..09f8f47
--- /dev/null
@@ -0,0 +1,26 @@
+# Test SIZE32 relocations against local symbols
+       .text
+       movl    $xxx@SIZE, %eax
+       movl    $xxx@SIZE - 8, %eax
+       movl    $xxx@SIZE + 8, %eax
+       movl    $yyy@SIZE, %eax
+       movl    $yyy@SIZE - 16, %eax
+       movl    $yyy@SIZE + 16, %eax
+       movl    $zzz@SIZE, %eax
+       movl    $zzz@SIZE - 32, %eax
+       movl    $zzz@SIZE + 32, %eax
+       .local  zzz
+       .comm   zzz,429496720,32
+       .bss
+       .type   yyy,%object
+       .size   yyy,30
+yyy:
+       .zero   30
+       .data
+       .type   xxx,%object
+       .size   xxx,80
+xxx:
+       .zero   80
+       .long   xxx@SIZE - 1
+       .long   yyy@SIZE + 2
+       .long   zzz@SIZE
diff --git a/gas/testsuite/gas/i386/size-3.d b/gas/testsuite/gas/i386/size-3.d
new file mode 100644 (file)
index 0000000..78a9fb6
--- /dev/null
@@ -0,0 +1,18 @@
+#name: i386 size 3
+#readelf: -r
+
+
+Relocation section '.rel.text' at offset 0x334 contains 6 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+0+1  00000626 R_386_SIZE32      00000000   xxx
+0+6  00000626 R_386_SIZE32      00000000   xxx
+0+b  00000626 R_386_SIZE32      00000000   xxx
+0+10  00000726 R_386_SIZE32      00000000   yyy
+0+15  00000726 R_386_SIZE32      00000000   yyy
+0+1a  00000726 R_386_SIZE32      00000000   yyy
+
+Relocation section '.rel.tdata' at offset 0x364 contains 2 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+0+50  00000626 R_386_SIZE32      00000000   xxx
+0+54  00000726 R_386_SIZE32      00000000   yyy
+#pass
diff --git a/gas/testsuite/gas/i386/size-3.s b/gas/testsuite/gas/i386/size-3.s
new file mode 100644 (file)
index 0000000..420cb84
--- /dev/null
@@ -0,0 +1,22 @@
+# Test SIZE32 relocations against global TLS symbols
+       .text
+       movl    $xxx@SIZE, %eax
+       movl    $xxx@SIZE - 8, %eax
+       movl    $xxx@SIZE + 8, %eax
+       movl    $yyy@SIZE, %eax
+       movl    $yyy@SIZE - 16, %eax
+       movl    $yyy@SIZE + 16, %eax
+       .section .tbss,"awT",%nobits
+       .global yyy
+       .type   yyy,%object
+       .size   yyy,30
+yyy:
+       .zero   30
+       .section .tdata,"awT",%progbits
+       .global xxx
+       .type   xxx,%object
+       .size   xxx,80
+xxx:
+       .zero   80
+       .long   xxx@SIZE - 1
+       .long   yyy@SIZE + 2
diff --git a/gas/testsuite/gas/i386/size-4.d b/gas/testsuite/gas/i386/size-4.d
new file mode 100644 (file)
index 0000000..384542c
--- /dev/null
@@ -0,0 +1,17 @@
+#name: i386 size 4
+#objdump: -dwr
+
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:    b8 50 00 00 00          mov    \$0x50,%eax
+[      ]*[a-f0-9]+:    b8 48 00 00 00          mov    \$0x48,%eax
+[      ]*[a-f0-9]+:    b8 58 00 00 00          mov    \$0x58,%eax
+[      ]*[a-f0-9]+:    b8 1e 00 00 00          mov    \$0x1e,%eax
+[      ]*[a-f0-9]+:    b8 0e 00 00 00          mov    \$0xe,%eax
+[      ]*[a-f0-9]+:    b8 2e 00 00 00          mov    \$0x2e,%eax
+#pass
diff --git a/gas/testsuite/gas/i386/size-4.s b/gas/testsuite/gas/i386/size-4.s
new file mode 100644 (file)
index 0000000..1e0944c
--- /dev/null
@@ -0,0 +1,20 @@
+# Test SIZE32 relocations against local TLS symbols
+       .text
+       movl    $xxx@SIZE, %eax
+       movl    $xxx@SIZE - 8, %eax
+       movl    $xxx@SIZE + 8, %eax
+       movl    $yyy@SIZE, %eax
+       movl    $yyy@SIZE - 16, %eax
+       movl    $yyy@SIZE + 16, %eax
+       .section .tbss,"awT",%nobits
+       .type   yyy,%object
+       .size   yyy,30
+yyy:
+       .zero   30
+       .section .tdata,"awT",%progbits
+       .type   xxx,%object
+       .size   xxx,80
+xxx:
+       .zero   80
+       .long   xxx@SIZE - 1
+       .long   yyy@SIZE + 2
diff --git a/gas/testsuite/gas/i386/x86-64-size-1.d b/gas/testsuite/gas/i386/x86-64-size-1.d
new file mode 100644 (file)
index 0000000..03484f8
--- /dev/null
@@ -0,0 +1,23 @@
+#name: x86-64 size 1
+#source: size-1.s
+#readelf: -r
+
+
+Relocation section '.rela.text' at offset 0x400 contains 9 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+0+1  000400000020 R_X86_64_SIZE32   0000000000000000 xxx \+ 0
+0+6  000400000020 R_X86_64_SIZE32   0000000000000000 xxx - 8
+0+b  000400000020 R_X86_64_SIZE32   0000000000000000 xxx \+ 8
+0+10  000500000020 R_X86_64_SIZE32   0000000000000000 yyy \+ 0
+0+15  000500000020 R_X86_64_SIZE32   0000000000000000 yyy - 10
+0+1a  000500000020 R_X86_64_SIZE32   0000000000000000 yyy \+ 10
+0+1f  000600000020 R_X86_64_SIZE32   0000000000000020 zzz \+ 0
+0+24  000600000020 R_X86_64_SIZE32   0000000000000020 zzz - 20
+0+29  000600000020 R_X86_64_SIZE32   0000000000000020 zzz \+ 20
+
+Relocation section '.rela.data' at offset 0x4d8 contains 3 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+0+50  000400000020 R_X86_64_SIZE32   0000000000000000 xxx - 1
+0+54  000500000020 R_X86_64_SIZE32   0000000000000000 yyy \+ 2
+0+58  000600000020 R_X86_64_SIZE32   0000000000000020 zzz \+ 0
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-size-2.d b/gas/testsuite/gas/i386/x86-64-size-2.d
new file mode 100644 (file)
index 0000000..f144c47
--- /dev/null
@@ -0,0 +1,21 @@
+#name: x86-64 size 2
+#source: size-2.s
+#objdump: -dwr
+
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:    b8 50 00 00 00          mov    \$0x50,%eax
+[      ]*[a-f0-9]+:    b8 48 00 00 00          mov    \$0x48,%eax
+[      ]*[a-f0-9]+:    b8 58 00 00 00          mov    \$0x58,%eax
+[      ]*[a-f0-9]+:    b8 1e 00 00 00          mov    \$0x1e,%eax
+[      ]*[a-f0-9]+:    b8 0e 00 00 00          mov    \$0xe,%eax
+[      ]*[a-f0-9]+:    b8 2e 00 00 00          mov    \$0x2e,%eax
+[      ]*[a-f0-9]+:    b8 90 99 99 19          mov    \$0x19999990,%eax
+[      ]*[a-f0-9]+:    b8 70 99 99 19          mov    \$0x19999970,%eax
+[      ]*[a-f0-9]+:    b8 b0 99 99 19          mov    \$0x199999b0,%eax
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-size-3.d b/gas/testsuite/gas/i386/x86-64-size-3.d
new file mode 100644 (file)
index 0000000..0ce908e
--- /dev/null
@@ -0,0 +1,19 @@
+#name: x86-64 size 3
+#source: size-3.s
+#readelf: -r
+
+
+Relocation section '.rela.text' at offset 0x490 contains 6 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+0+1  000600000020 R_X86_64_SIZE32   0000000000000000 xxx \+ 0
+0+6  000600000020 R_X86_64_SIZE32   0000000000000000 xxx - 8
+0+b  000600000020 R_X86_64_SIZE32   0000000000000000 xxx \+ 8
+0+10  000700000020 R_X86_64_SIZE32   0000000000000000 yyy \+ 0
+0+15  000700000020 R_X86_64_SIZE32   0000000000000000 yyy - 10
+0+1a  000700000020 R_X86_64_SIZE32   0000000000000000 yyy \+ 10
+
+Relocation section '.rela.tdata' at offset 0x520 contains 2 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+0+50  000600000020 R_X86_64_SIZE32   0000000000000000 xxx - 1
+0+54  000700000020 R_X86_64_SIZE32   0000000000000000 yyy \+ 2
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-size-4.d b/gas/testsuite/gas/i386/x86-64-size-4.d
new file mode 100644 (file)
index 0000000..8c3583c
--- /dev/null
@@ -0,0 +1,18 @@
+#name: x86-64 size 4
+#source: size-4.s
+#objdump: -dwr
+
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <.text>:
+[      ]*[a-f0-9]+:    b8 50 00 00 00          mov    \$0x50,%eax
+[      ]*[a-f0-9]+:    b8 48 00 00 00          mov    \$0x48,%eax
+[      ]*[a-f0-9]+:    b8 58 00 00 00          mov    \$0x58,%eax
+[      ]*[a-f0-9]+:    b8 1e 00 00 00          mov    \$0x1e,%eax
+[      ]*[a-f0-9]+:    b8 0e 00 00 00          mov    \$0xe,%eax
+[      ]*[a-f0-9]+:    b8 2e 00 00 00          mov    \$0x2e,%eax
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-size-5.d b/gas/testsuite/gas/i386/x86-64-size-5.d
new file mode 100644 (file)
index 0000000..be7e90d
--- /dev/null
@@ -0,0 +1,16 @@
+#name: x86-64 size 5
+#readelf: -r
+
+
+Relocation section '.rela.text' at offset 0x3f8 contains 3 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+0+2  000400000021 R_X86_64_SIZE64   0000000000000000 xxx \+ 0
+0+c  000400000021 R_X86_64_SIZE64   0000000000000000 xxx - 8
+0+16  000400000021 R_X86_64_SIZE64   0000000000000000 xxx \+ 8
+
+Relocation section '.rela.data' at offset 0x440 contains 3 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+0+50  000400000021 R_X86_64_SIZE64   0000000000000000 xxx - 1
+0+58  000600000021 R_X86_64_SIZE64   0000000000000000 yyy \+ c8
+0+60  000500000021 R_X86_64_SIZE64   0000000000000020 zzz \+ 0
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-size-5.s b/gas/testsuite/gas/i386/x86-64-size-5.s
new file mode 100644 (file)
index 0000000..42d248e
--- /dev/null
@@ -0,0 +1,21 @@
+# Test SIZE64 relocation
+       .text
+       movq    $xxx@SIZE, %r15
+       movq    $xxx@SIZE - 8, %r15
+       movq    $xxx@SIZE + 8, %r15
+       .comm   zzz,4294967290,32
+       .bss
+       .global yyy
+       .type   yyy,%object
+       .size   yyy,30
+yyy:
+       .zero   30
+       .data
+       .global xxx
+       .type   xxx,%object
+       .size   xxx,80
+xxx:
+       .zero   80
+       .quad   xxx@SIZE - 1
+       .quad   yyy@SIZE + 200
+       .quad   zzz@SIZE
diff --git a/gas/testsuite/gas/i386/x86-64-size-inval-1.l b/gas/testsuite/gas/i386/x86-64-size-inval-1.l
new file mode 100644 (file)
index 0000000..856174d
--- /dev/null
@@ -0,0 +1,25 @@
+.*: Assembler messages:
+.*:5: Error: .*
+.*:6: Error: .*
+.*:10: Error: .*
+.*:11: Error: .*
+GAS LISTING .*
+
+
+[      ]*1[    ]+\# Test SIZE32 relocation overflow
+[      ]*2[    ]+\.local       yyy
+[      ]*3[    ]+\.comm        yyy,80,32
+[      ]*4[    ]+\.text
+[      ]*5[    ]+\?\?\?\? B85E0000             movl    \$xxx@SIZE \+ 100, %eax
+[      ]*5[    ]+00
+[      ]*6[    ]+\?\?\?\? B8ECFFFF             movl    \$yyy@SIZE - 100, %eax
+[      ]*6[    ]+FF
+[      ]*7[    ]+\.local       xxx
+[      ]*8[    ]+\.comm        xxx,4294967290,32
+[      ]*9[    ]+\.data
+[      ]*10[   ]+\?\?\?\? 5E000000             \.long  xxx@SIZE \+ 100
+[      ]*11[   ]+\?\?\?\? ECFFFFFF             \.long  yyy@SIZE - 100
+\*\*\*\*  Error:symbol size computation overflow
+\*\*\*\*  Error:symbol size computation overflow
+\*\*\*\*  Error:symbol size computation overflow
+\*\*\*\*  Error:symbol size computation overflow
diff --git a/gas/testsuite/gas/i386/x86-64-size-inval-1.s b/gas/testsuite/gas/i386/x86-64-size-inval-1.s
new file mode 100644 (file)
index 0000000..020eb10
--- /dev/null
@@ -0,0 +1,11 @@
+# Test SIZE32 relocation overflow
+       .local  yyy
+       .comm   yyy,80,32
+       .text
+       movl    $xxx@SIZE + 100, %eax
+       movl    $yyy@SIZE - 100, %eax
+       .local  xxx
+       .comm   xxx,4294967290,32
+       .data
+       .long   xxx@SIZE + 100
+       .long   yyy@SIZE - 100
index 017758a19c0d143f20089143aa1527aaf0f4eade..c578fb681f1a4c755891fd817fdbea0e990fbd98 100644 (file)
@@ -1,3 +1,41 @@
+2013-01-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * ld-size/size.exp: New file.
+       * ld-size/size32-1-i386.d: Likewise.
+       * ld-size/size32-1-x32.d: Likewise.
+       * ld-size/size32-1-x86-64.d: Likewise.
+       * ld-size/size32-1.s: Likewise.
+       * ld-size/size32-2-i386.d: Likewise.
+       * ld-size/size32-2-x32.d: Likewise.
+       * ld-size/size32-2-x86-64.d: Likewise.
+       * ld-size/size32-2.s: Likewise.
+       * ld-size/size64-1-x32.d: Likewise.
+       * ld-size/size64-1-x86-64.d: Likewise.
+       * ld-size/size64-1.s: Likewise.
+       * ld-size/size64-2-x32.d: Likewise.
+       * ld-size/size64-2-x86-64.d: Likewise.
+       * ld-size/size64-2.s: Likewise.
+       * ld-size/size-3.c: Likewise.
+       * ld-size/size-3.out: Likewise.
+       * ld-size/size-3a.c: Likewise.
+       * ld-size/size-3b.c: Likewise.
+       * ld-size/size-3c.c: Likewise.
+       * ld-size/size-4.out: Likewise.
+       * ld-size/size-4a.c: Likewise.
+       * ld-size/size-4b.c: Likewise.
+       * ld-size/size-5.out: Likewise.
+       * ld-size/size-5a.c: Likewise.
+       * ld-size/size-5b.c: Likewise.
+       * ld-size/size-6.out: Likewise.
+       * ld-size/size-6a.c: Likewise.
+       * ld-size/size-6b.c: Likewise.
+       * ld-size/size-7.rd: Likewise.
+       * ld-size/size-7a.c: Likewise.
+       * ld-size/size-7b.c: Likewise.
+       * ld-size/size-8.rd: Likewise.
+       * ld-size/size-8a.c: Likewise.
+       * ld-size/size-8b.c: Likewise.
+
 2013-01-16  Alan Modra  <amodra@gmail.com>
 
        * ld-plugin/lto.exp (lto-9.o, pr13229.o): Pass -finline.
diff --git a/ld/testsuite/ld-size/size-3.c b/ld/testsuite/ld-size/size-3.c
new file mode 100644 (file)
index 0000000..71a7a66
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+extern int bar_size;
+
+int
+main ()
+{
+  if (bar_size == 10)
+    printf ("OK\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-size/size-3.out b/ld/testsuite/ld-size/size-3.out
new file mode 100644 (file)
index 0000000..d86bac9
--- /dev/null
@@ -0,0 +1 @@
+OK
diff --git a/ld/testsuite/ld-size/size-3a.c b/ld/testsuite/ld-size/size-3a.c
new file mode 100644 (file)
index 0000000..b321559
--- /dev/null
@@ -0,0 +1,3 @@
+char bar[10] __attribute__ ((visibility("hidden")));
+extern char size_of_bar asm ("bar@SIZE");
+char *bar_size = &size_of_bar;
diff --git a/ld/testsuite/ld-size/size-3b.c b/ld/testsuite/ld-size/size-3b.c
new file mode 100644 (file)
index 0000000..fc379df
--- /dev/null
@@ -0,0 +1,4 @@
+static char bar[10];
+extern char size_of_bar asm ("bar@SIZE");
+char *bar_size = &size_of_bar;
+char *bar_p = bar;
diff --git a/ld/testsuite/ld-size/size-3c.c b/ld/testsuite/ld-size/size-3c.c
new file mode 100644 (file)
index 0000000..d94ceef
--- /dev/null
@@ -0,0 +1,3 @@
+__thread char bar[10] __attribute__ ((visibility("hidden")));
+extern char size_of_bar asm ("bar@SIZE");
+char *bar_size = &size_of_bar;
diff --git a/ld/testsuite/ld-size/size-4.out b/ld/testsuite/ld-size/size-4.out
new file mode 100644 (file)
index 0000000..2c94e48
--- /dev/null
@@ -0,0 +1,2 @@
+OK
+OK
diff --git a/ld/testsuite/ld-size/size-4a.c b/ld/testsuite/ld-size/size-4a.c
new file mode 100644 (file)
index 0000000..b11089b
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+char bar[10];
+char foo[20] = { 1 } ;
+extern int bar_size1 (void);
+extern int bar_size2 (void);
+extern int foo_size1 (void);
+extern int foo_size2 (void);
+
+int
+main ()
+{
+  int size;
+  
+  size = bar_size1 ();
+  if (size == sizeof (bar) && bar_size2 () == size)
+    printf ("OK\n");
+
+  size = foo_size1 ();
+  if (size == sizeof (foo) && foo_size2 () == size)
+    printf ("OK\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-size/size-4b.c b/ld/testsuite/ld-size/size-4b.c
new file mode 100644 (file)
index 0000000..c618be0
--- /dev/null
@@ -0,0 +1,35 @@
+extern char bar[];
+extern char size_of_bar asm ("bar@SIZE");
+
+char *bar_size_1 = &size_of_bar;
+static char *bar_size_2 = &size_of_bar;
+
+char *
+bar_size1 (void)
+{
+  return bar_size_1;
+}
+
+char *
+bar_size2 (void)
+{
+  return bar_size_2;
+}
+
+extern char foo[];
+extern char size_of_foo asm ("foo@SIZE");
+
+char *foo_size_1 = &size_of_foo;
+static char *foo_size_2 = &size_of_foo;
+
+char *
+foo_size1 (void)
+{
+  return foo_size_1;
+}
+
+char *
+foo_size2 (void)
+{
+  return foo_size_2;
+}
diff --git a/ld/testsuite/ld-size/size-5.out b/ld/testsuite/ld-size/size-5.out
new file mode 100644 (file)
index 0000000..2c94e48
--- /dev/null
@@ -0,0 +1,2 @@
+OK
+OK
diff --git a/ld/testsuite/ld-size/size-5a.c b/ld/testsuite/ld-size/size-5a.c
new file mode 100644 (file)
index 0000000..500678a
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+__thread char bar[10];
+__thread char foo[20] = { 1 } ;
+extern int bar_size1 (void);
+extern int bar_size2 (void);
+extern int foo_size1 (void);
+extern int foo_size2 (void);
+
+int
+main ()
+{
+  int size;
+  
+  size = bar_size1 ();
+  if (bar[2] == 3 && size == sizeof (bar) && bar_size2 () == size)
+    printf ("OK\n");
+
+  size = foo_size1 ();
+  if (foo[3] == 4 && size == sizeof (foo) && foo_size2 () == size)
+    printf ("OK\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-size/size-5b.c b/ld/testsuite/ld-size/size-5b.c
new file mode 100644 (file)
index 0000000..a9450a5
--- /dev/null
@@ -0,0 +1,37 @@
+extern __thread char bar[];
+extern char size_of_bar asm ("bar@SIZE");
+
+char *bar_size_1 = &size_of_bar;
+static char *bar_size_2 = &size_of_bar;
+
+char *
+bar_size1 (void)
+{
+  bar[2] = 3;
+  return bar_size_1;
+}
+
+char *
+bar_size2 (void)
+{
+  return bar_size_2;
+}
+
+extern __thread char foo[];
+extern char size_of_foo asm ("foo@SIZE");
+
+char *foo_size_1 = &size_of_foo;
+static char *foo_size_2 = &size_of_foo;
+
+char *
+foo_size1 (void)
+{
+  foo[3] = 4;
+  return foo_size_1;
+}
+
+char *
+foo_size2 (void)
+{
+  return foo_size_2;
+}
diff --git a/ld/testsuite/ld-size/size-6.out b/ld/testsuite/ld-size/size-6.out
new file mode 100644 (file)
index 0000000..d86bac9
--- /dev/null
@@ -0,0 +1 @@
+OK
diff --git a/ld/testsuite/ld-size/size-6a.c b/ld/testsuite/ld-size/size-6a.c
new file mode 100644 (file)
index 0000000..3946fb1
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+extern char bar[];
+extern char size_of_bar asm ("bar@SIZE");
+extern void set_bar (int, int);
+
+int
+main ()
+{
+  set_bar (1, 20);
+  if (10 == (long) &size_of_bar && bar[1] == 20)
+    printf ("OK\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-size/size-6b.c b/ld/testsuite/ld-size/size-6b.c
new file mode 100644 (file)
index 0000000..5014bb5
--- /dev/null
@@ -0,0 +1,7 @@
+char bar[10];
+
+void
+set_bar (int i, int v)
+{
+  bar[i] = v;
+}
diff --git a/ld/testsuite/ld-size/size-7.rd b/ld/testsuite/ld-size/size-7.rd
new file mode 100644 (file)
index 0000000..a5f8ee8
--- /dev/null
@@ -0,0 +1,3 @@
+#...
+[0-9a-f]+ +[0-9a-f]+ +R_.*_SIZE(32|64) +.*
+#pass
diff --git a/ld/testsuite/ld-size/size-7a.c b/ld/testsuite/ld-size/size-7a.c
new file mode 100644 (file)
index 0000000..c415180
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+extern char size_of_bar asm ("bar@SIZE");
+
+int
+main ()
+{
+  if (10 == (long) &size_of_bar)
+    printf ("OK\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-size/size-7b.c b/ld/testsuite/ld-size/size-7b.c
new file mode 100644 (file)
index 0000000..b95ad01
--- /dev/null
@@ -0,0 +1 @@
+char bar[10];
diff --git a/ld/testsuite/ld-size/size-8.rd b/ld/testsuite/ld-size/size-8.rd
new file mode 100644 (file)
index 0000000..a5f8ee8
--- /dev/null
@@ -0,0 +1,3 @@
+#...
+[0-9a-f]+ +[0-9a-f]+ +R_.*_SIZE(32|64) +.*
+#pass
diff --git a/ld/testsuite/ld-size/size-8a.c b/ld/testsuite/ld-size/size-8a.c
new file mode 100644 (file)
index 0000000..78c5732
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+extern __thread char bar[];
+extern char size_of_bar asm ("bar@SIZE");
+extern void set_bar (int, int);
+
+int
+main ()
+{
+  set_bar (1, 20);
+  if (10 == (long) &size_of_bar && bar[1] == 20)
+    printf ("OK\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-size/size-8b.c b/ld/testsuite/ld-size/size-8b.c
new file mode 100644 (file)
index 0000000..e9f1204
--- /dev/null
@@ -0,0 +1,7 @@
+__thread char bar[10];
+
+void
+set_bar (int i, int v)
+{
+  bar[i] = v;
+}
diff --git a/ld/testsuite/ld-size/size.exp b/ld/testsuite/ld-size/size.exp
new file mode 100644 (file)
index 0000000..4bbb5d7
--- /dev/null
@@ -0,0 +1,122 @@
+# Expect script for linker support of size relocations.
+#
+#   Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+
+# Size relications have only been implemented for the ix86 and x86_64,
+# so far.
+if {!(([istarget "i?86-*-*"]
+       || [istarget "x86_64-*-*"])
+      && ([istarget "*-*-elf*"]
+         || [istarget "*-*-nacl*"]
+         || (([istarget "*-*-linux*"]
+              || [istarget "*-*-gnu*"])
+             && ![istarget "*-*-*aout*"]
+             && ![istarget "*-*-*oldld*"]))) } {
+    verbose "Size relocations tests not run - no target support"
+    return
+}
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach t $test_list {
+    # We need to strip the ".d", but can leave the dirname.
+    verbose [file rootname $t]
+    run_dump_test [file rootname $t]
+}
+
+# We need a native system.
+if ![isnative] {
+    verbose "Natibe size relocation tests not run - not a native toolchain"
+    return
+}
+
+# We need a working compiler.
+if { [which $CC] == 0 } {
+    verbose "Native size relocation tests not run - no compiler available"
+    return
+}
+
+set build_tests {
+  {"Build libsize-3a.so"
+   "-shared" "-fPIC"
+   {size-3a.c} {} "libsize-3a.so"}
+  {"Build libsize-3b.so"
+   "-shared" "-fPIC"
+   {size-3b.c} {} "libsize-3b.so"}
+  {"Build libsize-3c.so"
+   "-shared" "-fPIC"
+   {size-3c.c} {} "libsize-3c.so"}
+  {"Build libsize-6b.so"
+   "-shared" "-fPIC"
+   {size-6b.c} {} "libsize-6b.so"}
+  {"Build libsize-7.so"
+   "-shared" "-fPIC"
+   {size-7b.c} {} "libsize-7.so"}
+  {"Build size-7"
+   "tmpdir/libsize-7.so" ""
+   {size-7a.c} {{readelf -rW size-7.rd}} "size-7.exe"}
+  {"Build libsize-8.so"
+   "-shared" "-fPIC"
+   {size-8b.c} {} "libsize-8.so"}
+  {"Build size-8"
+   "tmpdir/libsize-8.so" ""
+   {size-8a.c} {{readelf -rW size-8.rd}} "size-8.exe"}
+}
+
+run_cc_link_tests $build_tests
+
+set run_tests {
+    {"Run size-3a"
+     "" ""
+     {size-3.c size-3a.c} "size-3a" "size-3.out"}
+    {"Run size-3b"
+     "tmpdir/libsize-3a.so" ""
+     {size-3.c} "size-3b" "size-3.out"}
+    {"Run size-3c"
+     "" ""
+     {size-3.c size-3b.c} "size-3c" "size-3.out"}
+    {"Run size-3d"
+     "tmpdir/libsize-3b.so" ""
+     {size-3.c} "size-3d" "size-3.out"}
+    {"Run size-3d"
+     "" ""
+     {size-3.c size-3c.c} "size-3d" "size-3.out"}
+    {"Run size-3e"
+     "tmpdir/libsize-3c.so" ""
+     {size-3.c} "size-3e" "size-3.out"}
+    {"Run size-4a"
+     "" ""
+     {size-4a.c size-4b.c} "size-4a" "size-4.out"}
+    {"Run size-4b"
+     "" ""
+     {size-4b.c size-4a.c} "size-4b" "size-4.out"}
+    {"Run size-5a"
+     "" ""
+     {size-5a.c size-5b.c} "size-5a" "size-5.out"}
+    {"Run size-5b"
+     "" ""
+     {size-5b.c size-5a.c} "size-5b" "size-5.out"}
+    {"Run size-6"
+     "tmpdir/libsize-6b.so" ""
+     {size-6a.c} "size-6" "size-6.out"}
+}
+
+run_ld_link_exec_tests [] $run_tests
diff --git a/ld/testsuite/ld-size/size32-1-i386.d b/ld/testsuite/ld-size/size32-1-i386.d
new file mode 100644 (file)
index 0000000..e8a6622
--- /dev/null
@@ -0,0 +1,22 @@
+#source: size32-1.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -R -s -j .data
+#target: x86_64-*-* i?86-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+0+11f4 R_386_SIZE32      xxx
+0+11f8 R_386_SIZE32      xxx
+0+11fc R_386_SIZE32      xxx
+0+1200 R_386_SIZE32      yyy
+0+1204 R_386_SIZE32      zzz
+
+
+Contents of section .data:
+ 11f4 00000000 e2ffffff 1e000000 00000000  ................
+ 1204 00000000 00000000 00000000 00000000  ................
+ 1214 00000000 00000000 00000000 00000000  ................
+ 1224 00000000 00000000 00000000           ............    
diff --git a/ld/testsuite/ld-size/size32-1-x32.d b/ld/testsuite/ld-size/size32-1-x32.d
new file mode 100644 (file)
index 0000000..1022dba
--- /dev/null
@@ -0,0 +1,22 @@
+#source: size32-1.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+0+200220 R_X86_64_SIZE32   xxx
+0+200224 R_X86_64_SIZE32   xxx-0x0000001e
+0+200228 R_X86_64_SIZE32   xxx\+0x0000001e
+0+20022c R_X86_64_SIZE32   yyy
+0+200230 R_X86_64_SIZE32   zzz
+
+
+Contents of section .data:
+ 200220 00000000 00000000 00000000 00000000  ................
+ 200230 00000000 00000000 00000000 00000000  ................
+ 200240 00000000 00000000 00000000 00000000  ................
+ 200250 00000000 00000000 00000000           ............    
diff --git a/ld/testsuite/ld-size/size32-1-x86-64.d b/ld/testsuite/ld-size/size32-1-x86-64.d
new file mode 100644 (file)
index 0000000..80c4a66
--- /dev/null
@@ -0,0 +1,22 @@
+#source: size32-1.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET           TYPE              VALUE 
+0+200360 R_X86_64_SIZE32   xxx
+0+200364 R_X86_64_SIZE32   xxx-0x000000000000001e
+0+200368 R_X86_64_SIZE32   xxx\+0x000000000000001e
+0+20036c R_X86_64_SIZE32   yyy
+0+200370 R_X86_64_SIZE32   zzz
+
+
+Contents of section .data:
+ 200360 00000000 00000000 00000000 00000000  ................
+ 200370 00000000 00000000 00000000 00000000  ................
+ 200380 00000000 00000000 00000000 00000000  ................
+ 200390 00000000 00000000 00000000           ............    
diff --git a/ld/testsuite/ld-size/size32-1.s b/ld/testsuite/ld-size/size32-1.s
new file mode 100644 (file)
index 0000000..9e2840c
--- /dev/null
@@ -0,0 +1,14 @@
+# 32-bit size relocation in shared object
+       .comm   xxx,40,32
+       .data
+       .p2align 2
+       .long   xxx@SIZE
+       .long   xxx@SIZE-30
+       .long   xxx@SIZE+30
+       .long   yyy@SIZE
+       .long   zzz@SIZE
+       .globl  yyy
+       .type   yyy, %object
+       .size   yyy, 40
+yyy:
+       .zero   40
diff --git a/ld/testsuite/ld-size/size32-2-i386.d b/ld/testsuite/ld-size/size32-2-i386.d
new file mode 100644 (file)
index 0000000..2db0e1d
--- /dev/null
@@ -0,0 +1,20 @@
+#source: size32-2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -R -s -j .data
+#target: x86_64-*-* i?86-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+0+123c R_386_SIZE32      xxx
+0+1240 R_386_SIZE32      yyy
+0+1244 R_386_SIZE32      zzz
+0+1248 R_386_SIZE32      zzz
+0+124c R_386_SIZE32      zzz
+
+
+Contents of section .data:
+ 123c 00000000 00000000 00000000 e2ffffff  ................
+ 124c 1e000000                             ....            
diff --git a/ld/testsuite/ld-size/size32-2-x32.d b/ld/testsuite/ld-size/size32-2-x32.d
new file mode 100644 (file)
index 0000000..9c1eae2
--- /dev/null
@@ -0,0 +1,20 @@
+#source: size32-2.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+0+200278 R_X86_64_SIZE32   xxx
+0+20027c R_X86_64_SIZE32   yyy
+0+200280 R_X86_64_SIZE32   zzz
+0+200284 R_X86_64_SIZE32   zzz-0x0000001e
+0+200288 R_X86_64_SIZE32   zzz\+0x0000001e
+
+
+Contents of section .data:
+ 200278 00000000 00000000 00000000 00000000  ................
+ 200288 00000000                             ....            
diff --git a/ld/testsuite/ld-size/size32-2-x86-64.d b/ld/testsuite/ld-size/size32-2-x86-64.d
new file mode 100644 (file)
index 0000000..1851e0f
--- /dev/null
@@ -0,0 +1,20 @@
+#source: size32-2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET           TYPE              VALUE 
+0+2003d8 R_X86_64_SIZE32   xxx
+0+2003dc R_X86_64_SIZE32   yyy
+0+2003e0 R_X86_64_SIZE32   zzz
+0+2003e4 R_X86_64_SIZE32   zzz-0x000000000000001e
+0+2003e8 R_X86_64_SIZE32   zzz\+0x000000000000001e
+
+
+Contents of section .data:
+ 2003d8 00000000 00000000 00000000 00000000  ................
+ 2003e8 00000000                             ....            
diff --git a/ld/testsuite/ld-size/size32-2.s b/ld/testsuite/ld-size/size32-2.s
new file mode 100644 (file)
index 0000000..d5a650d
--- /dev/null
@@ -0,0 +1,22 @@
+# 32-bit size relocation against TLS symbol in shared object
+       .globl  xxx
+       .section        .tbss,"awT",%nobits
+       .p2align 2
+       .type   xxx, %object
+       .size   xxx, 40
+xxx:
+       .zero   40
+       .globl  yyy
+       .section        .tdata,"awT",%progbits
+       .p2align 2
+       .type   yyy, %object
+       .size   yyy, 40
+yyy:
+       .zero   40
+       .data
+       .p2align 2
+       .long   xxx@SIZE
+       .long   yyy@SIZE
+       .long   zzz@SIZE
+       .long   zzz@SIZE-30
+       .long   zzz@SIZE+30
diff --git a/ld/testsuite/ld-size/size64-1-x32.d b/ld/testsuite/ld-size/size64-1-x32.d
new file mode 100644 (file)
index 0000000..51c2f13
--- /dev/null
@@ -0,0 +1,23 @@
+#source: size64-1.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+0+200220 R_X86_64_SIZE32   xxx
+0+200228 R_X86_64_SIZE64   xxx-0x0000001e
+0+200230 R_X86_64_SIZE64   xxx\+0x0000001e
+0+200238 R_X86_64_SIZE32   yyy
+0+200240 R_X86_64_SIZE32   zzz
+
+
+Contents of section .data:
+ 200220 00000000 00000000 00000000 00000000  ................
+ 200230 00000000 00000000 00000000 00000000  ................
+ 200240 00000000 00000000 00000000 00000000  ................
+ 200250 00000000 00000000 00000000 00000000  ................
+ 200260 00000000 00000000 00000000 00000000  ................
diff --git a/ld/testsuite/ld-size/size64-1-x86-64.d b/ld/testsuite/ld-size/size64-1-x86-64.d
new file mode 100644 (file)
index 0000000..c4ed9c2
--- /dev/null
@@ -0,0 +1,23 @@
+#source: size64-1.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET           TYPE              VALUE 
+0+200360 R_X86_64_SIZE64   xxx
+0+200368 R_X86_64_SIZE64   xxx-0x000000000000001e
+0+200370 R_X86_64_SIZE64   xxx\+0x000000000000001e
+0+200378 R_X86_64_SIZE64   yyy
+0+200380 R_X86_64_SIZE64   zzz
+
+
+Contents of section .data:
+ 200360 00000000 00000000 00000000 00000000  ................
+ 200370 00000000 00000000 00000000 00000000  ................
+ 200380 00000000 00000000 00000000 00000000  ................
+ 200390 00000000 00000000 00000000 00000000  ................
+ 2003a0 00000000 00000000 00000000 00000000  ................
diff --git a/ld/testsuite/ld-size/size64-1.s b/ld/testsuite/ld-size/size64-1.s
new file mode 100644 (file)
index 0000000..25672b5
--- /dev/null
@@ -0,0 +1,14 @@
+# 64-bit size relocation in shared object
+       .comm   xxx,40,32
+       .data
+       .p2align 2
+       .quad   xxx@SIZE
+       .quad   xxx@SIZE-30
+       .quad   xxx@SIZE+30
+       .quad   yyy@SIZE
+       .quad   zzz@SIZE
+       .globl  yyy
+       .type   yyy, %object
+       .size   yyy, 40
+yyy:
+       .zero   40
diff --git a/ld/testsuite/ld-size/size64-2-x32.d b/ld/testsuite/ld-size/size64-2-x32.d
new file mode 100644 (file)
index 0000000..1a30c98
--- /dev/null
@@ -0,0 +1,21 @@
+#source: size64-2.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+0+200278 R_X86_64_SIZE32   xxx
+0+200280 R_X86_64_SIZE32   yyy
+0+200288 R_X86_64_SIZE32   zzz
+0+200290 R_X86_64_SIZE64   zzz-0x0000001e
+0+200298 R_X86_64_SIZE64   zzz\+0x0000001e
+
+
+Contents of section .data:
+ 200278 00000000 00000000 00000000 00000000  ................
+ 200288 00000000 00000000 00000000 00000000  ................
+ 200298 00000000 00000000                    ........        
diff --git a/ld/testsuite/ld-size/size64-2-x86-64.d b/ld/testsuite/ld-size/size64-2-x86-64.d
new file mode 100644 (file)
index 0000000..4cc11cf
--- /dev/null
@@ -0,0 +1,21 @@
+#source: size64-2.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -R -s -j .data
+#target: x86_64-*-*
+
+.*: +file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET           TYPE              VALUE 
+0+2003d8 R_X86_64_SIZE64   xxx
+0+2003e0 R_X86_64_SIZE64   yyy
+0+2003e8 R_X86_64_SIZE64   zzz
+0+2003f0 R_X86_64_SIZE64   zzz-0x000000000000001e
+0+2003f8 R_X86_64_SIZE64   zzz\+0x000000000000001e
+
+
+Contents of section .data:
+ 2003d8 00000000 00000000 00000000 00000000  ................
+ 2003e8 00000000 00000000 00000000 00000000  ................
+ 2003f8 00000000 00000000                    ........        
diff --git a/ld/testsuite/ld-size/size64-2.s b/ld/testsuite/ld-size/size64-2.s
new file mode 100644 (file)
index 0000000..e443085
--- /dev/null
@@ -0,0 +1,22 @@
+# 64-bit size relocation against TLS symbol in shared object
+       .globl  xxx
+       .section        .tbss,"awT",%nobits
+       .p2align 2
+       .type   xxx, %object
+       .size   xxx, 40
+xxx:
+       .zero   40
+       .globl  yyy
+       .section        .tdata,"awT",%progbits
+       .p2align 2
+       .type   yyy, %object
+       .size   yyy, 40
+yyy:
+       .zero   40
+       .data
+       .p2align 2
+       .quad   xxx@SIZE
+       .quad   yyy@SIZE
+       .quad   zzz@SIZE
+       .quad   zzz@SIZE-30
+       .quad   zzz@SIZE+30