[PATCH] D74971: Add a llvm::shuffle and use it in lld

Rafael Avila de Espindola via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 21 09:09:38 PST 2020


respindola created this revision.
respindola added reviewers: grimar, MaskRay.
Herald added subscribers: dexonsmith, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

With this --shuffle-sections=seed produces the same result in every
host.


https://reviews.llvm.org/D74971

Files:
  lld/ELF/Writer.cpp
  lld/test/ELF/shuffle-sections.s
  llvm/include/llvm/ADT/STLExtras.h


Index: llvm/include/llvm/ADT/STLExtras.h
===================================================================
--- llvm/include/llvm/ADT/STLExtras.h
+++ llvm/include/llvm/ADT/STLExtras.h
@@ -1007,6 +1007,20 @@
 //     Extra additions for arrays
 //===----------------------------------------------------------------------===//
 
+// Based on the one in libc++. We have a copy in here so that llvm behaves the
+// same when using different standard libraries.
+template <class Iterator, class RNG>
+void shuffle(Iterator first, Iterator last, RNG &&g) {
+  --last;
+  for (; first < last; ++first) {
+    // It would be better to use a std::uniform_int_distribution,
+    // but that would be stdlib dependent.
+    auto d = last - first + 1;
+    auto i = g() % d;
+    std::swap(*first, *(first + i));
+  }
+}
+
 /// Find the length of an array.
 template <class T, std::size_t N>
 constexpr inline size_t array_lengthof(T (&)[N]) {
Index: lld/test/ELF/shuffle-sections.s
===================================================================
--- lld/test/ELF/shuffle-sections.s
+++ lld/test/ELF/shuffle-sections.s
@@ -6,6 +6,12 @@
 # CHECK: Hex dump of section '.text':
 # CHECK-NEXT: 01020304
 
+## --shuffle-sections= shuffles input sections.
+# RUN: ld.lld --shuffle-sections=1 %t.o -o %t1.out
+# RUN: llvm-readelf -x .text %t1.out | FileCheck %s --check-prefix=SHUFFLE1
+# SHUFFLE1: Hex dump of section '.text':
+# SHUFFLE1-NEXT: 0204cccc 0103
+
 ## Test that --shuffle-sections= can be used with --symbol-ordering-file
 # RUN: echo "foo" > %t_order.txt
 # RUN: echo "_start " >> %t_order.txt
@@ -13,12 +19,12 @@
 # RUN: ld.lld --symbol-ordering-file %t_order.txt --shuffle-sections=2 %t.o -o %t2.out
 # RUN: llvm-readelf -x .text %t2.out | FileCheck %s --check-prefix=SHUFFLE2
 # SHUFFLE2: Hex dump of section '.text':
-# SHUFFLE2-NEXT: 02cccccc 01{{....}}
+# SHUFFLE2-NEXT: 02cccccc 010304
 
 # RUN: ld.lld --symbol-ordering-file %t_order.txt --shuffle-sections=3 %t.o -o %t3.out
 # RUN: llvm-readelf -x .text %t3.out | FileCheck %s --check-prefix=SHUFFLE3
 # SHUFFLE3: Hex dump of section '.text':
-# SHUFFLE3-NEXT: 02cccccc 01{{....}}
+# SHUFFLE3-NEXT: 02cccccc 010403
 
 ## .text has an alignment of 4.
 .global _start
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -1218,7 +1218,7 @@
     prio = curPrio++;
   uint32_t seed = *config->shuffleSectionSeed;
   std::mt19937 g(seed ? seed : std::random_device()());
-  std::shuffle(priorities.begin(), priorities.end(), g);
+  llvm::shuffle(priorities.begin(), priorities.end(), g);
   int prioIndex = 0;
   for (InputSectionBase *sec : inputSections) {
     if (order.try_emplace(sec, priorities[prioIndex]).second)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D74971.245886.patch
Type: text/x-patch
Size: 2766 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200221/6dc5c516/attachment.bin>


More information about the llvm-commits mailing list