[PATCH] D34326: [ELF] - Allow mixing .init_array.* and .ctors.* sections in linkerscript.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 18 03:26:18 PDT 2017


grimar created this revision.
Herald added a subscriber: emaste.

We have a difference in behavior with bfd linkers when
init_array and ctors are mixed together.

bfd script has for example:

  .init_array     :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }

SORT_BY_INIT_PRIORITY is a https://reviews.llvm.org/D24611. Currently LLD implemented behavior is similar for
both types of section. But looks it is expected (and consistency) to make implementation slighly
different, by adding section name check. That is mostly for overall correctness,
because .ctors/.dtors is very outdated feature. Though somebody may still use such kind of bfd
script for example and will have a bug. Probably no need to do something more complicated here.


https://reviews.llvm.org/D34326

Files:
  ELF/LinkerScript.cpp
  test/ELF/linkerscript/sort-init2.s


Index: test/ELF/linkerscript/sort-init2.s
===================================================================
--- test/ELF/linkerscript/sort-init2.s
+++ test/ELF/linkerscript/sort-init2.s
@@ -0,0 +1,31 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: echo "SECTIONS { .init_array : { \
+# RUN: *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) } \
+# RUN:       .fini_array : { \
+# RUN: *(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) } }" > %t1.script
+# RUN: ld.lld --script %t1.script %t1.o -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck %s
+
+# CHECK:      Contents of section .init_array:
+# CHECK-NEXT:  01020403
+# CHECK:      Contents of section .fini_array:
+# CHECK-NEXT:  11121413
+
+.section .init_array.5, "aw", @init_array
+  .byte 0x1
+.section .init_array.10, "aw", @init_array
+  .byte 0x2
+.section .ctors.005, "aw", @progbits
+  .byte 0x3
+.section .ctors.100, "aw", @progbits
+  .byte 0x4
+
+.section .fini_array.5, "aw", @fini_array
+  .byte 0x11
+.section .fini_array.10, "aw", @fini_array
+  .byte 0x12
+.section .dtors.005, "aw", @progbits
+  .byte 0x13
+.section .dtors.100, "aw", @progbits
+  .byte 0x14
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -250,6 +250,15 @@
     };
   case SortSectionPolicy::Priority:
     return [](InputSectionBase *A, InputSectionBase *B) {
+      // Scripts may place both .init_array.* and .ctors.* to the same section.
+      // That what default ld.bfd script do, it contains next line:
+      // KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)
+      // SORT_BY_INIT_PRIORITY(.ctors.*))). But .init_array.*
+      // sections should go in a reversed order in compare with .ctors.*. And so
+      // behavior of SORT_BY_INIT_PRIORITY is different depending on section
+      // names.
+      if (A->Name.startswith(".ctors.") || A->Name.startswith(".dtors"))
+        return getPriority(A->Name) > getPriority(B->Name);
       return getPriority(A->Name) < getPriority(B->Name);
     };
   default:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34326.102965.patch
Type: text/x-patch
Size: 2157 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170618/ea71359b/attachment.bin>


More information about the llvm-commits mailing list