@@ -1444,6 +1444,37 @@ static void finalizeSynthetic(Ctx &ctx, SyntheticSection *sec) {
14441444 }
14451445}
14461446
1447+ static bool canInsertPadding (OutputSection *sec) {
1448+ StringRef s = sec->name ;
1449+ return s == " .bss" || s == " .data" || s == " .data.rel.ro" ||
1450+ s == " .rodata" || s.starts_with (" .text" );
1451+ }
1452+
1453+ static void shufflePadding (Ctx &ctx) {
1454+ std::mt19937 g (*ctx.arg .shufflePadding );
1455+ PhdrEntry *curPtLoad = nullptr ;
1456+ for (OutputSection *os : ctx.outputSections ) {
1457+ if (!canInsertPadding (os))
1458+ continue ;
1459+ for (SectionCommand *bc : os->commands ) {
1460+ if (auto *isd = dyn_cast<InputSectionDescription>(bc)) {
1461+ SmallVector<InputSection *, 0 > tmp;
1462+ if (os->ptLoad != curPtLoad) {
1463+ tmp.push_back (
1464+ make<ShufflePaddingSection>(ctx, g () % ctx.arg .maxPageSize , os));
1465+ curPtLoad = os->ptLoad ;
1466+ }
1467+ for (InputSection *isec : isd->sections ) {
1468+ if (g () < (1 <<28 ))
1469+ tmp.push_back (make<ShufflePaddingSection>(ctx, isec->addralign , os));
1470+ tmp.push_back (isec);
1471+ }
1472+ isd->sections = std::move (tmp);
1473+ }
1474+ }
1475+ }
1476+ }
1477+
14471478// We need to generate and finalize the content that depends on the address of
14481479// InputSections. As the generation of the content may also alter InputSection
14491480// addresses we must converge to a fixed point. We do that here. See the comment
@@ -1470,6 +1501,9 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
14701501 if (ctx.arg .emachine == EM_HEXAGON)
14711502 hexagonTLSSymbolUpdate (ctx);
14721503
1504+ if (ctx.arg .shufflePadding )
1505+ shufflePadding (ctx);
1506+
14731507 uint32_t pass = 0 , assignPasses = 0 ;
14741508 for (;;) {
14751509 bool changed = ctx.target ->needsThunks
0 commit comments