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; 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/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/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 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;