[PATCH] D91127: [ELF] Use input order instead of pattern order within an input section description

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 10 02:31:10 PST 2020


grimar added a comment.

> This patch also fixes 2 bugs:
> The second SORT in *(SORT(...) SORT(...)) is incorrectly parsed as a file pattern
> A section may be added multiple times if it multiple patterns match it

Can these bug fixes be separated to their own reviews (at least the first one seems can be independent)?



================
Comment at: lld/ELF/LinkerScript.cpp:435
+               [&](InputSectionBase *l, InputSectionBase *r) {
+                 return pos.find(l)->second < pos.find(r)->second;
+               });
----------------
I am not sure that doing 2 lookups in the DenseMap on each predicate call is a good idea.


================
Comment at: lld/ELF/LinkerScript.cpp:445
     for (InputSectionBase *sec : sections) {
-      if (!sec->isLive() || sec->parent)
+      if (!sec->isLive() || sec->parent || pos.find(sec)->second % 2)
         continue;
----------------
So, with it it is also possible to do lookup in pos twice:
one here and one with `pos[sec] |= 1;`

It looks a bit dirty. I think usually double lookup situation is avoided.


================
Comment at: lld/ELF/LinkerScript.cpp:468
+      // Prevent duplicate elements in ret.
+      pos[sec] |= 1;
     }
----------------
Looks a bit hacky approach to me.


================
Comment at: lld/ELF/LinkerScript.cpp:473
+      continue;
+    sortByPosition(sizeLastSort);
     sortInputSections(
----------------
You don't need to call `sortByPosition` here? It is always sorted I believe.


================
Comment at: lld/ELF/LinkerScript.cpp:484
   return ret;
 }
 
----------------
I've experimented with the implementation and got the following
version that addresses all my concerns/comments. What do you think?


```
// Compute and remember which sections the InputSectionDescription matches.
std::vector<InputSectionBase *>
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
                                   ArrayRef<InputSectionBase *> sections) {
  std::vector<InputSectionBase *> ret;
  SetVector<size_t> indices; // Parallel to ret.

  // Collects all sections that satisfy constraints of Cmd.
  size_t sizeLastSort = 0;
  for (const SectionPattern &pat : cmd->sectionPatterns) {
    size_t sizeBefore = ret.size();

    for (size_t I = 0, E = sections.size(); I != E; ++I) {
      InputSectionBase *sec = sections[I];
      if (!sec->isLive() || sec->parent || indices.contains(I))
        continue;

      // For -emit-relocs we have to ignore entries like
      //   .rela.dyn : { *(.rela.data) }
      // which are common because they are in the default bfd script.
      // We do not ignore SHT_REL[A] linker-synthesized sections here because
      // want to support scripts that do custom layout for them.
      if (isa<InputSection>(sec) &&
          cast<InputSection>(sec)->getRelocatedSection())
        continue;

      // Check the name early to improve performance in the common case.
      if (!pat.sectionPat.match(sec->name))
        continue;

      if (!cmd->matchesFile(sec->file) || pat.excludesFile(sec->file) ||
          (sec->flags & cmd->withFlags) != cmd->withFlags ||
          (sec->flags & cmd->withoutFlags) != 0)
        continue;

      indices.insert(I);
      ret.push_back(sec);
    }

    if (pat.sortOuter == SortSectionPolicy::Default)
      continue;

    sortInputSections(
        MutableArrayRef<InputSectionBase *>(ret).slice(sizeBefore),
        pat.sortOuter, pat.sortInner);
    sizeLastSort = ret.size();
  }

  std::vector<size_t> indicesV = indices.takeVector();
  llvm::sort(MutableArrayRef<size_t>(indicesV).slice(sizeLastSort),
             [&](size_t l, size_t r) { return l < r; });

  for (size_t I = sizeLastSort, E = ret.size(); I != E; ++I)
    ret[I] = sections[indicesV[I]];

  sortInputSections(
      MutableArrayRef<InputSectionBase *>(ret).slice(sizeLastSort),
      config->sortSection, SortSectionPolicy::None);
  return ret;
}
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91127/new/

https://reviews.llvm.org/D91127



More information about the llvm-commits mailing list