[PATCH] D74791: Add a --shuffle-sections option to lld

Rafael Avila de Espindola via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 18 13:40:29 PST 2020


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

This option causes lld to shuffle sections by assigning different
priorities in each run.

The use case for this is to introduce randomization in benchmarks. The
idea is inspired by the paper "Producing Wrong Data Without Doing
Anything Obviously Wrong!"
(https://www.inf.usi.ch/faculty/hauswirth/publications/asplos09.pdf). Unlike
the paper, we shuffle individual sections, not just input files.

Doing this in lld is particularly convenient as the --reproduce option
makes it easy to collect all the necessary bits for relinking the
program being benchmarked. Once that it is done, all that is needed is
to add --shuffle-sections to the response file and relink before each
run of the benchmark.


https://reviews.llvm.org/D74791

Files:
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/Options.td
  lld/ELF/Writer.cpp


Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -1212,6 +1212,22 @@
   if (!config->callGraphProfile.empty())
     return computeCallGraphProfileOrder();
 
+  if (config->shuffleSections) {
+      std::vector<int> priorities(inputSections.size());
+      int cur_prio = -1;
+      for (int &prio : priorities) {
+          prio = cur_prio;
+          --cur_prio;
+      }
+      std::random_device rd;
+      std::mt19937 g(rd());
+      std::shuffle(priorities.begin(), priorities.end(), g);
+      for (int i = 0, n = priorities.size(); i < n; ++i) {
+          sectionOrder[inputSections[i]] = priorities[i];
+      }
+      return sectionOrder;
+  }
+
   if (config->symbolOrderingFile.empty())
     return sectionOrder;
 
Index: lld/ELF/Options.td
===================================================================
--- lld/ELF/Options.td
+++ lld/ELF/Options.td
@@ -499,6 +499,7 @@
   HelpText<"The format used for serializing remarks (default: YAML)">;
 defm plugin_opt: Eq<"plugin-opt", "specifies LTO options for compatibility with GNU linkers">;
 def save_temps: F<"save-temps">;
+def shuffle_sections: F<"shuffle-sections">;
 def thinlto_cache_dir: J<"thinlto-cache-dir=">,
   HelpText<"Path to ThinLTO cached object file directory">;
 defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">;
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -956,6 +956,7 @@
   config->rpath = getRpath(args);
   config->relocatable = args.hasArg(OPT_relocatable);
   config->saveTemps = args.hasArg(OPT_save_temps);
+  config->shuffleSections = args.hasArg(OPT_shuffle_sections);
   config->searchPaths = args::getStrings(args, OPT_library_path);
   config->sectionStartMap = getSectionStartMap(args);
   config->shared = args.hasArg(OPT_shared);
Index: lld/ELF/Config.h
===================================================================
--- lld/ELF/Config.h
+++ lld/ELF/Config.h
@@ -182,6 +182,7 @@
   bool relocatable;
   bool relrPackDynRelocs;
   bool saveTemps;
+  bool shuffleSections;
   bool singleRoRx;
   bool shared;
   bool isStatic = false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D74791.245250.patch
Type: text/x-patch
Size: 2277 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200218/0b4eeb7c/attachment.bin>


More information about the llvm-commits mailing list