diff --git a/lld/ELF/Adlt/Config.cpp b/lld/ELF/Adlt/Config.cpp index 7f1dc4c06085c08e131f65dda14fd06f726058a6..6960d45d319657aac918fe751c18eda22e9a8720 100644 --- a/lld/ELF/Adlt/Config.cpp +++ b/lld/ELF/Adlt/Config.cpp @@ -15,11 +15,14 @@ using namespace lld::elf; using namespace lld::elf::adlt; Config::Config(bool isSimpleAdlt) - : mergedSegments(isSimpleAdlt ? true : false), + : splitExecSegments(isSimpleAdlt ? true : false), + mergedSegments(isSimpleAdlt ? true : false), symtabIndexes(isSimpleAdlt ? false : true), relocIndexes(isSimpleAdlt ? false : true), phdrIndexes(isSimpleAdlt ? false : true) {} +bool Config::isNeedSplitExecSegments() const { return splitExecSegments; } + bool Config::isNeedMergedSegments() const { return mergedSegments; } bool Config::isNeedSymtabIndexes() const { return symtabIndexes; } diff --git a/lld/ELF/Adlt/Config.h b/lld/ELF/Adlt/Config.h index 51f4db92e7d91c58b2a0b0c8d07af032d610abb4..b2dbcfcdf886fbdf9e298c3e855777709a2a4a8b 100644 --- a/lld/ELF/Adlt/Config.h +++ b/lld/ELF/Adlt/Config.h @@ -21,6 +21,7 @@ class Config { public: Config(bool isSimpleAdlt); + bool isNeedSplitExecSegments() const; bool isNeedMergedSegments() const; bool isNeedSymtabIndexes() const; bool isNeedRelocIndexes() const; @@ -28,6 +29,7 @@ public: bool isNeedSortSymtab() const; private: + bool splitExecSegments; bool mergedSegments; bool symtabIndexes; bool relocIndexes; diff --git a/lld/ELF/Adlt/Writer.cpp b/lld/ELF/Adlt/Writer.cpp index c618bf082dc03868cf69cdcc55f192d71e52aece..12c51b1ca6cb53ff6f3a96720cae52090fd67b47 100644 --- a/lld/ELF/Adlt/Writer.cpp +++ b/lld/ELF/Adlt/Writer.cpp @@ -229,6 +229,7 @@ bool SortHelper::needsPhdr(kOsec *sec, kU64 flags, kPhdr *load, kSize loadPos) { ownerIdx = getOwnerIndx(sec); lastOwnerIdx = getOwnerIndx(load->lastSec); auto isRelro = [](auto *sec) { return checker.isRelroSection(*sec); }; + auto isExec = [](auto *sec) { return checker.isExecSection(*sec); }; // Debugging hints: /*StringRef s = sec->name; @@ -247,8 +248,11 @@ bool SortHelper::needsPhdr(kOsec *sec, kU64 flags, kPhdr *load, kSize loadPos) { return true; } - if (lastOwnerIdx != ownerIdx) + if (lastOwnerIdx != ownerIdx) { needs = !elf::adlt::cfg->isNeedMergedSegments(); + if (elf::adlt::cfg->isNeedSplitExecSegments() && isExec(sec)) + needs = true; + } if (lastFlags != flags) needs = true; if ((sec && load->lastSec) && (isRelro(sec) != isRelro(load->lastSec))) @@ -571,7 +575,8 @@ template void Checker::checkPhdrs() const { " can't be in the EXEC segment!"); if (!(lastSecName.startswith(".init__") || lastSecName.startswith(".fini__"))) { - if (!elf::adlt::cfg->isNeedMergedSegments()) + if (!elf::adlt::cfg->isNeedMergedSegments() || + elf::adlt::cfg->isNeedSplitExecSegments()) fatal("ADLT: checkPhdrs(): " + firstSecName + " should not be in the end of EXEC segment!"); }