//===- LinkerScript.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the parser/evaluator of the linker script.
//
//===----------------------------------------------------------------------===//

#include "LinkerScript.h"
#include "Config.h"
#include "InputSection.h"
#include "OutputSections.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "lld/Common/Threads.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <limits>
#include <string>
#include <vector>

using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;

LinkerScript *elf::Script;

static uint64_t getOutputSectionVA(SectionBase *InputSec, StringRef Loc) {
  if (OutputSection *OS = InputSec->getOutputSection())
    return OS->Addr;
  error(Loc + ": unable to evaluate expression: input section " +
        InputSec->Name + " has no output section assigned");
  return 0;
}

uint64_t ExprValue::getValue() const {
  if (Sec)
    return alignTo(Sec->getOffset(Val) + getOutputSectionVA(Sec, Loc),
                   Alignment);
  return alignTo(Val, Alignment);
}

uint64_t ExprValue::getSecAddr() const {
  if (Sec)
    return Sec->getOffset(0) + getOutputSectionVA(Sec, Loc);
  return 0;
}

uint64_t ExprValue::getSectionOffset() const {
  // If the alignment is trivial, we don't have to compute the full
  // value to know the offset. This allows this function to succeed in
  // cases where the output section is not yet known.
  if (Alignment == 1 && (!Sec || !Sec->getOutputSection()))
    return Val;
  return getValue() - getSecAddr();
}

OutputSection *LinkerScript::createOutputSection(StringRef Name,
                                                 StringRef Location) {
  OutputSection *&SecRef = NameToOutputSection[Name];
  OutputSection *Sec;
  if (SecRef && SecRef->Location.empty()) {
    // There was a forward reference.
    Sec = SecRef;
  } else {
    Sec = make<OutputSection>(Name, SHT_PROGBITS, 0);
    if (!SecRef)
      SecRef = Sec;
  }
  Sec->Location = Location;
  return Sec;
}

OutputSection *LinkerScript::getOrCreateOutputSection(StringRef Name) {
  OutputSection *&CmdRef = NameToOutputSection[Name];
  if (!CmdRef)
    CmdRef = make<OutputSection>(Name, SHT_PROGBITS, 0);
  return CmdRef;
}

// Expands the memory region by the specified size.
static void expandMemoryRegion(MemoryRegion *MemRegion, uint64_t Size,
                               StringRef RegionName, StringRef SecName) {
  MemRegion->CurPos += Size;
  uint64_t NewSize = MemRegion->CurPos - MemRegion->Origin;
  if (NewSize > MemRegion->Length)
    error("section '" + SecName + "' will not fit in region '" + RegionName +
          "': overflowed by " + Twine(NewSize - MemRegion->Length) + " bytes");
}

void LinkerScript::expandMemoryRegions(uint64_t Size) {
  if (Ctx->MemRegion)
    expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name,
                       Ctx->OutSec->Name);
  // Only expand the LMARegion if it is different from MemRegion.
  if (Ctx->LMARegion && Ctx->MemRegion != Ctx->LMARegion)
    expandMemoryRegion(Ctx->LMARegion, Size, Ctx->LMARegion->Name,
                       Ctx->OutSec->Name);
}

void LinkerScript::expandOutputSection(uint64_t Size) {
  Ctx->OutSec->Size += Size;
  expandMemoryRegions(Size);
}

void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
  uint64_t Val = E().getValue();
  if (Val < Dot && InSec)
    error(Loc + ": unable to move location counter backward for: " +
          Ctx->OutSec->Name);

  // Update to location counter means update to section size.
  if (InSec)
    expandOutputSection(Val - Dot);

  Dot = Val;
}

// Used for handling linker symbol assignments, for both finalizing
// their values and doing early declarations. Returns true if symbol
// should be defined from linker script.
static bool shouldDefineSym(SymbolAssignment *Cmd) {
  if (Cmd->Name == ".")
    return false;

  if (!Cmd->Provide)
    return true;

  // If a symbol was in PROVIDE(), we need to define it only
  // when it is a referenced undefined symbol.
  Symbol *B = Symtab->find(Cmd->Name);
  if (B && !B->isDefined())
    return true;
  return false;
}

// This function is called from processSectionCommands,
// while we are fixing the output section layout.
void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
  if (!shouldDefineSym(Cmd))
    return;

  // Define a symbol.
  ExprValue Value = Cmd->Expression();
  SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;

  // When this function is called, section addresses have not been
  // fixed yet. So, we may or may not know the value of the RHS
  // expression.
  //
  // For example, if an expression is `x = 42`, we know x is always 42.
  // However, if an expression is `x = .`, there's no way to know its
  // value at the moment.
  //
  // We want to set symbol values early if we can. This allows us to
  // use symbols as variables in linker scripts. Doing so allows us to
  // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
  uint64_t SymValue = Value.Sec ? 0 : Value.getValue();

  Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue,
              0, Sec);

  Symbol *Sym = Symtab->insert(Cmd->Name);
  Sym->mergeProperties(New);
  Sym->replace(New);
  Cmd->Sym = cast<Defined>(Sym);
}

// This function is called from LinkerScript::declareSymbols.
// It creates a placeholder symbol if needed.
static void declareSymbol(SymbolAssignment *Cmd) {
  if (!shouldDefineSym(Cmd))
    return;

  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
  Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, 0, 0,
              nullptr);

  // We can't calculate final value right now.
  Symbol *Sym = Symtab->insert(Cmd->Name);
  Sym->mergeProperties(New);
  Sym->replace(New);

  Cmd->Sym = cast<Defined>(Sym);
  Cmd->Provide = false;
  Sym->ScriptDefined = true;
}

// This method is used to handle INSERT AFTER statement. Here we rebuild
// the list of script commands to mix sections inserted into.
void LinkerScript::processInsertCommands() {
  std::vector<BaseCommand *> V;
  auto Insert = [&](std::vector<BaseCommand *> &From) {
    V.insert(V.end(), From.begin(), From.end());
    From.clear();
  };

  for (BaseCommand *Base : SectionCommands) {
    if (auto *OS = dyn_cast<OutputSection>(Base)) {
      Insert(InsertBeforeCommands[OS->Name]);
      V.push_back(Base);
      Insert(InsertAfterCommands[OS->Name]);
      continue;
    }
    V.push_back(Base);
  }

  for (auto &Cmds : {InsertBeforeCommands, InsertAfterCommands})
    for (const std::pair<StringRef, std::vector<BaseCommand *>> &P : Cmds)
      if (!P.second.empty())
        error("unable to INSERT AFTER/BEFORE " + P.first +
              ": section not defined");

  SectionCommands = std::move(V);
}

// Symbols defined in script should not be inlined by LTO. At the same time
// we don't know their final values until late stages of link. Here we scan
// over symbol assignment commands and create placeholder symbols if needed.
void LinkerScript::declareSymbols() {
  assert(!Ctx);
  for (BaseCommand *Base : SectionCommands) {
    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
      declareSymbol(Cmd);
      continue;
    }

    // If the output section directive has constraints,
    // we can't say for sure if it is going to be included or not.
    // Skip such sections for now. Improve the checks if we ever
    // need symbols from that sections to be declared early.
    auto *Sec = cast<OutputSection>(Base);
    if (Sec->Constraint != ConstraintKind::NoConstraint)
      continue;
    for (BaseCommand *Base2 : Sec->SectionCommands)
      if (auto *Cmd = dyn_cast<SymbolAssignment>(Base2))
        declareSymbol(Cmd);
  }
}

// This function is called from assignAddresses, while we are
// fixing the output section addresses. This function is supposed
// to set the final value for a given symbol assignment.
void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
  if (Cmd->Name == ".") {
    setDot(Cmd->Expression, Cmd->Location, InSec);
    return;
  }

  if (!Cmd->Sym)
    return;

  ExprValue V = Cmd->Expression();
  if (V.isAbsolute()) {
    Cmd->Sym->Section = nullptr;
    Cmd->Sym->Value = V.getValue();
  } else {
    Cmd->Sym->Section = V.Sec;
    Cmd->Sym->Value = V.getSectionOffset();
  }
}

static std::string getFilename(InputFile *File) {
  if (!File)
    return "";
  if (File->ArchiveName.empty())
    return File->getName();
  return (File->ArchiveName + "(" + File->getName() + ")").str();
}

bool LinkerScript::shouldKeep(InputSectionBase *S) {
  if (KeptSections.empty())
    return false;
  std::string Filename = getFilename(S->File);
  for (InputSectionDescription *ID : KeptSections)
    if (ID->FilePat.match(Filename))
      for (SectionPattern &P : ID->SectionPatterns)
        if (P.SectionPat.match(S->Name))
          return true;
  return false;
}

// A helper function for the SORT() command.
static std::function<bool(InputSectionBase *, InputSectionBase *)>
getComparator(SortSectionPolicy K) {
  switch (K) {
  case SortSectionPolicy::Alignment:
    return [](InputSectionBase *A, InputSectionBase *B) {
      // ">" is not a mistake. Sections with larger alignments are placed
      // before sections with smaller alignments in order to reduce the
      // amount of padding necessary. This is compatible with GNU.
      return A->Alignment > B->Alignment;
    };
  case SortSectionPolicy::Name:
    return [](InputSectionBase *A, InputSectionBase *B) {
      return A->Name < B->Name;
    };
  case SortSectionPolicy::Priority:
    return [](InputSectionBase *A, InputSectionBase *B) {
      return getPriority(A->Name) < getPriority(B->Name);
    };
  default:
    llvm_unreachable("unknown sort policy");
  }
}

// A helper function for the SORT() command.
static bool matchConstraints(ArrayRef<InputSection *> Sections,
                             ConstraintKind Kind) {
  if (Kind == ConstraintKind::NoConstraint)
    return true;

  bool IsRW = llvm::any_of(
      Sections, [](InputSection *Sec) { return Sec->Flags & SHF_WRITE; });

  return (IsRW && Kind == ConstraintKind::ReadWrite) ||
         (!IsRW && Kind == ConstraintKind::ReadOnly);
}

static void sortSections(MutableArrayRef<InputSection *> Vec,
                         SortSectionPolicy K) {
  if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
    llvm::stable_sort(Vec, getComparator(K));
}

// Sort sections as instructed by SORT-family commands and --sort-section
// option. Because SORT-family commands can be nested at most two depth
// (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
// line option is respected even if a SORT command is given, the exact
// behavior we have here is a bit complicated. Here are the rules.
//
// 1. If two SORT commands are given, --sort-section is ignored.
// 2. If one SORT command is given, and if it is not SORT_NONE,
//    --sort-section is handled as an inner SORT command.
// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
// 4. If no SORT command is given, sort according to --sort-section.
static void sortInputSections(MutableArrayRef<InputSection *> Vec,
                              const SectionPattern &Pat) {
  if (Pat.SortOuter == SortSectionPolicy::None)
    return;

  if (Pat.SortInner == SortSectionPolicy::Default)
    sortSections(Vec, Config->SortSection);
  else
    sortSections(Vec, Pat.SortInner);
  sortSections(Vec, Pat.SortOuter);
}

// Compute and remember which sections the InputSectionDescription matches.
std::vector<InputSection *>
LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
  std::vector<InputSection *> Ret;

  // Collects all sections that satisfy constraints of Cmd.
  for (const SectionPattern &Pat : Cmd->SectionPatterns) {
    size_t SizeBefore = Ret.size();

    for (InputSectionBase *Sec : InputSections) {
      if (!Sec->isLive() || Sec->Assigned)
        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 (auto *IS = dyn_cast<InputSection>(Sec))
        if (IS->getRelocatedSection())
          continue;

      std::string Filename = getFilename(Sec->File);
      if (!Cmd->FilePat.match(Filename) ||
          Pat.ExcludedFilePat.match(Filename) ||
          !Pat.SectionPat.match(Sec->Name))
        continue;

      // It is safe to assume that Sec is an InputSection
      // because mergeable or EH input sections have already been
      // handled and eliminated.
      Ret.push_back(cast<InputSection>(Sec));
      Sec->Assigned = true;
    }

    sortInputSections(MutableArrayRef<InputSection *>(Ret).slice(SizeBefore),
                      Pat);
  }
  return Ret;
}

void LinkerScript::discard(ArrayRef<InputSection *> V) {
  for (InputSection *S : V) {
    if (S == In.ShStrTab || S == In.RelaDyn || S == In.RelrDyn)
      error("discarding " + S->Name + " section is not allowed");

    // You can discard .hash and .gnu.hash sections by linker scripts. Since
    // they are synthesized sections, we need to handle them differently than
    // other regular sections.
    if (S == In.GnuHashTab)
      In.GnuHashTab = nullptr;
    if (S == In.HashTab)
      In.HashTab = nullptr;

    S->Assigned = false;
    S->markDead();
    discard(S->DependentSections);
  }
}

std::vector<InputSection *>
LinkerScript::createInputSectionList(OutputSection &OutCmd) {
  std::vector<InputSection *> Ret;

  for (BaseCommand *Base : OutCmd.SectionCommands) {
    if (auto *Cmd = dyn_cast<InputSectionDescription>(Base)) {
      Cmd->Sections = computeInputSections(Cmd);
      Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
    }
  }
  return Ret;
}

void LinkerScript::processSectionCommands() {
  // A symbol can be assigned before any section is mentioned in the linker
  // script. In an DSO, the symbol values are addresses, so the only important
  // section values are:
  // * SHN_UNDEF
  // * SHN_ABS
  // * Any value meaning a regular section.
  // To handle that, create a dummy aether section that fills the void before
  // the linker scripts switches to another section. It has an index of one
  // which will map to whatever the first actual section is.
  Aether = make<OutputSection>("", 0, SHF_ALLOC);
  Aether->SectionIndex = 1;

  // Ctx captures the local AddressState and makes it accessible deliberately.
  // This is needed as there are some cases where we cannot just
  // thread the current state through to a lambda function created by the
  // script parser.
  auto Deleter = make_unique<AddressState>();
  Ctx = Deleter.get();
  Ctx->OutSec = Aether;

  size_t I = 0;
  // Add input sections to output sections.
  for (BaseCommand *Base : SectionCommands) {
    // Handle symbol assignments outside of any output section.
    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
      addSymbol(Cmd);
      continue;
    }

    if (auto *Sec = dyn_cast<OutputSection>(Base)) {
      std::vector<InputSection *> V = createInputSectionList(*Sec);

      // The output section name `/DISCARD/' is special.
      // Any input section assigned to it is discarded.
      if (Sec->Name == "/DISCARD/") {
        discard(V);
        Sec->SectionCommands.clear();
        Sec->SectionIndex = 0; // Not an orphan.
        continue;
      }

      // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
      // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
      // sections satisfy a given constraint. If not, a directive is handled
      // as if it wasn't present from the beginning.
      //
      // Because we'll iterate over SectionCommands many more times, the easy
      // way to "make it as if it wasn't present" is to make it empty.
      if (!matchConstraints(V, Sec->Constraint)) {
        for (InputSectionBase *S : V)
          S->Assigned = false;
        Sec->SectionCommands.clear();
        continue;
      }

      // A directive may contain symbol definitions like this:
      // ".foo : { ...; bar = .; }". Handle them.
      for (BaseCommand *Base : Sec->SectionCommands)
        if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
          addSymbol(OutCmd);

      // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
      // is given, input sections are aligned to that value, whether the
      // given value is larger or smaller than the original section alignment.
      if (Sec->SubalignExpr) {
        uint32_t Subalign = Sec->SubalignExpr().getValue();
        for (InputSectionBase *S : V)
          S->Alignment = Subalign;
      }

      // Add input sections to an output section.
      for (InputSection *S : V)
        Sec->addSection(S);

      Sec->SectionIndex = I++;
      if (Sec->Noload)
        Sec->Type = SHT_NOBITS;
      if (Sec->NonAlloc)
        Sec->Flags &= ~(uint64_t)SHF_ALLOC;
    }
  }
  Ctx = nullptr;
}

static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
                                 StringRef Name) {
  for (BaseCommand *Base : Vec)
    if (auto *Sec = dyn_cast<OutputSection>(Base))
      if (Sec->Name == Name)
        return Sec;
  return nullptr;
}

static OutputSection *createSection(InputSectionBase *IS,
                                    StringRef OutsecName) {
  OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>");
  Sec->addSection(cast<InputSection>(IS));
  return Sec;
}

static OutputSection *
addInputSec(StringMap<TinyPtrVector<OutputSection *>> &Map,
            InputSectionBase *IS, StringRef OutsecName) {
  // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
  // option is given. A section with SHT_GROUP defines a "section group", and
  // its members have SHF_GROUP attribute. Usually these flags have already been
  // stripped by InputFiles.cpp as section groups are processed and uniquified.
  // However, for the -r option, we want to pass through all section groups
  // as-is because adding/removing members or merging them with other groups
  // change their semantics.
  if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP))
    return createSection(IS, OutsecName);

  // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
  // relocation sections .rela.foo and .rela.bar for example. Most tools do
  // not allow multiple REL[A] sections for output section. Hence we
  // should combine these relocation sections into single output.
  // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
  // other REL[A] sections created by linker itself.
  if (!isa<SyntheticSection>(IS) &&
      (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
    auto *Sec = cast<InputSection>(IS);
    OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();

    if (Out->RelocationSection) {
      Out->RelocationSection->addSection(Sec);
      return nullptr;
    }

    Out->RelocationSection = createSection(IS, OutsecName);
    return Out->RelocationSection;
  }

  // When control reaches here, mergeable sections have already been merged into
  // synthetic sections. For relocatable case we want to create one output
  // section per syntetic section so that they have a valid sh_entsize.
  if (Config->Relocatable && (IS->Flags & SHF_MERGE))
    return createSection(IS, OutsecName);

  //  The ELF spec just says
  // ----------------------------------------------------------------
  // In the first phase, input sections that match in name, type and
  // attribute flags should be concatenated into single sections.
  // ----------------------------------------------------------------
  //
  // However, it is clear that at least some flags have to be ignored for
  // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be
  // ignored. We should not have two output .text sections just because one was
  // in a group and another was not for example.
  //
  // It also seems that wording was a late addition and didn't get the
  // necessary scrutiny.
  //
  // Merging sections with different flags is expected by some users. One
  // reason is that if one file has
  //
  // int *const bar __attribute__((section(".foo"))) = (int *)0;
  //
  // gcc with -fPIC will produce a read only .foo section. But if another
  // file has
  //
  // int zed;
  // int *const bar __attribute__((section(".foo"))) = (int *)&zed;
  //
  // gcc with -fPIC will produce a read write section.
  //
  // Last but not least, when using linker script the merge rules are forced by
  // the script. Unfortunately, linker scripts are name based. This means that
  // expressions like *(.foo*) can refer to multiple input sections with
  // different flags. We cannot put them in different output sections or we
  // would produce wrong results for
  //
  // start = .; *(.foo.*) end = .; *(.bar)
  //
  // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to
  // another. The problem is that there is no way to layout those output
  // sections such that the .foo sections are the only thing between the start
  // and end symbols.
  //
  // Given the above issues, we instead merge sections by name and error on
  // incompatible types and flags.
  TinyPtrVector<OutputSection *> &V = Map[OutsecName];
  for (OutputSection *Sec : V) {
    if (Sec->Partition != IS->Partition)
      continue;
    Sec->addSection(cast<InputSection>(IS));
    return nullptr;
  }

  OutputSection *Sec = createSection(IS, OutsecName);
  V.push_back(Sec);
  return Sec;
}

// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections() {
  StringMap<TinyPtrVector<OutputSection *>> Map;
  std::vector<OutputSection *> V;

  auto Add = [&](InputSectionBase *S) {
    if (!S->isLive() || S->Parent)
      return;

    StringRef Name = getOutputSectionName(S);

    if (Config->OrphanHandling == OrphanHandlingPolicy::Error)
      error(toString(S) + " is being placed in '" + Name + "'");
    else if (Config->OrphanHandling == OrphanHandlingPolicy::Warn)
      warn(toString(S) + " is being placed in '" + Name + "'");

    if (OutputSection *Sec = findByName(SectionCommands, Name)) {
      Sec->addSection(cast<InputSection>(S));
      return;
    }

    if (OutputSection *OS = addInputSec(Map, S, Name))
      V.push_back(OS);
    assert(S->getOutputSection()->SectionIndex == UINT32_MAX);
  };

  // For futher --emit-reloc handling code we need target output section
  // to be created before we create relocation output section, so we want
  // to create target sections first. We do not want priority handling
  // for synthetic sections because them are special.
  for (InputSectionBase *IS : InputSections) {
    if (auto *Sec = dyn_cast<InputSection>(IS))
      if (InputSectionBase *Rel = Sec->getRelocatedSection())
        if (auto *RelIS = dyn_cast_or_null<InputSectionBase>(Rel->Parent))
          Add(RelIS);
    Add(IS);
  }

  // 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) {
  bool IsTbss =
      (Ctx->OutSec->Flags & SHF_TLS) && Ctx->OutSec->Type == SHT_NOBITS;
  uint64_t Start = IsTbss ? Dot + Ctx->ThreadBssOffset : Dot;
  Start = alignTo(Start, Alignment);
  uint64_t End = Start + Size;

  if (IsTbss)
    Ctx->ThreadBssOffset = End - Dot;
  else
    Dot = End;
  return End;
}

void LinkerScript::output(InputSection *S) {
  assert(Ctx->OutSec == S->getParent());
  uint64_t Before = advance(0, 1);
  uint64_t Pos = advance(S->getSize(), S->Alignment);
  S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;

  // Update output section size after adding each section. This is so that
  // SIZEOF works correctly in the case below:
  // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
  expandOutputSection(Pos - Before);
}

void LinkerScript::switchTo(OutputSection *Sec) {
  Ctx->OutSec = Sec;

  uint64_t Before = advance(0, 1);
  Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment);
  expandMemoryRegions(Ctx->OutSec->Addr - Before);
}

// This function searches for a memory region to place the given output
// section in. If found, a pointer to the appropriate memory region is
// returned. Otherwise, a nullptr is returned.
MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) {
  // If a memory region name was specified in the output section command,
  // then try to find that region first.
  if (!Sec->MemoryRegionName.empty()) {
    if (MemoryRegion *M = MemoryRegions.lookup(Sec->MemoryRegionName))
      return M;
    error("memory region '" + Sec->MemoryRegionName + "' not declared");
    return nullptr;
  }

  // If at least one memory region is defined, all sections must
  // belong to some memory region. Otherwise, we don't need to do
  // anything for memory regions.
  if (MemoryRegions.empty())
    return nullptr;

  // See if a region can be found by matching section flags.
  for (auto &Pair : MemoryRegions) {
    MemoryRegion *M = Pair.second;
    if ((M->Flags & Sec->Flags) && (M->NegFlags & Sec->Flags) == 0)
      return M;
  }

  // Otherwise, no suitable region was found.
  if (Sec->Flags & SHF_ALLOC)
    error("no memory region specified for section '" + Sec->Name + "'");
  return nullptr;
}

static OutputSection *findFirstSection(PhdrEntry *Load) {
  for (OutputSection *Sec : OutputSections)
    if (Sec->PtLoad == Load)
      return Sec;
  return nullptr;
}

// This function assigns offsets to input sections and an output section
// for a single sections command (e.g. ".text { *(.text); }").
void LinkerScript::assignOffsets(OutputSection *Sec) {
  if (!(Sec->Flags & SHF_ALLOC))
    Dot = 0;

  Ctx->MemRegion = Sec->MemRegion;
  Ctx->LMARegion = Sec->LMARegion;
  if (Ctx->MemRegion)
    Dot = Ctx->MemRegion->CurPos;

  if ((Sec->Flags & SHF_ALLOC) && Sec->AddrExpr)
    setDot(Sec->AddrExpr, Sec->Location, false);

  switchTo(Sec);

  if (Sec->LMAExpr)
    Ctx->LMAOffset = Sec->LMAExpr().getValue() - Dot;

  if (MemoryRegion *MR = Sec->LMARegion)
    Ctx->LMAOffset = MR->CurPos - Dot;

  // If neither AT nor AT> is specified for an allocatable section, the linker
  // will set the LMA such that the difference between VMA and LMA for the
  // section is the same as the preceding output section in the same region
  // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
  // This, however, should only be done by the first "non-header" section
  // in the segment.
  if (PhdrEntry *L = Ctx->OutSec->PtLoad)
    if (Sec == findFirstSection(L))
      L->LMAOffset = Ctx->LMAOffset;

  // We can call this method multiple times during the creation of
  // thunks and want to start over calculation each time.
  Sec->Size = 0;

  // We visited SectionsCommands from processSectionCommands to
  // layout sections. Now, we visit SectionsCommands again to fix
  // section offsets.
  for (BaseCommand *Base : Sec->SectionCommands) {
    // This handles the assignments to symbol or to the dot.
    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
      Cmd->Addr = Dot;
      assignSymbol(Cmd, true);
      Cmd->Size = Dot - Cmd->Addr;
      continue;
    }

    // Handle BYTE(), SHORT(), LONG(), or QUAD().
    if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
      Cmd->Offset = Dot - Ctx->OutSec->Addr;
      Dot += Cmd->Size;
      expandOutputSection(Cmd->Size);
      continue;
    }

    // Handle a single input section description command.
    // It calculates and assigns the offsets for each section and also
    // updates the output section size.
    for (InputSection *Sec : cast<InputSectionDescription>(Base)->Sections)
      output(Sec);
  }
}

static bool isDiscardable(OutputSection &Sec) {
  // We do not remove empty sections that are explicitly
  // assigned to any segment.
  if (!Sec.Phdrs.empty())
    return false;

  // We do not want to remove OutputSections with expressions that reference
  // symbols even if the OutputSection is empty. We want to ensure that the
  // expressions can be evaluated and report an error if they cannot.
  if (Sec.ExpressionsUseSymbols)
    return false;

  // OutputSections may be referenced by name in ADDR and LOADADDR expressions,
  // as an empty Section can has a valid VMA and LMA we keep the OutputSection
  // to maintain the integrity of the other Expression.
  if (Sec.UsedInExpression)
    return false;

  for (BaseCommand *Base : Sec.SectionCommands) {
    if (auto Cmd = dyn_cast<SymbolAssignment>(Base))
      // Don't create empty output sections just for unreferenced PROVIDE
      // symbols.
      if (Cmd->Name != "." && !Cmd->Sym)
        continue;

    if (!isa<InputSectionDescription>(*Base))
      return false;
  }
  return true;
}

void LinkerScript::adjustSectionsBeforeSorting() {
  // If the output section contains only symbol assignments, create a
  // corresponding output section. The issue is what to do with linker script
  // like ".foo : { symbol = 42; }". One option would be to convert it to
  // "symbol = 42;". That is, move the symbol out of the empty section
  // description. That seems to be what bfd does for this simple case. The
  // problem is that this is not completely general. bfd will give up and
  // create a dummy section too if there is a ". = . + 1" inside the section
  // for example.
  // Given that we want to create the section, we have to worry what impact
  // it will have on the link. For example, if we just create a section with
  // 0 for flags, it would change which PT_LOADs are created.
  // We could remember that particular section is dummy and ignore it in
  // other parts of the linker, but unfortunately there are quite a few places
  // that would need to change:
  //   * The program header creation.
  //   * The orphan section placement.
  //   * The address assignment.
  // The other option is to pick flags that minimize the impact the section
  // will have on the rest of the linker. That is why we copy the flags from
  // the previous sections. Only a few flags are needed to keep the impact low.
  uint64_t Flags = SHF_ALLOC;

  for (BaseCommand *&Cmd : SectionCommands) {
    auto *Sec = dyn_cast<OutputSection>(Cmd);
    if (!Sec)
      continue;

    // Handle align (e.g. ".foo : ALIGN(16) { ... }").
    if (Sec->AlignExpr)
      Sec->Alignment =
          std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue());

    // A live output section means that some input section was added to it. It
    // might have been removed (if it was empty synthetic section), but we at
    // least know the flags.
    if (Sec->isLive())
      Flags = Sec->Flags;

    // We do not want to keep any special flags for output section
    // in case it is empty.
    bool IsEmpty = getInputSections(Sec).empty();
    if (IsEmpty)
      Sec->Flags = Flags & ((Sec->NonAlloc ? 0 : (uint64_t)SHF_ALLOC) |
                            SHF_WRITE | SHF_EXECINSTR);

    if (IsEmpty && isDiscardable(*Sec)) {
      Sec->markDead();
      Cmd = nullptr;
    }
  }

  // It is common practice to use very generic linker scripts. So for any
  // given run some of the output sections in the script will be empty.
  // We could create corresponding empty output sections, but that would
  // clutter the output.
  // We instead remove trivially empty sections. The bfd linker seems even
  // more aggressive at removing them.
  llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; });
}

void LinkerScript::adjustSectionsAfterSorting() {
  // Try and find an appropriate memory region to assign offsets in.
  for (BaseCommand *Base : SectionCommands) {
    if (auto *Sec = dyn_cast<OutputSection>(Base)) {
      if (!Sec->LMARegionName.empty()) {
        if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName))
          Sec->LMARegion = M;
        else
          error("memory region '" + Sec->LMARegionName + "' not declared");
      }
      Sec->MemRegion = findMemoryRegion(Sec);
    }
  }

  // If output section command doesn't specify any segments,
  // and we haven't previously assigned any section to segment,
  // then we simply assign section to the very first load segment.
  // Below is an example of such linker script:
  // PHDRS { seg PT_LOAD; }
  // SECTIONS { .aaa : { *(.aaa) } }
  std::vector<StringRef> DefPhdrs;
  auto FirstPtLoad = llvm::find_if(PhdrsCommands, [](const PhdrsCommand &Cmd) {
    return Cmd.Type == PT_LOAD;
  });
  if (FirstPtLoad != PhdrsCommands.end())
    DefPhdrs.push_back(FirstPtLoad->Name);

  // Walk the commands and propagate the program headers to commands that don't
  // explicitly specify them.
  for (BaseCommand *Base : SectionCommands) {
    auto *Sec = dyn_cast<OutputSection>(Base);
    if (!Sec)
      continue;

    if (Sec->Phdrs.empty()) {
      // To match the bfd linker script behaviour, only propagate program
      // headers to sections that are allocated.
      if (Sec->Flags & SHF_ALLOC)
        Sec->Phdrs = DefPhdrs;
    } else {
      DefPhdrs = Sec->Phdrs;
    }
  }
}

static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) {
  // If there is no SECTIONS or if the linkerscript is explicit about program
  // headers, do our best to allocate them.
  if (!Script->HasSectionsCommand || AllocateHeaders)
    return 0;
  // Otherwise only allocate program headers if that would not add a page.
  return alignDown(Min, Config->MaxPageSize);
}

// Try to find an address for the file and program headers output sections,
// which were unconditionally added to the first PT_LOAD segment earlier.
//
// When using the default layout, we check if the headers fit below the first
// allocated section. When using a linker script, we also check if the headers
// are covered by the output section. This allows omitting the headers by not
// leaving enough space for them in the linker script; this pattern is common
// in embedded systems.
//
// If there isn't enough space for these sections, we'll remove them from the
// PT_LOAD segment, and we'll also remove the PT_PHDR segment.
void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) {
  uint64_t Min = std::numeric_limits<uint64_t>::max();
  for (OutputSection *Sec : OutputSections)
    if (Sec->Flags & SHF_ALLOC)
      Min = std::min<uint64_t>(Min, Sec->Addr);

  auto It = llvm::find_if(
      Phdrs, [](const PhdrEntry *E) { return E->p_type == PT_LOAD; });
  if (It == Phdrs.end())
    return;
  PhdrEntry *FirstPTLoad = *It;

  bool HasExplicitHeaders =
      llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) {
        return Cmd.HasPhdrs || Cmd.HasFilehdr;
      });
  bool Paged = !Config->Omagic && !Config->Nmagic;
  uint64_t HeaderSize = getHeaderSize();
  if ((Paged || HasExplicitHeaders) &&
      HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) {
    Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
    Out::ElfHeader->Addr = Min;
    Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
    return;
  }

  // Error if we were explicitly asked to allocate headers.
  if (HasExplicitHeaders)
    error("could not allocate headers");

  Out::ElfHeader->PtLoad = nullptr;
  Out::ProgramHeaders->PtLoad = nullptr;
  FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad);

  llvm::erase_if(Phdrs,
                 [](const PhdrEntry *E) { return E->p_type == PT_PHDR; });
}

LinkerScript::AddressState::AddressState() {
  for (auto &MRI : Script->MemoryRegions) {
    MemoryRegion *MR = MRI.second;
    MR->CurPos = MR->Origin;
  }
}

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() {
  Dot = getInitialDot();

  auto Deleter = make_unique<AddressState>();
  Ctx = Deleter.get();
  ErrorOnMissingSection = true;
  switchTo(Aether);

  for (BaseCommand *Base : SectionCommands) {
    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
      Cmd->Addr = Dot;
      assignSymbol(Cmd, false);
      Cmd->Size = Dot - Cmd->Addr;
      continue;
    }
    assignOffsets(cast<OutputSection>(Base));
  }
  Ctx = nullptr;
}

// Creates program headers as instructed by PHDRS linker script command.
std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
  std::vector<PhdrEntry *> Ret;

  // Process PHDRS and FILEHDR keywords because they are not
  // real output sections and cannot be added in the following loop.
  for (const PhdrsCommand &Cmd : PhdrsCommands) {
    PhdrEntry *Phdr = make<PhdrEntry>(Cmd.Type, Cmd.Flags ? *Cmd.Flags : PF_R);

    if (Cmd.HasFilehdr)
      Phdr->add(Out::ElfHeader);
    if (Cmd.HasPhdrs)
      Phdr->add(Out::ProgramHeaders);

    if (Cmd.LMAExpr) {
      Phdr->p_paddr = Cmd.LMAExpr().getValue();
      Phdr->HasLMA = true;
    }
    Ret.push_back(Phdr);
  }

  // Add output sections to program headers.
  for (OutputSection *Sec : OutputSections) {
    // Assign headers specified by linker script
    for (size_t Id : getPhdrIndices(Sec)) {
      Ret[Id]->add(Sec);
      if (!PhdrsCommands[Id].Flags.hasValue())
        Ret[Id]->p_flags |= Sec->getPhdrFlags();
    }
  }
  return Ret;
}

// Returns true if we should emit an .interp section.
//
// We usually do. But if PHDRS commands are given, and
// no PT_INTERP is there, there's no place to emit an
// .interp, so we don't do that in that case.
bool LinkerScript::needsInterpSection() {
  if (PhdrsCommands.empty())
    return true;
  for (PhdrsCommand &Cmd : PhdrsCommands)
    if (Cmd.Type == PT_INTERP)
      return true;
  return false;
}

ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) {
  if (Name == ".") {
    if (Ctx)
      return {Ctx->OutSec, false, Dot - Ctx->OutSec->Addr, Loc};
    error(Loc + ": unable to get location counter value");
    return 0;
  }

  if (Symbol *Sym = Symtab->find(Name)) {
    if (auto *DS = dyn_cast<Defined>(Sym))
      return {DS->Section, false, DS->Value, Loc};
    if (isa<SharedSymbol>(Sym))
      if (!ErrorOnMissingSection)
        return {nullptr, false, 0, Loc};
  }

  error(Loc + ": symbol not found: " + Name);
  return 0;
}

// Returns the index of the segment named Name.
static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> Vec,
                                     StringRef Name) {
  for (size_t I = 0; I < Vec.size(); ++I)
    if (Vec[I].Name == Name)
      return I;
  return None;
}

// Returns indices of ELF headers containing specific section. Each index is a
// zero based number of ELF header listed within PHDRS {} script block.
std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Cmd) {
  std::vector<size_t> Ret;

  for (StringRef S : Cmd->Phdrs) {
    if (Optional<size_t> Idx = getPhdrIndex(PhdrsCommands, S))
      Ret.push_back(*Idx);
    else if (S != "NONE")
      error(Cmd->Location + ": section header '" + S +
            "' is not listed in PHDRS");
  }
  return Ret;
}
