[lld] r316984 - [ELF] - Simplify output section creation.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 7 10:33:54 PST 2017


Very nice find!

Thanks,
Rafael

George Rimar via llvm-commits <llvm-commits at lists.llvm.org> writes:

> Author: grimar
> Date: Tue Oct 31 03:31:58 2017
> New Revision: 316984
>
> URL: http://llvm.org/viewvc/llvm-project?rev=316984&view=rev
> Log:
> [ELF] - Simplify output section creation.
>
> When there is no SECTION commands given, all sections are
> technically orphans, but now we handle script orphans sections
> and regular "orphans" sections for non-scripted case differently,
> though we can handle them at one place.
>
> Patch do that change.
>
> Differential revision: https://reviews.llvm.org/D39045
>
> Modified:
>     lld/trunk/ELF/LinkerScript.cpp
>     lld/trunk/ELF/LinkerScript.h
>     lld/trunk/ELF/Writer.cpp
>
> Modified: lld/trunk/ELF/LinkerScript.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=316984&r1=316983&r2=316984&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.cpp (original)
> +++ lld/trunk/ELF/LinkerScript.cpp Tue Oct 31 03:31:58 2017
> @@ -426,25 +426,6 @@ void LinkerScript::processSectionCommand
>    }
>  }
>  
> -// If no SECTIONS command was given, we create simple SectionCommands
> -// as if a minimum SECTIONS command were given. This function does that.
> -void LinkerScript::fabricateDefaultCommands() {
> -  // Define start address
> -  uint64_t StartAddr = UINT64_MAX;
> -
> -  // The Sections with -T<section> have been sorted in order of ascending
> -  // address. We must lower StartAddr if the lowest -T<section address> as
> -  // calls to setDot() must be monotonically increasing.
> -  for (auto &KV : Config->SectionStartMap)
> -    StartAddr = std::min(StartAddr, KV.second);
> -
> -  auto Expr = [=] {
> -    return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
> -  };
> -  SectionCommands.insert(SectionCommands.begin(),
> -                         make<SymbolAssignment>(".", Expr, ""));
> -}
> -
>  static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
>                                   StringRef Name) {
>    for (BaseCommand *Base : Vec)
> @@ -465,6 +446,7 @@ static void reportOrphan(InputSectionBas
>  void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
>    unsigned End = SectionCommands.size();
>  
> +  std::vector<OutputSection *> V;
>    for (InputSectionBase *S : InputSections) {
>      if (!S->Live || S->Parent)
>        continue;
> @@ -479,9 +461,18 @@ void LinkerScript::addOrphanSections(Out
>      }
>  
>      if (OutputSection *OS = Factory.addInputSec(S, Name))
> -      SectionCommands.push_back(OS);
> +      V.push_back(OS);
>      assert(S->getOutputSection()->SectionIndex == INT_MAX);
>    }
> +
> +  // If no SECTIONS command was given, we should insert sections commands
> +  // before others, so that we can handle scripts which refers them,
> +  // for example: "foo = ABSOLUTE(ADDR(.text)));".
> +  // When SECTIONS command is present we just add all orphans to the end.
> +  if (HasSectionsCommand)
> +    SectionCommands.insert(SectionCommands.end(), V.begin(), V.end());
> +  else
> +    SectionCommands.insert(SectionCommands.begin(), V.begin(), V.end());
>  }
>  
>  uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) {
> @@ -802,11 +793,26 @@ LinkerScript::AddressState::AddressState
>    }
>  }
>  
> -// Assign addresses as instructed by linker script SECTIONS sub-commands.
> +static uint64_t getInitialDot() {
> +  // By default linker scripts use an initial value of 0 for '.',
> +  // but prefer -image-base if set.
> +  if (Script->HasSectionsCommand)
> +    return Config->ImageBase ? *Config->ImageBase : 0;
> +
> +  uint64_t StartAddr = UINT64_MAX;
> +  // The Sections with -T<section> have been sorted in order of ascending
> +  // address. We must lower StartAddr if the lowest -T<section address> as
> +  // calls to setDot() must be monotonically increasing.
> +  for (auto &KV : Config->SectionStartMap)
> +    StartAddr = std::min(StartAddr, KV.second);
> +  return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
> +}
> +
> +// Here we assign addresses as instructed by linker script SECTIONS
> +// sub-commands. Doing that allows us to use final VA values, so here
> +// we also handle rest commands like symbol assignments and ASSERTs.
>  void LinkerScript::assignAddresses() {
> -  // By default linker scripts use an initial value of 0 for '.', but prefer
> -  // -image-base if set.
> -  Dot = Config->ImageBase ? *Config->ImageBase : 0;
> +  Dot = getInitialDot();
>  
>    auto Deleter = make_unique<AddressState>();
>    Ctx = Deleter.get();
>
> Modified: lld/trunk/ELF/LinkerScript.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=316984&r1=316983&r2=316984&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.h (original)
> +++ lld/trunk/ELF/LinkerScript.h Tue Oct 31 03:31:58 2017
> @@ -250,7 +250,6 @@ public:
>  
>    ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
>  
> -  void fabricateDefaultCommands();
>    void addOrphanSections(OutputSectionFactory &Factory);
>    void removeEmptyCommands();
>    void adjustSectionsBeforeSorting();
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=316984&r1=316983&r2=316984&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Tue Oct 31 03:31:58 2017
> @@ -49,7 +49,6 @@ private:
>    void copyLocalSymbols();
>    void addSectionSymbols();
>    void addReservedSymbols();
> -  void createSections();
>    void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
>    void sortSections();
>    void sortInputSections();
> @@ -169,22 +168,14 @@ template <class ELFT> void Writer<ELFT>:
>    if (!Config->Relocatable)
>      addReservedSymbols();
>  
> -  // Create output sections.
> -  if (Script->HasSectionsCommand) {
> -    // If linker script contains SECTIONS commands, let it create sections.
> -    Script->processSectionCommands();
> -
> -    // Linker scripts may have left some input sections unassigned.
> -    // Assign such sections using the default rule.
> -    Script->addOrphanSections(Factory);
> -  } else {
> -    // If linker script does not contain SECTIONS commands, create
> -    // output sections by default rules. We still need to give the
> -    // linker script a chance to run, because it might contain
> -    // non-SECTIONS commands such as ASSERT.
> -    Script->processSectionCommands();
> -    createSections();
> -  }
> +  // We want to process linker script commands. When SECTIONS command
> +  // is given we let it create sections.
> +  Script->processSectionCommands();
> +
> +  // Linker scripts controls how input sections are assigned to output sections.
> +  // Input sections that were not handled by scripts are called "orphans", and
> +  // they are assigned to output sections by the default rule. Process that.
> +  Script->addOrphanSections(Factory);
>  
>    if (Config->Discard != DiscardPolicy::All)
>      copyLocalSymbols();
> @@ -852,20 +843,6 @@ void Writer<ELFT>::forEachRelSec(std::fu
>      Fn(*ES);
>  }
>  
> -template <class ELFT> void Writer<ELFT>::createSections() {
> -  std::vector<OutputSection *> Vec;
> -  for (InputSectionBase *IS : InputSections)
> -    if (IS && IS->Live)
> -      if (OutputSection *Sec =
> -              Factory.addInputSec(IS, getOutputSectionName(IS->Name)))
> -        Vec.push_back(Sec);
> -
> -  Script->SectionCommands.insert(Script->SectionCommands.begin(), Vec.begin(),
> -                                 Vec.end());
> -
> -  Script->fabricateDefaultCommands();
> -}
> -
>  // This function generates assignments for predefined symbols (e.g. _end or
>  // _etext) and inserts them into the commands sequence to be processed at the
>  // appropriate time. This ensures that the value is going to be correct by the
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list