6161#include " eld/SymbolResolver/ResolveInfo.h"
6262#include " eld/Target/ELFFileFormat.h"
6363#include " eld/Target/GNULDBackend.h"
64+ #include " eld/Target/LDFileFormat.h"
6465#include " eld/Target/Relocator.h"
6566#include " llvm/ADT/ScopeExit.h"
6667#include " llvm/ADT/StringSwitch.h"
8182#include < chrono>
8283#include < mutex>
8384#include < sstream>
85+ #include < unordered_set>
8486
8587using namespace llvm ;
8688using namespace eld ;
@@ -970,7 +972,7 @@ bool ObjectLinker::sortSections(RuleContainer *I, bool SortRule) {
970972bool ObjectLinker::createOutputSection (ObjectBuilder &Builder,
971973 OutputSectionEntry *Output,
972974 bool PostLayout) {
973- uint64_t OutAlign = 0x0 , InAlign = 0x0 ;
975+ uint64_t OutAlign = 0x0 ;
974976 bool IsPartialLink = (LinkerConfig::Object == ThisConfig.codeGenType ());
975977
976978 ELFSection *OutSect = Output->getSection ();
@@ -980,15 +982,6 @@ bool ObjectLinker::createOutputSection(ObjectBuilder &Builder,
980982 OutputSectionEntry::iterator In, InBegin, InEnd;
981983 InBegin = Output->begin ();
982984 InEnd = Output->end ();
983- bool HasSubAlign = false ;
984-
985- // force input alignment from ldscript if any
986- if (Output->prolog ().hasSubAlign ()) {
987- Output->prolog ().subAlign ().eval ();
988- Output->prolog ().subAlign ().commit ();
989- InAlign = Output->prolog ().subAlign ().result ();
990- HasSubAlign = true ;
991- }
992985
993986 // force output alignment from ldscript if any
994987 if (Output->prolog ().hasAlign ()) {
@@ -1030,12 +1023,6 @@ bool ObjectLinker::createOutputSection(ObjectBuilder &Builder,
10301023 }
10311024 InSect->setAddrAlign (Alignment);
10321025 }
1033- if (HasSubAlign && (InSect->getAddrAlign () < InAlign)) {
1034- if (InSect->getFragmentList ().size ()) {
1035- InSect->getFragmentList ().front ()->setAlignment (InAlign);
1036- InSect->setAddrAlign (InAlign);
1037- }
1038- }
10391026 if (InSect->getFragmentList ().size () && !FirstNonEmptyRule)
10401027 FirstNonEmptyRule = *In;
10411028
@@ -1286,6 +1273,9 @@ bool ObjectLinker::mergeSections() {
12861273 {
12871274 eld::RegisterTimer T (" Create Output Section" , " Merge Sections" ,
12881275 ThisConfig.options ().printTimingStats ());
1276+ // Prepass: apply SUBALIGN to first fragments per input section per output
1277+ // section serially to avoid races in parallel output creation.
1278+ applySubAlign ();
12891279 std::vector<OutputSectionEntry *> OutSections;
12901280 for (Out = OutBegin; Out != OutEnd; ++Out) {
12911281 OutSections.push_back (*Out);
@@ -1329,6 +1319,41 @@ bool ObjectLinker::initializeOutputSectionsAndRunPlugin() {
13291319 return runOutputSectionIteratorPlugin ();
13301320}
13311321
1322+ void ObjectLinker::applySubAlign () {
1323+ std::unordered_set<ELFSection *> seen;
1324+
1325+ for (auto *O : ThisModule->getScript ().sectionMap ()) {
1326+ auto &prolog = O->prolog ();
1327+ if (!prolog.hasSubAlign ())
1328+ continue ;
1329+ uint64_t subAlign;
1330+ prolog.subAlign ().eval ();
1331+ prolog.subAlign ().commit ();
1332+ subAlign = prolog.subAlign ().result ();
1333+
1334+ for (RuleContainer *R : *O) {
1335+ ELFSection *inSect = R->getSection ();
1336+ for (Fragment *F : inSect->getFragmentList ()) {
1337+ ELFSection *owningSect = F->getOwningSection ();
1338+ if (owningSect->getKind () == LDFileFormat::Kind::OutputSectData) {
1339+ continue ;
1340+ }
1341+ if (owningSect && seen.insert (owningSect).second ) {
1342+ // Warn if SUBALIGN is reducing the section alignment
1343+ if (ThisConfig.showLinkerScriptWarnings () && F->alignment () > subAlign) {
1344+ ThisConfig.raise (Diag::warn_subalign_less_than_section_alignment)
1345+ << utility::toHex (subAlign) << utility::toHex (F->alignment ())
1346+ << owningSect->getLocation (0 , ThisConfig.options ());
1347+ }
1348+ F->setAlignment (subAlign);
1349+ inSect->setAddrAlign (std::max (
1350+ static_cast <uint64_t >(inSect->getAddrAlign ()), subAlign));
1351+ }
1352+ }
1353+ }
1354+ }
1355+ }
1356+
13321357void ObjectLinker::assignOffset (OutputSectionEntry *Out) {
13331358 int64_t O = 0 ;
13341359 const ELFSection *OutSection = Out->getSection ();
0 commit comments