Enable elf_backend_rela_normal for AArch64
authorJiong Wang <jiong.wang@arm.com>
Tue, 8 Jul 2014 08:29:06 +0000 (09:29 +0100)
committerJiong Wang <jiong.wang@arm.com>
Tue, 8 Jul 2014 08:29:06 +0000 (09:29 +0100)
  If we are generating non-relocatable object and --emit-relocs specified,
  aarch64 ld is actually generating wrong addend for rela entry when
  relocate against local symbol.

  for example, for simple testcase

  foo.c
  ===

  const char * const a = "foo";

  const char *
  foo ()
  {
    return a;
  }

  bar.c
  ===

  const char * const b = "bar";

  const char * bar ()
  {
    return b;
  }

  aarch64-none-linux-gnu-ld --emit-relocs -o x.o  foo.o bar.o
  aarch64-none-linux-gnu-readelf -r x.o

   ... R_AARCH64_ADR_PRE 0000000000400018 .rodata + 0
   ... R_AARCH64_ADD_ABS 0000000000400018 .rodata + 0
   ... R_AARCH64_ADR_PRE 0000000000400018 .rodata + 0
   ... R_AARCH64_ADD_ABS 0000000000400018 .rodata + 0

   while it should be:

   ... R_AARCH64_ADR_PRE 0000000000400018 .rodata + 0
   ... R_AARCH64_ADD_ABS 0000000000400018 .rodata + 0
   ... R_AARCH64_ADR_PRE 0000000000400018 .rodata + 10
   ... R_AARCH64_ADD_ABS 0000000000400018 .rodata + 10

   bfd generic code could actually handle this properly, but only when
   elf_backend_rela_normal set to '1'.

   this patch enable this and remove those target specific hack.

    bfd/
      * elfnn-aarch64.c (elf_backend_rela_normal): Set to 1.
      (elfNN_aarch64_relocate_section): Remove duplicated addend adjustment
      when info->relocatable be true.

    ld/testsuite/
      * ld-aarch64/emit-relocs-local-addend-bar.s: * New source file.
      * ld-aarch64/emit-relocs-local-addend-foo.s: * Likewise.
      * ld-aarch64/emit-relocs-local-addend.d: * New testcase.
      * ld-aarch64/local-addend-r.d: Likewise.

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/testsuite/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/emit-relocs-local-addend-bar.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-local-addend-foo.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-local-addend.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/local-addend-r.d [new file with mode: 0644]

index f6bc88bd651723e95fe1174121ad238b96340666..deed8cede5c537494aba88368c4ef89dc93924a7 100644 (file)
@@ -1,3 +1,9 @@
+2014-07-08  Jiong Wang  <jiong.wang@arm.com>
+
+       * elfnn-aarch64.c (elf_backend_rela_normal): Set to 1.
+       (elfNN_aarch64_relocate_section): Remove duplicated addend adjustment
+       when info->relocatable be true.
+
 2014-07-07  Barney Stratford  <barney_stratford@fastmail.fm>
 
        * elf32-avr.c: Handle R_AVR_PORT5 and R_AVR_PORT6.
index a8578dae0cd457ad616812207f0f6c43c522cd09..4dfb6043ae67564fb39173d625e80389f85a6833 100644 (file)
@@ -4158,15 +4158,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                                         rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
-       {
-         /* This is a relocatable link.  We don't have to change
-            anything, unless the reloc is against a section symbol,
-            in which case we have to adjust according to where the
-            section symbol winds up in the output section.  */
-         if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-           rel->r_addend += sec->output_offset;
-         continue;
-       }
+       continue;
 
       if (h != NULL)
        name = h->root.root.string;
@@ -7288,6 +7280,7 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_may_use_rel_p      0
 #define elf_backend_may_use_rela_p     1
 #define elf_backend_default_use_rela_p 1
+#define elf_backend_rela_normal        1
 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
 #define elf_backend_default_execstack  0
 
index 50a1b8a99864c178ac9dc63e4d6ca92c87e1f44d..bbef087cfdd8793b0fa549fad42bfd792613999e 100644 (file)
@@ -1,3 +1,10 @@
+2014-07-08  Jiong Wang  <jiong.wang@arm.com>
+
+       * ld-aarch64/emit-relocs-local-addend-bar.s: New source file.
+       * ld-aarch64/emit-relocs-local-addend-foo.s: Likewise.
+       * ld-aarch64/emit-relocs-local-addend.d: New testcase.
+       * ld-aarch64/local-addend-r.d: Likewise.
+
 2014-07-08  Alan Modra  <amodra@gmail.com>
 
        PR 17112
index 845ea202b4eb495bcd7f3727482aed9fe7264d51..36babf3b4ee41cd280413583ab49f2af6ed4e998 100644 (file)
@@ -87,6 +87,10 @@ run_dump_test "emit-relocs-309-low-bad"
 run_dump_test "emit-relocs-311"
 run_dump_test "emit-relocs-312"
 
+# test addend correctness when --emit-relocs specified for non-relocatable obj.
+run_dump_test "emit-relocs-local-addend"
+# test addend correctness when -r specified.
+run_dump_test "local-addend-r"
 
 run_dump_test "limit-b"
 run_dump_test "limit-bl"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-local-addend-bar.s b/ld/testsuite/ld-aarch64/emit-relocs-local-addend-bar.s
new file mode 100644 (file)
index 0000000..ab8b0fb
--- /dev/null
@@ -0,0 +1,19 @@
+       .global b
+       .section        .rodata
+       .align  3
+.LC0:
+       .string "bar"
+       .align  3
+       .type   b, %object
+       .size   b, 8
+b:
+       .xword  .LC0
+       .text
+       .align  2
+       .global bar
+       .type   bar, %function
+bar:
+       adrp    x0, .LC0
+       add     x0, x0, :lo12:.LC0
+       ret
+       .size   bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-local-addend-foo.s b/ld/testsuite/ld-aarch64/emit-relocs-local-addend-foo.s
new file mode 100644 (file)
index 0000000..497eef7
--- /dev/null
@@ -0,0 +1,20 @@
+       .cpu generic+fp+simd
+       .global a
+       .section        .rodata
+       .align  3
+.LC0:
+       .string "foo"
+       .align  3
+       .type   a, %object
+       .size   a, 8
+a:
+       .xword  .LC0
+       .text
+       .align  2
+       .global foo
+       .type   foo, %function
+foo:
+       adrp    x0, .LC0
+       add     x0, x0, :lo12:.LC0
+       ret
+       .size   foo, .-foo
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-local-addend.d b/ld/testsuite/ld-aarch64/emit-relocs-local-addend.d
new file mode 100644 (file)
index 0000000..1739e64
--- /dev/null
@@ -0,0 +1,16 @@
+#source: emit-relocs-local-addend-foo.s
+#source: emit-relocs-local-addend-bar.s
+#ld: -e0 --emit-relocs
+#readelf: -r
+
+Relocation section '\.rela\.text' at offset 0x102f8 contains 4 entries:
+  Offset          Info           Type           Sym\. Value    Sym\. Name \+ Addend
+000000400000  000200000113 R_AARCH64_ADR_PRE 0000000000400018 \.rodata \+ 0
+000000400004  000200000115 R_AARCH64_ADD_ABS 0000000000400018 \.rodata \+ 0
+00000040000c  000200000113 R_AARCH64_ADR_PRE 0000000000400018 \.rodata \+ 10
+000000400010  000200000115 R_AARCH64_ADD_ABS 0000000000400018 \.rodata \+ 10
+
+Relocation section '\.rela\.rodata' at offset 0x10358 contains 2 entries:
+  Offset          Info           Type           Sym\. Value    Sym. Name \+ Addend
+000000400020  000200000101 R_AARCH64_ABS64   0000000000400018 \.rodata \+ 0
+000000400030  000200000101 R_AARCH64_ABS64   0000000000400018 \.rodata \+ 10
diff --git a/ld/testsuite/ld-aarch64/local-addend-r.d b/ld/testsuite/ld-aarch64/local-addend-r.d
new file mode 100644 (file)
index 0000000..c8c2777
--- /dev/null
@@ -0,0 +1,16 @@
+#source: emit-relocs-local-addend-foo.s
+#source: emit-relocs-local-addend-bar.s
+#ld: -e0 -r
+#readelf: -r
+
+Relocation section '\.rela\.text' at offset 0x338 contains 4 entries:
+  Offset          Info           Type           Sym\. Value    Sym\. Name \+ Addend
+000000000000  000200000113 R_AARCH64_ADR_PRE 0000000000000000 \.rodata \+ 0
+000000000004  000200000115 R_AARCH64_ADD_ABS 0000000000000000 \.rodata \+ 0
+00000000000c  000200000113 R_AARCH64_ADR_PRE 0000000000000000 \.rodata \+ 10
+000000000010  000200000115 R_AARCH64_ADD_ABS 0000000000000000 \.rodata \+ 10
+
+Relocation section '\.rela\.rodata' at offset 0x398 contains 2 entries:
+  Offset          Info           Type           Sym\. Value    Sym. Name \+ Addend
+000000000008  000200000101 R_AARCH64_ABS64   0000000000000000 \.rodata \+ 0
+000000000018  000200000101 R_AARCH64_ABS64   0000000000000000 \.rodata \+ 10