1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11f7c5fbb1SRui Ueyama // 12f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 13f7c5fbb1SRui Ueyama 14717677afSRui Ueyama #include "LinkerScript.h" 15f7c5fbb1SRui Ueyama #include "Config.h" 16f7c5fbb1SRui Ueyama #include "Driver.h" 171ebc8ed7SRui Ueyama #include "InputSection.h" 189381eb10SRui Ueyama #include "Memory.h" 19652852c5SGeorge Rimar #include "OutputSections.h" 20794366a2SRui Ueyama #include "ScriptLexer.h" 2193c9af42SRui Ueyama #include "Strings.h" 22f7c5fbb1SRui Ueyama #include "SymbolTable.h" 2355518e7dSRui Ueyama #include "Symbols.h" 243fb5a6dcSGeorge Rimar #include "SyntheticSections.h" 25467c4d55SEugene Leviant #include "Target.h" 26bbe38602SEugene Leviant #include "Writer.h" 2722886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h" 288c6a5aafSRui Ueyama #include "llvm/ADT/SmallString.h" 2922886a28SEugene Zelenko #include "llvm/ADT/StringRef.h" 30960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 3122886a28SEugene Zelenko #include "llvm/Support/Casting.h" 32652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 3322886a28SEugene Zelenko #include "llvm/Support/Endian.h" 3422886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 35f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 3622886a28SEugene Zelenko #include "llvm/Support/MathExtras.h" 37f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 3822886a28SEugene Zelenko #include <algorithm> 3922886a28SEugene Zelenko #include <cassert> 4022886a28SEugene Zelenko #include <cstddef> 4122886a28SEugene Zelenko #include <cstdint> 4222886a28SEugene Zelenko #include <iterator> 4322886a28SEugene Zelenko #include <limits> 4422886a28SEugene Zelenko #include <memory> 4522886a28SEugene Zelenko #include <string> 4622886a28SEugene Zelenko #include <tuple> 4722886a28SEugene Zelenko #include <vector> 48f7c5fbb1SRui Ueyama 49f7c5fbb1SRui Ueyama using namespace llvm; 50652852c5SGeorge Rimar using namespace llvm::ELF; 511ebc8ed7SRui Ueyama using namespace llvm::object; 52e38cbab5SGeorge Rimar using namespace llvm::support::endian; 53f7c5fbb1SRui Ueyama using namespace lld; 54e0df00b9SRafael Espindola using namespace lld::elf; 55f7c5fbb1SRui Ueyama 56a34da938SRui Ueyama LinkerScript *elf::Script; 57a34da938SRui Ueyama 5872dc195dSRafael Espindola uint64_t ExprValue::getValue() const { 5972dc195dSRafael Espindola if (Sec) 6072dc195dSRafael Espindola return Sec->getOffset(Val) + Sec->getOutputSection()->Addr; 6172dc195dSRafael Espindola return Val; 6272dc195dSRafael Espindola } 6372dc195dSRafael Espindola 647ba5f47eSRafael Espindola uint64_t ExprValue::getSecAddr() const { 657ba5f47eSRafael Espindola if (Sec) 667ba5f47eSRafael Espindola return Sec->getOffset(0) + Sec->getOutputSection()->Addr; 677ba5f47eSRafael Espindola return 0; 687ba5f47eSRafael Espindola } 697ba5f47eSRafael Espindola 707ba5f47eSRafael Espindola // Some operations only support one non absolute value. Move the 717ba5f47eSRafael Espindola // absolute one to the right hand side for convenience. 727ba5f47eSRafael Espindola static void moveAbsRight(ExprValue &A, ExprValue &B) { 73f2115f04SRafael Espindola if (A.isAbsolute()) 74f2115f04SRafael Espindola std::swap(A, B); 755f08a1dcSRafael Espindola if (!B.isAbsolute()) 765f08a1dcSRafael Espindola error("At least one side of the expression must be absolute"); 777ba5f47eSRafael Espindola } 787ba5f47eSRafael Espindola 797ba5f47eSRafael Espindola static ExprValue add(ExprValue A, ExprValue B) { 807ba5f47eSRafael Espindola moveAbsRight(A, B); 8172dc195dSRafael Espindola return {A.Sec, A.ForceAbsolute, A.Val + B.getValue()}; 8272dc195dSRafael Espindola } 8372dc195dSRafael Espindola static ExprValue sub(ExprValue A, ExprValue B) { 8472dc195dSRafael Espindola return {A.Sec, A.Val - B.getValue()}; 8572dc195dSRafael Espindola } 8672dc195dSRafael Espindola static ExprValue mul(ExprValue A, ExprValue B) { 8772dc195dSRafael Espindola return A.getValue() * B.getValue(); 8872dc195dSRafael Espindola } 8972dc195dSRafael Espindola static ExprValue div(ExprValue A, ExprValue B) { 9072dc195dSRafael Espindola if (uint64_t BV = B.getValue()) 9172dc195dSRafael Espindola return A.getValue() / BV; 9272dc195dSRafael Espindola error("division by zero"); 9372dc195dSRafael Espindola return 0; 9472dc195dSRafael Espindola } 9572dc195dSRafael Espindola static ExprValue leftShift(ExprValue A, ExprValue B) { 9672dc195dSRafael Espindola return A.getValue() << B.getValue(); 9772dc195dSRafael Espindola } 9872dc195dSRafael Espindola static ExprValue rightShift(ExprValue A, ExprValue B) { 9972dc195dSRafael Espindola return A.getValue() >> B.getValue(); 10072dc195dSRafael Espindola } 10172dc195dSRafael Espindola static ExprValue bitAnd(ExprValue A, ExprValue B) { 1027ba5f47eSRafael Espindola moveAbsRight(A, B); 1037ba5f47eSRafael Espindola return {A.Sec, A.ForceAbsolute, 1047ba5f47eSRafael Espindola (A.getValue() & B.getValue()) - A.getSecAddr()}; 10572dc195dSRafael Espindola } 10672dc195dSRafael Espindola static ExprValue bitOr(ExprValue A, ExprValue B) { 1077ba5f47eSRafael Espindola moveAbsRight(A, B); 1087ba5f47eSRafael Espindola return {A.Sec, A.ForceAbsolute, 1097ba5f47eSRafael Espindola (A.getValue() | B.getValue()) - A.getSecAddr()}; 11072dc195dSRafael Espindola } 11172dc195dSRafael Espindola static ExprValue bitNot(ExprValue A) { return ~A.getValue(); } 11272dc195dSRafael Espindola static ExprValue minus(ExprValue A) { return -A.getValue(); } 11372dc195dSRafael Espindola 1148f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) { 1155e51f7d2SPetr Hosek Symbol *Sym; 1163dabfc6bSRafael Espindola uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 1175e51f7d2SPetr Hosek std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert( 1185e51f7d2SPetr Hosek Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false, 1195e51f7d2SPetr Hosek /*File*/ nullptr); 1205e51f7d2SPetr Hosek Sym->Binding = STB_GLOBAL; 12172dc195dSRafael Espindola ExprValue Value = Cmd->Expression(); 12272dc195dSRafael Espindola SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec; 12380474a26SRui Ueyama replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility, 1245616adf6SRafael Espindola STT_NOTYPE, 0, 0, Sec, nullptr); 1258f1f3c40SMeador Inge return Sym->body(); 126ceabe80eSEugene Leviant } 127ceabe80eSEugene Leviant 12822375f24SRui Ueyama static bool isUnderSysroot(StringRef Path) { 12922375f24SRui Ueyama if (Config->Sysroot == "") 13022375f24SRui Ueyama return false; 13122375f24SRui Ueyama for (; !Path.empty(); Path = sys::path::parent_path(Path)) 13222375f24SRui Ueyama if (sys::fs::equivalent(Config->Sysroot, Path)) 13322375f24SRui Ueyama return true; 13422375f24SRui Ueyama return false; 13522375f24SRui Ueyama } 13622375f24SRui Ueyama 137b8dd23f5SRui Ueyama OutputSection *LinkerScript::getOutputSection(const Twine &Loc, 138851dc1e8SGeorge Rimar StringRef Name) { 139851dc1e8SGeorge Rimar for (OutputSection *Sec : *OutputSections) 140851dc1e8SGeorge Rimar if (Sec->Name == Name) 141851dc1e8SGeorge Rimar return Sec; 142851dc1e8SGeorge Rimar 143*a08fa2ecSRui Ueyama static OutputSection Dummy("", 0, 0); 14472dc195dSRafael Espindola if (ErrorOnMissingSection) 145851dc1e8SGeorge Rimar error(Loc + ": undefined section " + Name); 146*a08fa2ecSRui Ueyama return &Dummy; 147851dc1e8SGeorge Rimar } 148851dc1e8SGeorge Rimar 149d83ce1b4SGeorge Rimar // This function is essentially the same as getOutputSection(Name)->Size, 150d83ce1b4SGeorge Rimar // but it won't print out an error message if a given section is not found. 151d83ce1b4SGeorge Rimar // 152d83ce1b4SGeorge Rimar // Linker script does not create an output section if its content is empty. 153d83ce1b4SGeorge Rimar // We want to allow SIZEOF(.foo) where .foo is a section which happened to 154d83ce1b4SGeorge Rimar // be empty. That is why this function is different from getOutputSection(). 155b8dd23f5SRui Ueyama uint64_t LinkerScript::getOutputSectionSize(StringRef Name) { 156d83ce1b4SGeorge Rimar for (OutputSection *Sec : *OutputSections) 157d83ce1b4SGeorge Rimar if (Sec->Name == Name) 158d83ce1b4SGeorge Rimar return Sec->Size; 159d83ce1b4SGeorge Rimar return 0; 160d83ce1b4SGeorge Rimar } 161d83ce1b4SGeorge Rimar 162b8dd23f5SRui Ueyama void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { 16372dc195dSRafael Espindola uint64_t Val = E().getValue(); 1644cd7352cSRafael Espindola if (Val < Dot) { 1654cd7352cSRafael Espindola if (InSec) 1662ee2d2dcSGeorge Rimar error(Loc + ": unable to move location counter backward for: " + 1672ee2d2dcSGeorge Rimar CurOutSec->Name); 1684cd7352cSRafael Espindola else 1692ee2d2dcSGeorge Rimar error(Loc + ": unable to move location counter backward"); 1704cd7352cSRafael Espindola } 1714cd7352cSRafael Espindola Dot = Val; 1724cd7352cSRafael Espindola // Update to location counter means update to section size. 1734cd7352cSRafael Espindola if (InSec) 1744cd7352cSRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 175679828ffSRafael Espindola } 176679828ffSRafael Espindola 177679828ffSRafael Espindola // Sets value of a symbol. Two kinds of symbols are processed: synthetic 178679828ffSRafael Espindola // symbols, whose value is an offset from beginning of section and regular 179679828ffSRafael Espindola // symbols whose value is absolute. 180b8dd23f5SRui Ueyama void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) { 181679828ffSRafael Espindola if (Cmd->Name == ".") { 1822ee2d2dcSGeorge Rimar setDot(Cmd->Expression, Cmd->Location, InSec); 1834cd7352cSRafael Espindola return; 1844cd7352cSRafael Espindola } 1854cd7352cSRafael Espindola 186b2b70975SGeorge Rimar if (!Cmd->Sym) 1878f1f3c40SMeador Inge return; 1888f1f3c40SMeador Inge 1895616adf6SRafael Espindola auto *Sym = cast<DefinedRegular>(Cmd->Sym); 19072dc195dSRafael Espindola ExprValue V = Cmd->Expression(); 19172dc195dSRafael Espindola if (V.isAbsolute()) { 19272dc195dSRafael Espindola Sym->Value = V.getValue(); 19372dc195dSRafael Espindola } else { 19472dc195dSRafael Espindola Sym->Section = V.Sec; 19572dc195dSRafael Espindola if (Sym->Section->Flags & SHF_ALLOC) 19672dc195dSRafael Espindola Sym->Value = V.Val; 19772dc195dSRafael Espindola else 19872dc195dSRafael Espindola Sym->Value = V.getValue(); 199ea590d91SRafael Espindola } 2008f1f3c40SMeador Inge } 2018f1f3c40SMeador Inge 202a8dba487SGeorge Rimar static SymbolBody *findSymbol(StringRef S) { 203a8dba487SGeorge Rimar switch (Config->EKind) { 204a8dba487SGeorge Rimar case ELF32LEKind: 205a8dba487SGeorge Rimar return Symtab<ELF32LE>::X->find(S); 206a8dba487SGeorge Rimar case ELF32BEKind: 207a8dba487SGeorge Rimar return Symtab<ELF32BE>::X->find(S); 208a8dba487SGeorge Rimar case ELF64LEKind: 209a8dba487SGeorge Rimar return Symtab<ELF64LE>::X->find(S); 210a8dba487SGeorge Rimar case ELF64BEKind: 211a8dba487SGeorge Rimar return Symtab<ELF64BE>::X->find(S); 212a8dba487SGeorge Rimar default: 213a8dba487SGeorge Rimar llvm_unreachable("unknown Config->EKind"); 214a8dba487SGeorge Rimar } 215a8dba487SGeorge Rimar } 216a8dba487SGeorge Rimar 217a8dba487SGeorge Rimar static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) { 218a8dba487SGeorge Rimar switch (Config->EKind) { 219a8dba487SGeorge Rimar case ELF32LEKind: 220a8dba487SGeorge Rimar return addRegular<ELF32LE>(Cmd); 221a8dba487SGeorge Rimar case ELF32BEKind: 222a8dba487SGeorge Rimar return addRegular<ELF32BE>(Cmd); 223a8dba487SGeorge Rimar case ELF64LEKind: 224a8dba487SGeorge Rimar return addRegular<ELF64LE>(Cmd); 225a8dba487SGeorge Rimar case ELF64BEKind: 226a8dba487SGeorge Rimar return addRegular<ELF64BE>(Cmd); 227a8dba487SGeorge Rimar default: 228a8dba487SGeorge Rimar llvm_unreachable("unknown Config->EKind"); 229a8dba487SGeorge Rimar } 230a8dba487SGeorge Rimar } 231a8dba487SGeorge Rimar 232b8dd23f5SRui Ueyama void LinkerScript::addSymbol(SymbolAssignment *Cmd) { 2331602421cSRui Ueyama if (Cmd->Name == ".") 2348f1f3c40SMeador Inge return; 2358f1f3c40SMeador Inge 2368f1f3c40SMeador Inge // If a symbol was in PROVIDE(), we need to define it only when 2378f1f3c40SMeador Inge // it is a referenced undefined symbol. 238a8dba487SGeorge Rimar SymbolBody *B = findSymbol(Cmd->Name); 2398f1f3c40SMeador Inge if (Cmd->Provide && (!B || B->isDefined())) 2408f1f3c40SMeador Inge return; 2418f1f3c40SMeador Inge 242a8dba487SGeorge Rimar Cmd->Sym = addRegularSymbol(Cmd); 243ceabe80eSEugene Leviant } 244ceabe80eSEugene Leviant 245076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 246076fe157SGeorge Rimar return C->Kind == AssignmentKind; 247076fe157SGeorge Rimar } 248076fe157SGeorge Rimar 249076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 250076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 251076fe157SGeorge Rimar } 252076fe157SGeorge Rimar 253eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 254eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 255eea3114fSGeorge Rimar } 256eea3114fSGeorge Rimar 257eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 258eefa758eSGeorge Rimar return C->Kind == AssertKind; 259eefa758eSGeorge Rimar } 260eefa758eSGeorge Rimar 261e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 262e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 263e38cbab5SGeorge Rimar } 264e38cbab5SGeorge Rimar 265b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) { 266b4c9b81aSRafael Espindola if (S->File) 267b4c9b81aSRafael Espindola return sys::path::filename(S->File->getName()); 268e0be2901SRui Ueyama return ""; 269e0be2901SRui Ueyama } 270e0be2901SRui Ueyama 271b8dd23f5SRui Ueyama bool LinkerScript::shouldKeep(InputSectionBase *S) { 272e0be2901SRui Ueyama for (InputSectionDescription *ID : Opt.KeptSections) 273e0be2901SRui Ueyama if (ID->FilePat.match(basename(S))) 274cf43f179SEugene Leviant for (SectionPattern &P : ID->SectionPatterns) 275f91282e1SRui Ueyama if (P.SectionPat.match(S->Name)) 276eea3114fSGeorge Rimar return true; 277eea3114fSGeorge Rimar return false; 278eea3114fSGeorge Rimar } 279eea3114fSGeorge Rimar 280c404d50dSRafael Espindola static bool comparePriority(InputSectionBase *A, InputSectionBase *B) { 281575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 282575208caSGeorge Rimar } 283575208caSGeorge Rimar 284c404d50dSRafael Espindola static bool compareName(InputSectionBase *A, InputSectionBase *B) { 285042a3f20SRafael Espindola return A->Name < B->Name; 2860702c4e8SGeorge Rimar } 287742c3836SRui Ueyama 288c404d50dSRafael Espindola static bool compareAlignment(InputSectionBase *A, InputSectionBase *B) { 289742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 290742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 291742c3836SRui Ueyama // This is compatible with GNU. 292742c3836SRui Ueyama return A->Alignment > B->Alignment; 293742c3836SRui Ueyama } 294742c3836SRui Ueyama 295c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)> 296be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 297be394db3SGeorge Rimar switch (K) { 298be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 299c0028d3dSRafael Espindola return compareAlignment; 300be394db3SGeorge Rimar case SortSectionPolicy::Name: 301be394db3SGeorge Rimar return compareName; 302be394db3SGeorge Rimar case SortSectionPolicy::Priority: 303be394db3SGeorge Rimar return comparePriority; 304be394db3SGeorge Rimar default: 305be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 306be394db3SGeorge Rimar } 307742c3836SRui Ueyama } 3080702c4e8SGeorge Rimar 309b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections, 31006ae6836SGeorge Rimar ConstraintKind Kind) { 3118f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 3128f66df92SGeorge Rimar return true; 313c404d50dSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionBase *Sec2) { 314b4c9b81aSRafael Espindola auto *Sec = static_cast<InputSectionBase *>(Sec2); 3151854a8ebSRafael Espindola return Sec->Flags & SHF_WRITE; 31606ae6836SGeorge Rimar }); 317e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 318e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 31906ae6836SGeorge Rimar } 32006ae6836SGeorge Rimar 321c404d50dSRafael Espindola static void sortSections(InputSectionBase **Begin, InputSectionBase **End, 322ee924709SRui Ueyama SortSectionPolicy K) { 323ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 32407171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 325ee924709SRui Ueyama } 326ee924709SRui Ueyama 327d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 328b8dd23f5SRui Ueyama void LinkerScript::computeInputSections(InputSectionDescription *I) { 3294dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 3304dc07becSRui Ueyama // and attach them to I. 3314dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 33207171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 3338c6a5aafSRui Ueyama 334536a2670SRui Ueyama for (InputSectionBase *S : InputSections) { 3353773bcacSRafael Espindola if (S->Assigned) 3368c6a5aafSRui Ueyama continue; 337908a3d34SRafael Espindola // For -emit-relocs we have to ignore entries like 338908a3d34SRafael Espindola // .rela.dyn : { *(.rela.data) } 339908a3d34SRafael Espindola // which are common because they are in the default bfd script. 340908a3d34SRafael Espindola if (S->Type == SHT_REL || S->Type == SHT_RELA) 341908a3d34SRafael Espindola continue; 3428c6a5aafSRui Ueyama 343e0be2901SRui Ueyama StringRef Filename = basename(S); 344e0be2901SRui Ueyama if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename)) 345e0be2901SRui Ueyama continue; 346e0be2901SRui Ueyama if (!Pat.SectionPat.match(S->Name)) 347e0be2901SRui Ueyama continue; 348d3190795SRafael Espindola I->Sections.push_back(S); 349f94efdddSRui Ueyama S->Assigned = true; 350f94efdddSRui Ueyama } 351d3190795SRafael Espindola 352ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 353ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 354ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 355ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 356ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 357ee924709SRui Ueyama // 358ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 359ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 360ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 361ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 362ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 363c404d50dSRafael Espindola InputSectionBase **Begin = I->Sections.data() + SizeBefore; 364c404d50dSRafael Espindola InputSectionBase **End = I->Sections.data() + I->Sections.size(); 36507171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 36607171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 36707171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 368ee924709SRui Ueyama else 36907171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 37007171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 37107171f21SGeorge Rimar } 372ee924709SRui Ueyama } 373be94e1b6SRafael Espindola } 374be94e1b6SRafael Espindola 375b8dd23f5SRui Ueyama void LinkerScript::discard(ArrayRef<InputSectionBase *> V) { 376b4c9b81aSRafael Espindola for (InputSectionBase *S : V) { 377be94e1b6SRafael Espindola S->Live = false; 378503206c5SGeorge Rimar if (S == InX::ShStrTab) 379ecbfd871SRafael Espindola error("discarding .shstrtab section is not allowed"); 380647c1685SGeorge Rimar discard(S->DependentSections); 381be94e1b6SRafael Espindola } 382be94e1b6SRafael Espindola } 383be94e1b6SRafael Espindola 384b4c9b81aSRafael Espindola std::vector<InputSectionBase *> 385b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) { 386b4c9b81aSRafael Espindola std::vector<InputSectionBase *> Ret; 387e7f912cdSRui Ueyama 38806ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 3897c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 3907c3ff2ebSRafael Espindola if (!Cmd) 3910b9ce6a4SRui Ueyama continue; 392e71a3f8aSRafael Espindola computeInputSections(Cmd); 393c404d50dSRafael Espindola for (InputSectionBase *S : Cmd->Sections) 394b4c9b81aSRafael Espindola Ret.push_back(static_cast<InputSectionBase *>(S)); 3950b9ce6a4SRui Ueyama } 396e71a3f8aSRafael Espindola 3970b9ce6a4SRui Ueyama return Ret; 3980b9ce6a4SRui Ueyama } 3990b9ce6a4SRui Ueyama 400b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) { 4015616adf6SRafael Espindola // A symbol can be assigned before any section is mentioned in the linker 4025616adf6SRafael Espindola // script. In an DSO, the symbol values are addresses, so the only important 4035616adf6SRafael Espindola // section values are: 4045616adf6SRafael Espindola // * SHN_UNDEF 4055616adf6SRafael Espindola // * SHN_ABS 4065616adf6SRafael Espindola // * Any value meaning a regular section. 4075616adf6SRafael Espindola // To handle that, create a dummy aether section that fills the void before 4085616adf6SRafael Espindola // the linker scripts switches to another section. It has an index of one 4095616adf6SRafael Espindola // which will map to whatever the first actual section is. 4105616adf6SRafael Espindola Aether = make<OutputSection>("", 0, SHF_ALLOC); 4115616adf6SRafael Espindola Aether->SectionIndex = 1; 4125616adf6SRafael Espindola CurOutSec = Aether; 41349592cf6SRafael Espindola Dot = 0; 4145616adf6SRafael Espindola 4157c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 4167c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 4177c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 4180b1b695aSRui Ueyama 4190b1b695aSRui Ueyama // Handle symbol assignments outside of any output section. 4202ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 4214cd7352cSRafael Espindola addSymbol(Cmd); 4222ab5f73dSRui Ueyama continue; 4232ab5f73dSRui Ueyama } 4240b1b695aSRui Ueyama 425ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 426b4c9b81aSRafael Espindola std::vector<InputSectionBase *> V = createInputSectionList(*Cmd); 4277bd37870SRafael Espindola 4280b1b695aSRui Ueyama // The output section name `/DISCARD/' is special. 4290b1b695aSRui Ueyama // Any input section assigned to it is discarded. 43048c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 4317bd37870SRafael Espindola discard(V); 43248c3f1ceSRui Ueyama continue; 43348c3f1ceSRui Ueyama } 4340b9ce6a4SRui Ueyama 4350b1b695aSRui Ueyama // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive 4360b1b695aSRui Ueyama // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input 4370b1b695aSRui Ueyama // sections satisfy a given constraint. If not, a directive is handled 4380b1b695aSRui Ueyama // as if it wasn't present from the beginning. 4390b1b695aSRui Ueyama // 4400b1b695aSRui Ueyama // Because we'll iterate over Commands many more times, the easiest 4410b1b695aSRui Ueyama // way to "make it as if it wasn't present" is to just remove it. 442f7f0d088SGeorge Rimar if (!matchConstraints(V, Cmd->Constraint)) { 443b4c9b81aSRafael Espindola for (InputSectionBase *S : V) 444f94efdddSRui Ueyama S->Assigned = false; 4457c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 446dfbbbc86SGeorge Rimar --I; 4477c3ff2ebSRafael Espindola continue; 4487c3ff2ebSRafael Espindola } 4497c3ff2ebSRafael Espindola 4500b1b695aSRui Ueyama // A directive may contain symbol definitions like this: 4510b1b695aSRui Ueyama // ".foo : { ...; bar = .; }". Handle them. 4527c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 4537c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 4544cd7352cSRafael Espindola addSymbol(OutCmd); 4557c3ff2ebSRafael Espindola 4560b1b695aSRui Ueyama // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign 4570b1b695aSRui Ueyama // is given, input sections are aligned to that value, whether the 4580b1b695aSRui Ueyama // given value is larger or smaller than the original section alignment. 4590b1b695aSRui Ueyama if (Cmd->SubalignExpr) { 46072dc195dSRafael Espindola uint32_t Subalign = Cmd->SubalignExpr().getValue(); 461b4c9b81aSRafael Espindola for (InputSectionBase *S : V) 4620b1b695aSRui Ueyama S->Alignment = Subalign; 46320d03194SEugene Leviant } 4640b1b695aSRui Ueyama 4650b1b695aSRui Ueyama // Add input sections to an output section. 466b4c9b81aSRafael Espindola for (InputSectionBase *S : V) 467e21c3af7SGeorge Rimar Factory.addInputSec(S, Cmd->Name); 468eea3114fSGeorge Rimar } 46948c3f1ceSRui Ueyama } 4705616adf6SRafael Espindola CurOutSec = nullptr; 471db24d9c3SGeorge Rimar } 472e63d81bdSEugene Leviant 4730b1b695aSRui Ueyama // Add sections that didn't match any sections command. 474b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { 475536a2670SRui Ueyama for (InputSectionBase *S : InputSections) 4768f9026baSRafael Espindola if (S->Live && !S->OutSec) 477e21c3af7SGeorge Rimar Factory.addInputSec(S, getOutputSectionName(S->Name)); 478e63d81bdSEugene Leviant } 479e63d81bdSEugene Leviant 480f7f0d088SGeorge Rimar static bool isTbss(OutputSection *Sec) { 48104a2e348SRafael Espindola return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS; 482a940e539SRafael Espindola } 483a940e539SRafael Espindola 484b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) { 485d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 486ceabe80eSEugene Leviant return; 487f7f0d088SGeorge Rimar bool IsTbss = isTbss(CurOutSec); 488d3190795SRafael Espindola 4890c1c8085SGeorge Rimar uint64_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 490d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 49104a2e348SRafael Espindola S->OutSecOff = Pos - CurOutSec->Addr; 49276b6bd35SRafael Espindola Pos += S->getSize(); 493d3190795SRafael Espindola 494d3190795SRafael Espindola // Update output section size after adding each section. This is so that 495d3190795SRafael Espindola // SIZEOF works correctly in the case below: 496d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 49704a2e348SRafael Espindola CurOutSec->Size = Pos - CurOutSec->Addr; 498d3190795SRafael Espindola 499b889744eSMeador Inge // If there is a memory region associated with this input section, then 500b889744eSMeador Inge // place the section in that region and update the region index. 501b889744eSMeador Inge if (CurMemRegion) { 502b889744eSMeador Inge CurMemRegion->Offset += CurOutSec->Size; 503b889744eSMeador Inge uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin; 504b889744eSMeador Inge if (CurSize > CurMemRegion->Length) { 505b889744eSMeador Inge uint64_t OverflowAmt = CurSize - CurMemRegion->Length; 506b889744eSMeador Inge error("section '" + CurOutSec->Name + "' will not fit in region '" + 507b889744eSMeador Inge CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) + 508b889744eSMeador Inge " bytes"); 509b889744eSMeador Inge } 510b889744eSMeador Inge } 511b889744eSMeador Inge 5127252ae52SRafael Espindola if (IsTbss) 5137252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 5147252ae52SRafael Espindola else 515d3190795SRafael Espindola Dot = Pos; 5162de509c3SRui Ueyama } 517ceabe80eSEugene Leviant 518b8dd23f5SRui Ueyama void LinkerScript::flush() { 519bd12e2a0SRafael Espindola assert(CurOutSec); 520bd12e2a0SRafael Espindola if (!AlreadyOutputOS.insert(CurOutSec).second) 52165499b90SRafael Espindola return; 52224e6f363SRafael Espindola for (InputSection *I : CurOutSec->Sections) 523d3190795SRafael Espindola output(I); 524d3190795SRafael Espindola } 52597403d15SEugene Leviant 526b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) { 527d3190795SRafael Espindola if (CurOutSec == Sec) 528d3190795SRafael Espindola return; 529d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 530d3190795SRafael Espindola return; 531d3190795SRafael Espindola 532d3190795SRafael Espindola CurOutSec = Sec; 533d3190795SRafael Espindola 5343770763cSRafael Espindola Dot = alignTo(Dot, CurOutSec->Alignment); 535f7f0d088SGeorge Rimar CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot; 536b71d6f7aSEugene Leviant 537b71d6f7aSEugene Leviant // If neither AT nor AT> is specified for an allocatable section, the linker 538b71d6f7aSEugene Leviant // will set the LMA such that the difference between VMA and LMA for the 539b71d6f7aSEugene Leviant // section is the same as the preceding output section in the same region 540b71d6f7aSEugene Leviant // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html 54121467876SGeorge Rimar if (LMAOffset) 54229c1afb8SRafael Espindola CurOutSec->LMAOffset = LMAOffset(); 543d3190795SRafael Espindola } 544d3190795SRafael Espindola 545b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) { 546e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 547d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 5484cd7352cSRafael Espindola assignSymbol(AssignCmd, true); 549d3190795SRafael Espindola return; 55097403d15SEugene Leviant } 551e38cbab5SGeorge Rimar 552e38cbab5SGeorge Rimar // Handle BYTE(), SHORT(), LONG(), or QUAD(). 553e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) { 55404a2e348SRafael Espindola DataCmd->Offset = Dot - CurOutSec->Addr; 555e38cbab5SGeorge Rimar Dot += DataCmd->Size; 55604a2e348SRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 557e38cbab5SGeorge Rimar return; 558e38cbab5SGeorge Rimar } 559e38cbab5SGeorge Rimar 560b2d99d6aSMeador Inge if (auto *AssertCmd = dyn_cast<AssertCommand>(&Base)) { 5614595df94SRafael Espindola AssertCmd->Expression(); 562b2d99d6aSMeador Inge return; 563b2d99d6aSMeador Inge } 564b2d99d6aSMeador Inge 565e38cbab5SGeorge Rimar // It handles single input section description command, 566e38cbab5SGeorge Rimar // calculates and assigns the offsets for each section and also 567e38cbab5SGeorge Rimar // updates the output section size. 568d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 569bd12e2a0SRafael Espindola for (InputSectionBase *IB : ICmd.Sections) { 5703fb5a6dcSGeorge Rimar // We tentatively added all synthetic sections at the beginning and removed 5713fb5a6dcSGeorge Rimar // empty ones afterwards (because there is no way to know whether they were 5723fb5a6dcSGeorge Rimar // going be empty or not other than actually running linker scripts.) 5733fb5a6dcSGeorge Rimar // We need to ignore remains of empty sections. 574bd12e2a0SRafael Espindola if (auto *Sec = dyn_cast<SyntheticSection>(IB)) 5753fb5a6dcSGeorge Rimar if (Sec->empty()) 5763fb5a6dcSGeorge Rimar continue; 5773fb5a6dcSGeorge Rimar 57878ef645fSGeorge Rimar if (!IB->Live) 57978ef645fSGeorge Rimar continue; 580bedccb5eSRafael Espindola assert(CurOutSec == IB->OutSec || AlreadyOutputOS.count(IB->OutSec)); 581bd12e2a0SRafael Espindola output(cast<InputSection>(IB)); 582ceabe80eSEugene Leviant } 583ceabe80eSEugene Leviant } 584ceabe80eSEugene Leviant 58524e6f363SRafael Espindola static OutputSection * 58624e6f363SRafael Espindola findSection(StringRef Name, const std::vector<OutputSection *> &Sections) { 5872b074553SRafael Espindola auto End = Sections.end(); 58824e6f363SRafael Espindola auto HasName = [=](OutputSection *Sec) { return Sec->Name == Name; }; 5892b074553SRafael Espindola auto I = std::find_if(Sections.begin(), End, HasName); 59024e6f363SRafael Espindola std::vector<OutputSection *> Ret; 5912b074553SRafael Espindola if (I == End) 5922b074553SRafael Espindola return nullptr; 5932b074553SRafael Espindola assert(std::find_if(I + 1, End, HasName) == End); 5942b074553SRafael Espindola return *I; 5958f66df92SGeorge Rimar } 5968f66df92SGeorge Rimar 597b889744eSMeador Inge // This function searches for a memory region to place the given output 598b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is 599b889744eSMeador Inge // returned. Otherwise, a nullptr is returned. 600b8dd23f5SRui Ueyama MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd, 60124e6f363SRafael Espindola OutputSection *Sec) { 602b889744eSMeador Inge // If a memory region name was specified in the output section command, 603b889744eSMeador Inge // then try to find that region first. 604b889744eSMeador Inge if (!Cmd->MemoryRegionName.empty()) { 605b889744eSMeador Inge auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName); 606b889744eSMeador Inge if (It != Opt.MemoryRegions.end()) 607b889744eSMeador Inge return &It->second; 608b889744eSMeador Inge error("memory region '" + Cmd->MemoryRegionName + "' not declared"); 609b889744eSMeador Inge return nullptr; 610b889744eSMeador Inge } 611b889744eSMeador Inge 612b889744eSMeador Inge // The memory region name is empty, thus a suitable region must be 613b889744eSMeador Inge // searched for in the region map. If the region map is empty, just 614b889744eSMeador Inge // return. Note that this check doesn't happen at the very beginning 615b889744eSMeador Inge // so that uses of undeclared regions can be caught. 616b889744eSMeador Inge if (!Opt.MemoryRegions.size()) 617b889744eSMeador Inge return nullptr; 618b889744eSMeador Inge 619b889744eSMeador Inge // See if a region can be found by matching section flags. 620b889744eSMeador Inge for (auto &MRI : Opt.MemoryRegions) { 621b889744eSMeador Inge MemoryRegion &MR = MRI.second; 6228a8a953eSRui Ueyama if ((MR.Flags & Sec->Flags) != 0 && (MR.NegFlags & Sec->Flags) == 0) 623b889744eSMeador Inge return &MR; 624b889744eSMeador Inge } 625b889744eSMeador Inge 626b889744eSMeador Inge // Otherwise, no suitable region was found. 627b889744eSMeador Inge if (Sec->Flags & SHF_ALLOC) 628b889744eSMeador Inge error("no memory region specified for section '" + Sec->Name + "'"); 629b889744eSMeador Inge return nullptr; 630b889744eSMeador Inge } 631b889744eSMeador Inge 6320b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section 6330b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }"). 634b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) { 63523e6a024SGeorge Rimar OutputSection *Sec = findSection(Cmd->Name, *OutputSections); 6362b074553SRafael Espindola if (!Sec) 637d3190795SRafael Espindola return; 638b889744eSMeador Inge 639679828ffSRafael Espindola if (Cmd->AddrExpr && Sec->Flags & SHF_ALLOC) 6402ee2d2dcSGeorge Rimar setDot(Cmd->AddrExpr, Cmd->Location); 641679828ffSRafael Espindola 6425784e96fSEugene Leviant if (Cmd->LMAExpr) { 6430c1c8085SGeorge Rimar uint64_t D = Dot; 64472dc195dSRafael Espindola LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; }; 6455784e96fSEugene Leviant } 6465784e96fSEugene Leviant 647165088aaSPetr Hosek // Handle align (e.g. ".foo : ALIGN(16) { ... }"). 648165088aaSPetr Hosek if (Cmd->AlignExpr) 64972dc195dSRafael Espindola Sec->updateAlignment(Cmd->AlignExpr().getValue()); 650165088aaSPetr Hosek 651b889744eSMeador Inge // Try and find an appropriate memory region to assign offsets in. 652b889744eSMeador Inge CurMemRegion = findMemoryRegion(Cmd, Sec); 653b889744eSMeador Inge if (CurMemRegion) 654b889744eSMeador Inge Dot = CurMemRegion->Offset; 655b889744eSMeador Inge switchTo(Sec); 6560b1b695aSRui Ueyama 657d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 658d3190795SRafael Espindola // there so that end symbols point to the correct location. 659d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 660d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 661d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 662d3190795SRafael Espindola }) 663d3190795SRafael Espindola .base(); 664d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 665d3190795SRafael Espindola process(**I); 6662506cb4dSEugene Leviant flush(); 667b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 668b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 669d3190795SRafael Espindola } 670d3190795SRafael Espindola 671b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() { 6726d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 6736d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 6746d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 6756d38e4dbSRafael Espindola // clutter the output. 6766d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 6776d38e4dbSRafael Espindola // more aggressive at removing them. 6786d38e4dbSRafael Espindola auto Pos = std::remove_if( 6796d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 6806d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 6810b1b695aSRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 68223e6a024SGeorge Rimar return !findSection(Cmd->Name, *OutputSections); 6830b1b695aSRui Ueyama return false; 6846d38e4dbSRafael Espindola }); 6856d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 68607fe6129SRafael Espindola } 68707fe6129SRafael Espindola 6886a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) { 6896a53737cSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands) 6906a53737cSRafael Espindola if (!isa<InputSectionDescription>(*I)) 6916a53737cSRafael Espindola return false; 6926a53737cSRafael Espindola return true; 6936a53737cSRafael Espindola } 6946d38e4dbSRafael Espindola 695b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() { 6969546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 6979546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 6989546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 6999546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 7000c1c8085SGeorge Rimar uint64_t Flags = SHF_ALLOC; 701f93b8c29SRafael Espindola uint32_t Type = SHT_NOBITS; 7029546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 7039546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 7049546fffbSRafael Espindola if (!Cmd) 7059546fffbSRafael Espindola continue; 70623e6a024SGeorge Rimar if (OutputSection *Sec = findSection(Cmd->Name, *OutputSections)) { 7072b074553SRafael Espindola Flags = Sec->Flags; 7082b074553SRafael Espindola Type = Sec->Type; 7099546fffbSRafael Espindola continue; 7109546fffbSRafael Espindola } 7119546fffbSRafael Espindola 7126a53737cSRafael Espindola if (isAllSectionDescription(*Cmd)) 7136a53737cSRafael Espindola continue; 7146a53737cSRafael Espindola 71524e6f363SRafael Espindola auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags); 7169546fffbSRafael Espindola OutputSections->push_back(OutSec); 7179546fffbSRafael Espindola } 718f7a17448SRafael Espindola } 719f7a17448SRafael Espindola 720b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() { 721f7a17448SRafael Espindola placeOrphanSections(); 722f7a17448SRafael Espindola 723f7a17448SRafael Espindola // If output section command doesn't specify any segments, 724f7a17448SRafael Espindola // and we haven't previously assigned any section to segment, 725f7a17448SRafael Espindola // then we simply assign section to the very first load segment. 726f7a17448SRafael Espindola // Below is an example of such linker script: 727f7a17448SRafael Espindola // PHDRS { seg PT_LOAD; } 728f7a17448SRafael Espindola // SECTIONS { .aaa : { *(.aaa) } } 729f7a17448SRafael Espindola std::vector<StringRef> DefPhdrs; 730f7a17448SRafael Espindola auto FirstPtLoad = 731f7a17448SRafael Espindola std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(), 732f7a17448SRafael Espindola [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); 733f7a17448SRafael Espindola if (FirstPtLoad != Opt.PhdrsCommands.end()) 734f7a17448SRafael Espindola DefPhdrs.push_back(FirstPtLoad->Name); 735f7a17448SRafael Espindola 736f7a17448SRafael Espindola // Walk the commands and propagate the program headers to commands that don't 737f7a17448SRafael Espindola // explicitly specify them. 738f7a17448SRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 739f7a17448SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 740f7a17448SRafael Espindola if (!Cmd) 741f7a17448SRafael Espindola continue; 742f7a17448SRafael Espindola if (Cmd->Phdrs.empty()) 743f7a17448SRafael Espindola Cmd->Phdrs = DefPhdrs; 744f7a17448SRafael Espindola else 745f7a17448SRafael Espindola DefPhdrs = Cmd->Phdrs; 746f7a17448SRafael Espindola } 7476a53737cSRafael Espindola 7486a53737cSRafael Espindola removeEmptyCommands(); 7499546fffbSRafael Espindola } 7509546fffbSRafael Espindola 75115c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 75215c57951SRafael Espindola // so that an orphan after 75315c57951SRafael Espindola // begin_foo = .; 75415c57951SRafael Espindola // foo : { *(foo) } 75515c57951SRafael Espindola // end_foo = .; 75615c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 75715c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 75815c57951SRafael Espindola // one in charge of deciding the order of the sections. 75915c57951SRafael Espindola // We don't want to go over alignments, since doing so in 76015c57951SRafael Espindola // rx_sec : { *(rx_sec) } 76115c57951SRafael Espindola // . = ALIGN(0x1000); 76215c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 76315c57951SRafael Espindola // rw_sec : { *(rw_sec) } 76415c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 7655fcc99c2SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 76615c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 76715c57951SRafael Espindola return false; 76815c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 76915c57951SRafael Espindola if (!Assign) 77015c57951SRafael Espindola return true; 7715fcc99c2SRafael Espindola return Assign->Name != "."; 77215c57951SRafael Espindola } 77315c57951SRafael Espindola 7746697ec29SRui Ueyama // Orphan sections are sections present in the input files which are 7756697ec29SRui Ueyama // not explicitly placed into the output file by the linker script. 7766697ec29SRui Ueyama // 7776697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains 7786697ec29SRui Ueyama // output section commands for non-orphan sections only. This function 77981cb7107SRui Ueyama // adds new elements for orphan sections so that all sections are 78081cb7107SRui Ueyama // explicitly handled by Opt.Commands. 7816697ec29SRui Ueyama // 7826697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections. 7836697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and 7846697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an 7856697ec29SRui Ueyama // output section that doesn't have a corresponding entry in 7866697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands. 7876697ec29SRui Ueyama // 7886697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be 7896697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section 79081cb7107SRui Ueyama // commands but also other types of commands such as symbol assignment 7916697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the 7926697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to 7936697ec29SRui Ueyama // determine whether a new output command should be added before or 7946697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip 7956697ec29SRui Ueyama // function. 796b8dd23f5SRui Ueyama void LinkerScript::placeOrphanSections() { 797aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 798aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 799aab6d5c5SRafael Espindola // correct order. 800aab6d5c5SRafael Espindola int CmdIndex = 0; 8015fcc99c2SRafael Espindola 8025fcc99c2SRafael Espindola // As a horrible special case, skip the first . assignment if it is before any 8035fcc99c2SRafael Espindola // section. We do this because it is common to set a load address by starting 8045fcc99c2SRafael Espindola // the script with ". = 0xabcd" and the expectation is that every section is 8055fcc99c2SRafael Espindola // after that. 8065fcc99c2SRafael Espindola auto FirstSectionOrDotAssignment = 8075fcc99c2SRafael Espindola std::find_if(Opt.Commands.begin(), Opt.Commands.end(), 8085fcc99c2SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 8095fcc99c2SRafael Espindola if (isa<OutputSectionCommand>(*Cmd)) 8105fcc99c2SRafael Espindola return true; 8115fcc99c2SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get()); 8125fcc99c2SRafael Espindola if (!Assign) 8135fcc99c2SRafael Espindola return false; 8145fcc99c2SRafael Espindola return Assign->Name == "."; 8155fcc99c2SRafael Espindola }); 8165fcc99c2SRafael Espindola if (FirstSectionOrDotAssignment != Opt.Commands.end()) { 8175fcc99c2SRafael Espindola CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin(); 8185fcc99c2SRafael Espindola if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment)) 8195fcc99c2SRafael Espindola ++CmdIndex; 8205fcc99c2SRafael Espindola } 8215fcc99c2SRafael Espindola 82224e6f363SRafael Espindola for (OutputSection *Sec : *OutputSections) { 82340849419SRafael Espindola StringRef Name = Sec->Name; 824aab6d5c5SRafael Espindola 825aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 82615c57951SRafael Espindola // correct result. 827aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 828aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 8295fcc99c2SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 830aab6d5c5SRafael Espindola ++CmdIter; 831aab6d5c5SRafael Espindola ++CmdIndex; 832aab6d5c5SRafael Espindola } 833aab6d5c5SRafael Espindola 834aab6d5c5SRafael Espindola auto Pos = 835aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 836aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 837aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 838aab6d5c5SRafael Espindola }); 839aab6d5c5SRafael Espindola if (Pos == E) { 840aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 841aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 842aab6d5c5SRafael Espindola ++CmdIndex; 84315c57951SRafael Espindola continue; 84415c57951SRafael Espindola } 84515c57951SRafael Espindola 84615c57951SRafael Espindola // Continue from where we found it. 84715c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 848652852c5SGeorge Rimar } 849337f903cSRafael Espindola } 850337f903cSRafael Espindola 851b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() { 85202ad516bSPetr Hosek for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 85302ad516bSPetr Hosek if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) 85402ad516bSPetr Hosek assignSymbol(Cmd); 85502ad516bSPetr Hosek else if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) 85602ad516bSPetr Hosek Cmd->Expression(); 85702ad516bSPetr Hosek } 85802ad516bSPetr Hosek } 85902ad516bSPetr Hosek 860b8dd23f5SRui Ueyama void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) { 8617c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 862be607334SRafael Espindola Dot = 0; 86372dc195dSRafael Espindola ErrorOnMissingSection = true; 86406f4743aSRafael Espindola switchTo(Aether); 86506f4743aSRafael Espindola 866076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 867076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 8684cd7352cSRafael Espindola assignSymbol(Cmd); 86905ef4cffSRui Ueyama continue; 870652852c5SGeorge Rimar } 871652852c5SGeorge Rimar 872eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 8734595df94SRafael Espindola Cmd->Expression(); 874eefa758eSGeorge Rimar continue; 875eefa758eSGeorge Rimar } 876eefa758eSGeorge Rimar 877076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 878d3190795SRafael Espindola assignOffsets(Cmd); 879a14b13d8SGeorge Rimar } 880467c4d55SEugene Leviant 8810c1c8085SGeorge Rimar uint64_t MinVA = std::numeric_limits<uint64_t>::max(); 88224e6f363SRafael Espindola for (OutputSection *Sec : *OutputSections) { 88304a2e348SRafael Espindola if (Sec->Flags & SHF_ALLOC) 884e08e78dfSRafael Espindola MinVA = std::min<uint64_t>(MinVA, Sec->Addr); 885ea590d91SRafael Espindola else 886ea590d91SRafael Espindola Sec->Addr = 0; 887ea590d91SRafael Espindola } 888aab6d5c5SRafael Espindola 8892d262109SGeorge Rimar allocateHeaders(Phdrs, *OutputSections, MinVA); 890fb8978fcSDima Stepanov } 891652852c5SGeorge Rimar 892464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 893b8dd23f5SRui Ueyama std::vector<PhdrEntry> LinkerScript::createPhdrs() { 89417cb7c0aSRafael Espindola std::vector<PhdrEntry> Ret; 895bbe38602SEugene Leviant 896464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 897464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 898bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 899edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 90017cb7c0aSRafael Espindola PhdrEntry &Phdr = Ret.back(); 901bbe38602SEugene Leviant 902bbe38602SEugene Leviant if (Cmd.HasFilehdr) 9039d1bacb1SRui Ueyama Phdr.add(Out::ElfHeader); 904bbe38602SEugene Leviant if (Cmd.HasPhdrs) 9059d1bacb1SRui Ueyama Phdr.add(Out::ProgramHeaders); 90656b21c86SEugene Leviant 90756b21c86SEugene Leviant if (Cmd.LMAExpr) { 90872dc195dSRafael Espindola Phdr.p_paddr = Cmd.LMAExpr().getValue(); 90956b21c86SEugene Leviant Phdr.HasLMA = true; 91056b21c86SEugene Leviant } 911bbe38602SEugene Leviant } 912bbe38602SEugene Leviant 913464daadcSRui Ueyama // Add output sections to program headers. 91424e6f363SRafael Espindola for (OutputSection *Sec : *OutputSections) { 91504a2e348SRafael Espindola if (!(Sec->Flags & SHF_ALLOC)) 916bbe38602SEugene Leviant break; 917bbe38602SEugene Leviant 918bbe38602SEugene Leviant // Assign headers specified by linker script 91940849419SRafael Espindola for (size_t Id : getPhdrIndices(Sec->Name)) { 920edebbdf1SRui Ueyama Ret[Id].add(Sec); 921865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 92217cb7c0aSRafael Espindola Ret[Id].p_flags |= Sec->getPhdrFlags(); 923bbe38602SEugene Leviant } 924bbe38602SEugene Leviant } 925edebbdf1SRui Ueyama return Ret; 926bbe38602SEugene Leviant } 927bbe38602SEugene Leviant 928b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() { 929f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 930f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 931f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 932f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 933f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 934f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 935f9bc3bd2SEugene Leviant } 936f9bc3bd2SEugene Leviant 937b8dd23f5SRui Ueyama uint32_t LinkerScript::getFiller(StringRef Name) { 938f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 939f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 940f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 941f6c3ccefSGeorge Rimar return Cmd->Filler; 94216068aebSRui Ueyama return 0; 943e2ee72b5SGeorge Rimar } 944e2ee72b5SGeorge Rimar 945e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 946e38cbab5SGeorge Rimar switch (Size) { 947e38cbab5SGeorge Rimar case 1: 948e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 949e38cbab5SGeorge Rimar break; 950e38cbab5SGeorge Rimar case 2: 951f93ed4deSRui Ueyama write16(Buf, Data, Config->Endianness); 952e38cbab5SGeorge Rimar break; 953e38cbab5SGeorge Rimar case 4: 954f93ed4deSRui Ueyama write32(Buf, Data, Config->Endianness); 955e38cbab5SGeorge Rimar break; 956e38cbab5SGeorge Rimar case 8: 957f93ed4deSRui Ueyama write64(Buf, Data, Config->Endianness); 958e38cbab5SGeorge Rimar break; 959e38cbab5SGeorge Rimar default: 960e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 961e38cbab5SGeorge Rimar } 962e38cbab5SGeorge Rimar } 963e38cbab5SGeorge Rimar 964b8dd23f5SRui Ueyama void LinkerScript::writeDataBytes(StringRef Name, uint8_t *Buf) { 965e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 966e38cbab5SGeorge Rimar if (I == INT_MAX) 967e38cbab5SGeorge Rimar return; 968e38cbab5SGeorge Rimar 9696e68c5e5SRui Ueyama auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 9706e68c5e5SRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 9716e68c5e5SRui Ueyama if (auto *Data = dyn_cast<BytesDataCommand>(Base.get())) 972a8dba487SGeorge Rimar writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size); 973e38cbab5SGeorge Rimar } 974e38cbab5SGeorge Rimar 975b8dd23f5SRui Ueyama bool LinkerScript::hasLMA(StringRef Name) { 9768ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 9778ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 978b71d6f7aSEugene Leviant if (Cmd->LMAExpr && Cmd->Name == Name) 979b71d6f7aSEugene Leviant return true; 980b71d6f7aSEugene Leviant return false; 9818ceadb38SGeorge Rimar } 9828ceadb38SGeorge Rimar 983c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 984c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 985c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 986c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 987b8dd23f5SRui Ueyama int LinkerScript::getSectionIndex(StringRef Name) { 9886e68c5e5SRui Ueyama for (int I = 0, E = Opt.Commands.size(); I != E; ++I) 9896e68c5e5SRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get())) 990076fe157SGeorge Rimar if (Cmd->Name == Name) 991f510fa6bSRui Ueyama return I; 992f510fa6bSRui Ueyama return INT_MAX; 99371b26e94SGeorge Rimar } 99471b26e94SGeorge Rimar 995b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) { 9964595df94SRafael Espindola if (S == ".") 99772dc195dSRafael Espindola return {CurOutSec, Dot - CurOutSec->Addr}; 998a8dba487SGeorge Rimar if (SymbolBody *B = findSymbol(S)) { 99972dc195dSRafael Espindola if (auto *D = dyn_cast<DefinedRegular>(B)) 100072dc195dSRafael Espindola return {D->Section, D->Value}; 100130f16b23SPetr Hosek if (auto *C = dyn_cast<DefinedCommon>(B)) 1002a8dba487SGeorge Rimar return {InX::Common, C->Offset}; 100372dc195dSRafael Espindola } 1004f6aeed36SEugene Leviant error(Loc + ": symbol not found: " + S); 1005884e786dSGeorge Rimar return 0; 1006884e786dSGeorge Rimar } 1007884e786dSGeorge Rimar 1008b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; } 1009f34f45fdSGeorge Rimar 1010bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 1011bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 1012bbe38602SEugene Leviant // PHDRS {} script block. 1013b8dd23f5SRui Ueyama std::vector<size_t> LinkerScript::getPhdrIndices(StringRef SectionName) { 1014076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 1015076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 1016edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 101731d842f5SGeorge Rimar continue; 101831d842f5SGeorge Rimar 101929c5a2a9SRui Ueyama std::vector<size_t> Ret; 102029c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 10212a942c4bSEugene Leviant Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName)); 102229c5a2a9SRui Ueyama return Ret; 1023bbe38602SEugene Leviant } 102431d842f5SGeorge Rimar return {}; 102531d842f5SGeorge Rimar } 1026bbe38602SEugene Leviant 1027b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) { 102829c5a2a9SRui Ueyama size_t I = 0; 102929c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 103029c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 103129c5a2a9SRui Ueyama return I; 103229c5a2a9SRui Ueyama ++I; 103329c5a2a9SRui Ueyama } 10342a942c4bSEugene Leviant error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS"); 103529c5a2a9SRui Ueyama return 0; 103629c5a2a9SRui Ueyama } 103729c5a2a9SRui Ueyama 1038794366a2SRui Ueyama class elf::ScriptParser final : public ScriptLexer { 1039c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 1040c3794e58SGeorge Rimar 1041f7c5fbb1SRui Ueyama public: 104222375f24SRui Ueyama ScriptParser(MemoryBufferRef MB) 1043794366a2SRui Ueyama : ScriptLexer(MB), 104422375f24SRui Ueyama IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 1045f23b2320SGeorge Rimar 104620b6598cSGeorge Rimar void readLinkerScript(); 104720b6598cSGeorge Rimar void readVersionScript(); 1048d0ebd84cSRafael Espindola void readDynamicList(); 1049f7c5fbb1SRui Ueyama 1050f7c5fbb1SRui Ueyama private: 105152a1509eSRui Ueyama void addFile(StringRef Path); 105252a1509eSRui Ueyama 1053f7c5fbb1SRui Ueyama void readAsNeeded(); 105490c5099eSDenis Protivensky void readEntry(); 105583f406cfSGeorge Rimar void readExtern(); 1056f7c5fbb1SRui Ueyama void readGroup(); 105731aa1f83SRui Ueyama void readInclude(); 1058b889744eSMeador Inge void readMemory(); 1059ee59282bSRui Ueyama void readOutput(); 10609159ce93SDavide Italiano void readOutputArch(); 1061f7c5fbb1SRui Ueyama void readOutputFormat(); 1062bbe38602SEugene Leviant void readPhdrs(); 106368a39a65SDavide Italiano void readSearchDir(); 10648e3b38abSDenis Protivensky void readSections(); 106595769b4aSRui Ueyama void readVersion(); 106695769b4aSRui Ueyama void readVersionScriptCommand(); 10678e3b38abSDenis Protivensky 1068113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 1069e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 107016068aebSRui Ueyama uint32_t readFill(); 107110416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 107216068aebSRui Ueyama uint32_t readOutputSectionFiller(StringRef Tok); 1073bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 1074a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 1075db688454SEugene Leviant StringMatcher readFilePatterns(); 107607171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 1077a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 1078bbe38602SEugene Leviant unsigned readPhdrType(); 1079be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 1080a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 1081c96da110SRafael Espindola SymbolAssignment *readProvideOrAssignment(StringRef Tok); 108203fc010eSGeorge Rimar void readSort(); 1083eefa758eSGeorge Rimar Expr readAssert(); 1084708019c4SRui Ueyama 108524e626ccSRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 108624e626ccSRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 108724e626ccSRui Ueyama 1088708019c4SRui Ueyama Expr readExpr(); 1089708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 1090b71d6f7aSEugene Leviant StringRef readParenLiteral(); 1091708019c4SRui Ueyama Expr readPrimary(); 1092708019c4SRui Ueyama Expr readTernary(Expr Cond); 10936ad7dfccSRui Ueyama Expr readParenExpr(); 1094f7c5fbb1SRui Ueyama 109520b6598cSGeorge Rimar // For parsing version script. 109612450b20SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 109712450b20SRui Ueyama void readAnonymousDeclaration(); 109895769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 1099f5fce486SRui Ueyama 1100f5fce486SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1101f5fce486SRui Ueyama readSymbols(); 110220b6598cSGeorge Rimar 110316b0cc9eSSimon Atanasyan bool IsUnderSysroot; 1104f7c5fbb1SRui Ueyama }; 1105f7c5fbb1SRui Ueyama 1106d0ebd84cSRafael Espindola void ScriptParser::readDynamicList() { 1107d0ebd84cSRafael Espindola expect("{"); 1108d0ebd84cSRafael Espindola readAnonymousDeclaration(); 1109d0ebd84cSRafael Espindola if (!atEOF()) 1110d0ebd84cSRafael Espindola setError("EOF expected, but got " + next()); 1111d0ebd84cSRafael Espindola } 1112d0ebd84cSRafael Espindola 111320b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 111495769b4aSRui Ueyama readVersionScriptCommand(); 111520b6598cSGeorge Rimar if (!atEOF()) 111695769b4aSRui Ueyama setError("EOF expected, but got " + next()); 111795769b4aSRui Ueyama } 111895769b4aSRui Ueyama 111995769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 112083043f23SRui Ueyama if (consume("{")) { 112112450b20SRui Ueyama readAnonymousDeclaration(); 112220b6598cSGeorge Rimar return; 112320b6598cSGeorge Rimar } 112420b6598cSGeorge Rimar 112595769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 112620b6598cSGeorge Rimar StringRef VerStr = next(); 112720b6598cSGeorge Rimar if (VerStr == "{") { 112895769b4aSRui Ueyama setError("anonymous version definition is used in " 112995769b4aSRui Ueyama "combination with other version definitions"); 113020b6598cSGeorge Rimar return; 113120b6598cSGeorge Rimar } 113220b6598cSGeorge Rimar expect("{"); 113395769b4aSRui Ueyama readVersionDeclaration(VerStr); 113420b6598cSGeorge Rimar } 113520b6598cSGeorge Rimar } 113620b6598cSGeorge Rimar 113795769b4aSRui Ueyama void ScriptParser::readVersion() { 113895769b4aSRui Ueyama expect("{"); 113995769b4aSRui Ueyama readVersionScriptCommand(); 114095769b4aSRui Ueyama expect("}"); 114195769b4aSRui Ueyama } 114295769b4aSRui Ueyama 114320b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 1144f7c5fbb1SRui Ueyama while (!atEOF()) { 1145f7c5fbb1SRui Ueyama StringRef Tok = next(); 1146a27eeccaSRui Ueyama if (Tok == ";") 1147a27eeccaSRui Ueyama continue; 1148a27eeccaSRui Ueyama 114920d03194SEugene Leviant if (Tok == "ASSERT") { 1150a34da938SRui Ueyama Script->Opt.Commands.emplace_back(new AssertCommand(readAssert())); 115120d03194SEugene Leviant } else if (Tok == "ENTRY") { 1152a27eeccaSRui Ueyama readEntry(); 1153a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 1154a27eeccaSRui Ueyama readExtern(); 1155a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 1156a27eeccaSRui Ueyama readGroup(); 1157a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 1158a27eeccaSRui Ueyama readInclude(); 1159b889744eSMeador Inge } else if (Tok == "MEMORY") { 1160b889744eSMeador Inge readMemory(); 1161a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 1162a27eeccaSRui Ueyama readOutput(); 1163a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 1164a27eeccaSRui Ueyama readOutputArch(); 1165a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 1166a27eeccaSRui Ueyama readOutputFormat(); 1167a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 1168a27eeccaSRui Ueyama readPhdrs(); 1169a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 1170a27eeccaSRui Ueyama readSearchDir(); 1171a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 1172a27eeccaSRui Ueyama readSections(); 1173a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 1174a27eeccaSRui Ueyama readVersion(); 1175c96da110SRafael Espindola } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 1176a34da938SRui Ueyama Script->Opt.Commands.emplace_back(Cmd); 1177e5d3ca50SPetr Hosek } else { 11785761042dSGeorge Rimar setError("unknown directive: " + Tok); 1179f7c5fbb1SRui Ueyama } 1180f7c5fbb1SRui Ueyama } 1181e5d3ca50SPetr Hosek } 1182f7c5fbb1SRui Ueyama 1183717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 118416b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 11855af1687fSJustin Bogner SmallString<128> PathData; 11865af1687fSJustin Bogner StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 118716b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 11885af1687fSJustin Bogner Driver->addFile(Saver.save(Path)); 118916b0cc9eSSimon Atanasyan return; 119016b0cc9eSSimon Atanasyan } 119116b0cc9eSSimon Atanasyan } 119216b0cc9eSSimon Atanasyan 1193f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 119452a1509eSRui Ueyama Driver->addFile(S); 119552a1509eSRui Ueyama } else if (S.startswith("=")) { 119652a1509eSRui Ueyama if (Config->Sysroot.empty()) 119752a1509eSRui Ueyama Driver->addFile(S.substr(1)); 119852a1509eSRui Ueyama else 119952a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 120052a1509eSRui Ueyama } else if (S.startswith("-l")) { 120121eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 1202a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 1203a1b8fc3bSSimon Atanasyan Driver->addFile(S); 120452a1509eSRui Ueyama } else { 1205061f9286SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 1206061f9286SRui Ueyama Driver->addFile(Saver.save(*Path)); 1207025d59b1SRui Ueyama else 1208061f9286SRui Ueyama setError("unable to find " + S); 120952a1509eSRui Ueyama } 121052a1509eSRui Ueyama } 121152a1509eSRui Ueyama 1212717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1213f7c5fbb1SRui Ueyama expect("("); 121435da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 121535da9b6eSRui Ueyama Config->AsNeeded = true; 121683043f23SRui Ueyama while (!Error && !consume(")")) 1217cd574a5eSGeorge Rimar addFile(unquote(next())); 121835da9b6eSRui Ueyama Config->AsNeeded = Orig; 1219f7c5fbb1SRui Ueyama } 1220f7c5fbb1SRui Ueyama 1221717677afSRui Ueyama void ScriptParser::readEntry() { 122290c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 122390c5099eSDenis Protivensky expect("("); 122490c5099eSDenis Protivensky StringRef Tok = next(); 122590c5099eSDenis Protivensky if (Config->Entry.empty()) 122690c5099eSDenis Protivensky Config->Entry = Tok; 122790c5099eSDenis Protivensky expect(")"); 122890c5099eSDenis Protivensky } 122990c5099eSDenis Protivensky 1230717677afSRui Ueyama void ScriptParser::readExtern() { 123183f406cfSGeorge Rimar expect("("); 123283043f23SRui Ueyama while (!Error && !consume(")")) 1233a2acc931SRui Ueyama Config->Undefined.push_back(next()); 123483f406cfSGeorge Rimar } 123583f406cfSGeorge Rimar 1236717677afSRui Ueyama void ScriptParser::readGroup() { 1237f7c5fbb1SRui Ueyama expect("("); 123883043f23SRui Ueyama while (!Error && !consume(")")) { 1239f7c5fbb1SRui Ueyama StringRef Tok = next(); 1240a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1241f7c5fbb1SRui Ueyama readAsNeeded(); 1242a2acc931SRui Ueyama else 1243cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1244f7c5fbb1SRui Ueyama } 1245f7c5fbb1SRui Ueyama } 1246f7c5fbb1SRui Ueyama 1247717677afSRui Ueyama void ScriptParser::readInclude() { 1248d4500653SGeorge Rimar StringRef Tok = unquote(next()); 1249ec1c75e0SRui Ueyama 1250d4500653SGeorge Rimar // https://sourceware.org/binutils/docs/ld/File-Commands.html: 1251d4500653SGeorge Rimar // The file will be searched for in the current directory, and in any 1252d4500653SGeorge Rimar // directory specified with the -L option. 1253ec1c75e0SRui Ueyama if (sys::fs::exists(Tok)) { 1254ec1c75e0SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(Tok)) 1255ec1c75e0SRui Ueyama tokenize(*MB); 1256025d59b1SRui Ueyama return; 1257025d59b1SRui Ueyama } 1258ec1c75e0SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(Tok)) { 1259ec1c75e0SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(*Path)) 1260ec1c75e0SRui Ueyama tokenize(*MB); 1261ec1c75e0SRui Ueyama return; 1262ec1c75e0SRui Ueyama } 1263ec1c75e0SRui Ueyama setError("cannot open " + Tok); 126431aa1f83SRui Ueyama } 126531aa1f83SRui Ueyama 1266717677afSRui Ueyama void ScriptParser::readOutput() { 1267ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1268ee59282bSRui Ueyama expect("("); 1269ee59282bSRui Ueyama StringRef Tok = next(); 1270ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1271cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1272ee59282bSRui Ueyama expect(")"); 1273ee59282bSRui Ueyama } 1274ee59282bSRui Ueyama 1275717677afSRui Ueyama void ScriptParser::readOutputArch() { 12764e01c3e8SGeorge Rimar // OUTPUT_ARCH is ignored for now. 12779159ce93SDavide Italiano expect("("); 12784e01c3e8SGeorge Rimar while (!Error && !consume(")")) 12795424e7c7SJustin Bogner skip(); 12809159ce93SDavide Italiano } 12819159ce93SDavide Italiano 1282717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1283f7c5fbb1SRui Ueyama // Error checking only for now. 1284f7c5fbb1SRui Ueyama expect("("); 12855424e7c7SJustin Bogner skip(); 12866836c618SDavide Italiano StringRef Tok = next(); 12876836c618SDavide Italiano if (Tok == ")") 12886836c618SDavide Italiano return; 1289025d59b1SRui Ueyama if (Tok != ",") { 12905761042dSGeorge Rimar setError("unexpected token: " + Tok); 1291025d59b1SRui Ueyama return; 1292025d59b1SRui Ueyama } 12935424e7c7SJustin Bogner skip(); 12946836c618SDavide Italiano expect(","); 12955424e7c7SJustin Bogner skip(); 1296f7c5fbb1SRui Ueyama expect(")"); 1297f7c5fbb1SRui Ueyama } 1298f7c5fbb1SRui Ueyama 1299bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1300bbe38602SEugene Leviant expect("{"); 130183043f23SRui Ueyama while (!Error && !consume("}")) { 1302bbe38602SEugene Leviant StringRef Tok = next(); 1303a34da938SRui Ueyama Script->Opt.PhdrsCommands.push_back( 130456b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1305a34da938SRui Ueyama PhdrsCommand &PhdrCmd = Script->Opt.PhdrsCommands.back(); 1306bbe38602SEugene Leviant 1307bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1308bbe38602SEugene Leviant do { 1309bbe38602SEugene Leviant Tok = next(); 1310bbe38602SEugene Leviant if (Tok == ";") 1311bbe38602SEugene Leviant break; 1312bbe38602SEugene Leviant if (Tok == "FILEHDR") 1313bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1314bbe38602SEugene Leviant else if (Tok == "PHDRS") 1315bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 131656b21c86SEugene Leviant else if (Tok == "AT") 131756b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1318865bf863SEugene Leviant else if (Tok == "FLAGS") { 1319865bf863SEugene Leviant expect("("); 1320eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1321eb685cd7SRafael Espindola // we accept expressions like ".|1". 132272dc195dSRafael Espindola PhdrCmd.Flags = readExpr()().getValue(); 1323865bf863SEugene Leviant expect(")"); 1324865bf863SEugene Leviant } else 1325bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1326bbe38602SEugene Leviant } while (!Error); 1327bbe38602SEugene Leviant } 1328bbe38602SEugene Leviant } 1329bbe38602SEugene Leviant 1330717677afSRui Ueyama void ScriptParser::readSearchDir() { 133168a39a65SDavide Italiano expect("("); 133286c5fb82SRui Ueyama StringRef Tok = next(); 13336c7ad13fSRui Ueyama if (!Config->Nostdlib) 1334cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 133568a39a65SDavide Italiano expect(")"); 133668a39a65SDavide Italiano } 133768a39a65SDavide Italiano 1338717677afSRui Ueyama void ScriptParser::readSections() { 1339a34da938SRui Ueyama Script->Opt.HasSections = true; 134018a30962SGeorge Rimar // -no-rosegment is used to avoid placing read only non-executable sections in 134118a30962SGeorge Rimar // their own segment. We do the same if SECTIONS command is present in linker 134218a30962SGeorge Rimar // script. See comment for computeFlags(). 134318a30962SGeorge Rimar Config->SingleRoRx = true; 134418a30962SGeorge Rimar 13458e3b38abSDenis Protivensky expect("{"); 134683043f23SRui Ueyama while (!Error && !consume("}")) { 1347113cdec9SRui Ueyama StringRef Tok = next(); 1348c96da110SRafael Espindola BaseCommand *Cmd = readProvideOrAssignment(Tok); 1349ceabe80eSEugene Leviant if (!Cmd) { 1350ceabe80eSEugene Leviant if (Tok == "ASSERT") 1351eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1352ceabe80eSEugene Leviant else 135310416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 13548e3b38abSDenis Protivensky } 1355a34da938SRui Ueyama Script->Opt.Commands.emplace_back(Cmd); 1356652852c5SGeorge Rimar } 1357708019c4SRui Ueyama } 13588e3b38abSDenis Protivensky 1359708019c4SRui Ueyama static int precedence(StringRef Op) { 1360708019c4SRui Ueyama return StringSwitch<int>(Op) 13610120e3f2SRui Ueyama .Cases("*", "/", 5) 13620120e3f2SRui Ueyama .Cases("+", "-", 4) 13630120e3f2SRui Ueyama .Cases("<<", ">>", 3) 13649c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 13650120e3f2SRui Ueyama .Cases("&", "|", 1) 1366708019c4SRui Ueyama .Default(-1); 1367708019c4SRui Ueyama } 1368708019c4SRui Ueyama 1369db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() { 137010416564SRui Ueyama std::vector<StringRef> V; 137183043f23SRui Ueyama while (!Error && !consume(")")) 137210416564SRui Ueyama V.push_back(next()); 1373f91282e1SRui Ueyama return StringMatcher(V); 13740702c4e8SGeorge Rimar } 13750702c4e8SGeorge Rimar 1376be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 137783043f23SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 1378be394db3SGeorge Rimar return SortSectionPolicy::Name; 137983043f23SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 1380be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 138183043f23SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 1382be394db3SGeorge Rimar return SortSectionPolicy::Priority; 138383043f23SRui Ueyama if (consume("SORT_NONE")) 1384be394db3SGeorge Rimar return SortSectionPolicy::None; 1385b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1386be394db3SGeorge Rimar } 1387be394db3SGeorge Rimar 1388395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1389395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1390395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1391af03be19SGeorge Rimar // The semantics of that is next: 1392af03be19SGeorge Rimar // * Include .foo.1 from every file. 1393af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1394af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 139507171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 139607171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1397601e9898SGeorge Rimar while (!Error && peek() != ")") { 1398f91282e1SRui Ueyama StringMatcher ExcludeFilePat; 139983043f23SRui Ueyama if (consume("EXCLUDE_FILE")) { 1400395281cfSGeorge Rimar expect("("); 1401f91282e1SRui Ueyama ExcludeFilePat = readFilePatterns(); 1402395281cfSGeorge Rimar } 1403395281cfSGeorge Rimar 1404601e9898SGeorge Rimar std::vector<StringRef> V; 1405601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1406395281cfSGeorge Rimar V.push_back(next()); 1407601e9898SGeorge Rimar 1408601e9898SGeorge Rimar if (!V.empty()) 1409f91282e1SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 1410601e9898SGeorge Rimar else 1411601e9898SGeorge Rimar setError("section pattern is expected"); 1412395281cfSGeorge Rimar } 141307171f21SGeorge Rimar return Ret; 1414395281cfSGeorge Rimar } 1415395281cfSGeorge Rimar 1416f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 1417f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 1418f8f6f1e7SRui Ueyama // 1419f8f6f1e7SRui Ueyama // <patterns> ::= <section-list> 1420f8f6f1e7SRui Ueyama // | <sort> "(" <section-list> ")" 1421f8f6f1e7SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 1422f8f6f1e7SRui Ueyama // 1423f8f6f1e7SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 1424f8f6f1e7SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 1425f8f6f1e7SRui Ueyama // 1426f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 1427a2496cbeSGeorge Rimar InputSectionDescription * 1428a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1429c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 14300ed42b0cSDavide Italiano expect("("); 1431f373dd76SRui Ueyama while (!Error && !consume(")")) { 143207171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 143307171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 143407171f21SGeorge Rimar std::vector<SectionPattern> V; 143507171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 14360702c4e8SGeorge Rimar expect("("); 143707171f21SGeorge Rimar Inner = readSortKind(); 143807171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1439350ece4eSGeorge Rimar expect("("); 144007171f21SGeorge Rimar V = readInputSectionsList(); 14410702c4e8SGeorge Rimar expect(")"); 1442350ece4eSGeorge Rimar } else { 144307171f21SGeorge Rimar V = readInputSectionsList(); 1444350ece4eSGeorge Rimar } 1445350ece4eSGeorge Rimar expect(")"); 144607171f21SGeorge Rimar } else { 144707171f21SGeorge Rimar V = readInputSectionsList(); 14480659800eSGeorge Rimar } 14490702c4e8SGeorge Rimar 145007171f21SGeorge Rimar for (SectionPattern &Pat : V) { 145107171f21SGeorge Rimar Pat.SortInner = Inner; 145207171f21SGeorge Rimar Pat.SortOuter = Outer; 145307171f21SGeorge Rimar } 145407171f21SGeorge Rimar 145507171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 145607171f21SGeorge Rimar } 145710416564SRui Ueyama return Cmd; 14580659800eSGeorge Rimar } 14590659800eSGeorge Rimar 1460a2496cbeSGeorge Rimar InputSectionDescription * 1461a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 14620659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 14630659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1464a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1465e7282797SDavide Italiano expect("("); 1466a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1467a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 14680ed42b0cSDavide Italiano expect(")"); 1469a34da938SRui Ueyama Script->Opt.KeptSections.push_back(Cmd); 147010416564SRui Ueyama return Cmd; 147110416564SRui Ueyama } 1472a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 14730659800eSGeorge Rimar } 14740659800eSGeorge Rimar 147503fc010eSGeorge Rimar void ScriptParser::readSort() { 147603fc010eSGeorge Rimar expect("("); 147703fc010eSGeorge Rimar expect("CONSTRUCTORS"); 147803fc010eSGeorge Rimar expect(")"); 147903fc010eSGeorge Rimar } 148003fc010eSGeorge Rimar 1481eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1482eefa758eSGeorge Rimar expect("("); 1483eefa758eSGeorge Rimar Expr E = readExpr(); 1484eefa758eSGeorge Rimar expect(","); 1485cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1486eefa758eSGeorge Rimar expect(")"); 14874595df94SRafael Espindola return [=] { 148872dc195dSRafael Espindola if (!E().getValue()) 1489eefa758eSGeorge Rimar error(Msg); 1490a8dba487SGeorge Rimar return Script->getDot(); 1491eefa758eSGeorge Rimar }; 1492eefa758eSGeorge Rimar } 1493eefa758eSGeorge Rimar 149425150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 149525150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 149625150e8bSRui Ueyama // what GNU linkers do. 149725150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 149816068aebSRui Ueyama uint32_t ScriptParser::readFill() { 1499ff1f29e0SGeorge Rimar expect("("); 150016068aebSRui Ueyama uint32_t V = readOutputSectionFiller(next()); 1501ff1f29e0SGeorge Rimar expect(")"); 1502ff1f29e0SGeorge Rimar expect(";"); 1503ff1f29e0SGeorge Rimar return V; 1504ff1f29e0SGeorge Rimar } 1505ff1f29e0SGeorge Rimar 150610416564SRui Ueyama OutputSectionCommand * 150710416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1508076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 15092a942c4bSEugene Leviant Cmd->Location = getCurrentLocation(); 151058e5c4dcSGeorge Rimar 151158e5c4dcSGeorge Rimar // Read an address expression. 151258e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 151358e5c4dcSGeorge Rimar if (peek() != ":") 151458e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 151558e5c4dcSGeorge Rimar 15168e3b38abSDenis Protivensky expect(":"); 1517246f681eSDavide Italiano 151883043f23SRui Ueyama if (consume("AT")) 1519b71d6f7aSEugene Leviant Cmd->LMAExpr = readParenExpr(); 152083043f23SRui Ueyama if (consume("ALIGN")) 15216ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 152283043f23SRui Ueyama if (consume("SUBALIGN")) 1523db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1524630c6179SGeorge Rimar 1525246f681eSDavide Italiano // Parse constraints. 152683043f23SRui Ueyama if (consume("ONLY_IF_RO")) 1527efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 152883043f23SRui Ueyama if (consume("ONLY_IF_RW")) 1529efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 15308e3b38abSDenis Protivensky expect("{"); 15318ec77e64SRui Ueyama 153283043f23SRui Ueyama while (!Error && !consume("}")) { 1533ceabe80eSEugene Leviant StringRef Tok = next(); 15342fe07923SGeorge Rimar if (Tok == ";") { 153569750755SGeorge Rimar // Empty commands are allowed. Do nothing here. 15362fe07923SGeorge Rimar } else if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) { 1537ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1538b2d99d6aSMeador Inge } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) { 1539e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1540b2d99d6aSMeador Inge } else if (Tok == "ASSERT") { 1541b2d99d6aSMeador Inge Cmd->Commands.emplace_back(new AssertCommand(readAssert())); 1542b2d99d6aSMeador Inge expect(";"); 15438e2eca22SGeorge Rimar } else if (Tok == "CONSTRUCTORS") { 15448e2eca22SGeorge Rimar // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 15458e2eca22SGeorge Rimar // by name. This is for very old file formats such as ECOFF/XCOFF. 15468e2eca22SGeorge Rimar // For ELF, we should ignore. 1547b2d99d6aSMeador Inge } else if (Tok == "FILL") { 1548ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1549b2d99d6aSMeador Inge } else if (Tok == "SORT") { 155003fc010eSGeorge Rimar readSort(); 1551b2d99d6aSMeador Inge } else if (peek() == "(") { 1552a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1553b2d99d6aSMeador Inge } else { 1554ceabe80eSEugene Leviant setError("unknown command " + Tok); 15558e3b38abSDenis Protivensky } 1556b2d99d6aSMeador Inge } 1557b889744eSMeador Inge 1558b889744eSMeador Inge if (consume(">")) 1559b889744eSMeador Inge Cmd->MemoryRegionName = next(); 1560b889744eSMeador Inge 1561076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 15624ebc5620SGeorge Rimar 156383043f23SRui Ueyama if (consume("=")) 15644ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 15654ebc5620SGeorge Rimar else if (peek().startswith("=")) 1566ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 15674ebc5620SGeorge Rimar 15687185a1acSGeorge Rimar // Consume optional comma following output section command. 15697185a1acSGeorge Rimar consume(","); 15707185a1acSGeorge Rimar 157110416564SRui Ueyama return Cmd; 1572f71caa2bSRui Ueyama } 15738ec77e64SRui Ueyama 15742c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 15752c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 15762c8f1f04SRui Ueyama // 15772c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 15782c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 15792c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 15802c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 158116068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) { 1582965827d6SRui Ueyama uint32_t V; 158316068aebSRui Ueyama if (!Tok.getAsInteger(0, V)) 158416068aebSRui Ueyama return V; 1585965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 158616068aebSRui Ueyama return 0; 15878e3b38abSDenis Protivensky } 15888e3b38abSDenis Protivensky 1589a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1590a31c91b1SEugene Leviant expect("("); 1591174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1592a35e39caSPetr Hosek Cmd->Provide = Provide; 1593174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1594a31c91b1SEugene Leviant expect(")"); 1595a31c91b1SEugene Leviant expect(";"); 159610416564SRui Ueyama return Cmd; 1597eda81a1bSEugene Leviant } 1598eda81a1bSEugene Leviant 1599c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1600ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1601ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1602ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1603ceabe80eSEugene Leviant expect(";"); 1604ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1605a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1606a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1607a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1608ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1609a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1610ceabe80eSEugene Leviant } 1611ceabe80eSEugene Leviant return Cmd; 1612ceabe80eSEugene Leviant } 1613ceabe80eSEugene Leviant 161430835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 161530835ea4SGeorge Rimar StringRef Op = next(); 161630835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 161702ad516bSPetr Hosek Expr E = readExpr(); 1618f6aeed36SEugene Leviant if (Op == "+=") { 1619f6aeed36SEugene Leviant std::string Loc = getCurrentLocation(); 1620a8dba487SGeorge Rimar E = [=] { return add(Script->getSymbolValue(Loc, Name), E()); }; 1621f6aeed36SEugene Leviant } 16222ee2d2dcSGeorge Rimar return new SymbolAssignment(Name, E, getCurrentLocation()); 162330835ea4SGeorge Rimar } 162430835ea4SGeorge Rimar 162530835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 162630835ea4SGeorge Rimar // script expression. 1627731a66aeSRui Ueyama Expr ScriptParser::readExpr() { 1628731a66aeSRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 1629731a66aeSRui Ueyama // they apply different tokenization rules. 1630731a66aeSRui Ueyama bool Orig = InExpr; 1631731a66aeSRui Ueyama InExpr = true; 1632731a66aeSRui Ueyama Expr E = readExpr1(readPrimary(), 0); 1633731a66aeSRui Ueyama InExpr = Orig; 1634731a66aeSRui Ueyama return E; 1635731a66aeSRui Ueyama } 163630835ea4SGeorge Rimar 163736c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 163836c1cd23SRui Ueyama if (Op == "*") 163972dc195dSRafael Espindola return [=] { return mul(L(), R()); }; 164036c1cd23SRui Ueyama if (Op == "/") { 164172dc195dSRafael Espindola return [=] { return div(L(), R()); }; 164236c1cd23SRui Ueyama } 164336c1cd23SRui Ueyama if (Op == "+") 164472dc195dSRafael Espindola return [=] { return add(L(), R()); }; 164536c1cd23SRui Ueyama if (Op == "-") 164672dc195dSRafael Espindola return [=] { return sub(L(), R()); }; 1647c8ccd1f1SGeorge Rimar if (Op == "<<") 164872dc195dSRafael Espindola return [=] { return leftShift(L(), R()); }; 1649c8ccd1f1SGeorge Rimar if (Op == ">>") 165072dc195dSRafael Espindola return [=] { return rightShift(L(), R()); }; 165136c1cd23SRui Ueyama if (Op == "<") 1652195f23c5SRafael Espindola return [=] { return L().getValue() < R().getValue(); }; 165336c1cd23SRui Ueyama if (Op == ">") 1654195f23c5SRafael Espindola return [=] { return L().getValue() > R().getValue(); }; 165536c1cd23SRui Ueyama if (Op == ">=") 1656195f23c5SRafael Espindola return [=] { return L().getValue() >= R().getValue(); }; 165736c1cd23SRui Ueyama if (Op == "<=") 1658195f23c5SRafael Espindola return [=] { return L().getValue() <= R().getValue(); }; 165936c1cd23SRui Ueyama if (Op == "==") 1660195f23c5SRafael Espindola return [=] { return L().getValue() == R().getValue(); }; 166136c1cd23SRui Ueyama if (Op == "!=") 1662195f23c5SRafael Espindola return [=] { return L().getValue() != R().getValue(); }; 166336c1cd23SRui Ueyama if (Op == "&") 166472dc195dSRafael Espindola return [=] { return bitAnd(L(), R()); }; 1665cc3dd629SRafael Espindola if (Op == "|") 166672dc195dSRafael Espindola return [=] { return bitOr(L(), R()); }; 166736c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 166836c1cd23SRui Ueyama } 166936c1cd23SRui Ueyama 1670708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1671708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1672708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1673708019c4SRui Ueyama while (!atEOF() && !Error) { 1674708019c4SRui Ueyama // Read an operator and an expression. 167546247b85SRui Ueyama if (consume("?")) 1676708019c4SRui Ueyama return readTernary(Lhs); 167746247b85SRui Ueyama StringRef Op1 = peek(); 1678708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1679a31c91b1SEugene Leviant break; 16805424e7c7SJustin Bogner skip(); 1681708019c4SRui Ueyama Expr Rhs = readPrimary(); 1682708019c4SRui Ueyama 1683708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1684708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1685708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1686708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1687708019c4SRui Ueyama while (!atEOF()) { 1688708019c4SRui Ueyama StringRef Op2 = peek(); 1689708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1690eda81a1bSEugene Leviant break; 1691708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1692eda81a1bSEugene Leviant } 1693708019c4SRui Ueyama 1694708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1695708019c4SRui Ueyama } 1696708019c4SRui Ueyama return Lhs; 1697708019c4SRui Ueyama } 1698708019c4SRui Ueyama 1699708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1700e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1701708019c4SRui Ueyama return Target->PageSize; 1702e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1703997f8838SPetr Hosek return Config->MaxPageSize; 1704708019c4SRui Ueyama error("unknown constant: " + S); 1705708019c4SRui Ueyama return 0; 1706708019c4SRui Ueyama } 1707708019c4SRui Ueyama 1708626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1709626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1710626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1711626e0b08SRui Ueyama // "M" (mega) prefixes. 17129f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 171346247b85SRui Ueyama // Negative number 1714eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1715eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1716eaeafb2bSSimon Atanasyan return false; 1717eaeafb2bSSimon Atanasyan Result = -Result; 1718eaeafb2bSSimon Atanasyan return true; 1719eaeafb2bSSimon Atanasyan } 172046247b85SRui Ueyama 172146247b85SRui Ueyama // Hexadecimal 17229f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 17239f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 17249f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 17259f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 17269f2f7ad9SGeorge Rimar 172746247b85SRui Ueyama // Decimal 17289f2f7ad9SGeorge Rimar int Suffix = 1; 17299f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 17309f2f7ad9SGeorge Rimar Suffix = 1024; 17319f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 17329f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 17339f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 17349f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 17359f2f7ad9SGeorge Rimar } 17369f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 17379f2f7ad9SGeorge Rimar return false; 17389f2f7ad9SGeorge Rimar Result *= Suffix; 17399f2f7ad9SGeorge Rimar return true; 17409f2f7ad9SGeorge Rimar } 17419f2f7ad9SGeorge Rimar 1742e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1743e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1744e38cbab5SGeorge Rimar .Case("BYTE", 1) 1745e38cbab5SGeorge Rimar .Case("SHORT", 2) 1746e38cbab5SGeorge Rimar .Case("LONG", 4) 1747e38cbab5SGeorge Rimar .Case("QUAD", 8) 1748e38cbab5SGeorge Rimar .Default(-1); 1749e38cbab5SGeorge Rimar if (Size == -1) 1750e38cbab5SGeorge Rimar return nullptr; 1751e38cbab5SGeorge Rimar 175295c7d8d2SMeador Inge return new BytesDataCommand(readParenExpr(), Size); 1753e38cbab5SGeorge Rimar } 1754e38cbab5SGeorge Rimar 1755b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() { 1756b71d6f7aSEugene Leviant expect("("); 1757b71d6f7aSEugene Leviant StringRef Tok = next(); 1758b71d6f7aSEugene Leviant expect(")"); 1759b71d6f7aSEugene Leviant return Tok; 1760b71d6f7aSEugene Leviant } 1761b71d6f7aSEugene Leviant 1762708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 17636ad7dfccSRui Ueyama if (peek() == "(") 17646ad7dfccSRui Ueyama return readParenExpr(); 1765708019c4SRui Ueyama 17666ad7dfccSRui Ueyama StringRef Tok = next(); 1767b5f1c3ecSRui Ueyama std::string Location = getCurrentLocation(); 1768708019c4SRui Ueyama 1769eaeafb2bSSimon Atanasyan if (Tok == "~") { 1770eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 177172dc195dSRafael Espindola return [=] { return bitNot(E()); }; 1772eaeafb2bSSimon Atanasyan } 1773eaeafb2bSSimon Atanasyan if (Tok == "-") { 1774eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 177572dc195dSRafael Espindola return [=] { return minus(E()); }; 1776eaeafb2bSSimon Atanasyan } 1777eaeafb2bSSimon Atanasyan 1778708019c4SRui Ueyama // Built-in functions are parsed here. 1779708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 178002ad516bSPetr Hosek if (Tok == "ABSOLUTE") { 178172dc195dSRafael Espindola Expr Inner = readParenExpr(); 178272dc195dSRafael Espindola return [=] { 178372dc195dSRafael Espindola ExprValue I = Inner(); 178472dc195dSRafael Espindola I.ForceAbsolute = true; 178572dc195dSRafael Espindola return I; 178672dc195dSRafael Espindola }; 178702ad516bSPetr Hosek } 178896659df0SGeorge Rimar if (Tok == "ADDR") { 1789b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 179072dc195dSRafael Espindola return [=]() -> ExprValue { 1791a8dba487SGeorge Rimar return {Script->getOutputSection(Location, Name), 0}; 179272dc195dSRafael Espindola }; 179396659df0SGeorge Rimar } 1794708019c4SRui Ueyama if (Tok == "ALIGN") { 17955d804dc8SRui Ueyama expect("("); 17965d804dc8SRui Ueyama Expr E = readExpr(); 17975d804dc8SRui Ueyama if (consume(",")) { 17985d804dc8SRui Ueyama Expr E2 = readExpr(); 17995d804dc8SRui Ueyama expect(")"); 180072dc195dSRafael Espindola return [=] { return alignTo(E().getValue(), E2().getValue()); }; 18015d804dc8SRui Ueyama } 18025d804dc8SRui Ueyama expect(")"); 1803a8dba487SGeorge Rimar return [=] { return alignTo(Script->getDot(), E().getValue()); }; 1804708019c4SRui Ueyama } 1805fc16173cSRui Ueyama if (Tok == "ALIGNOF") { 1806fc16173cSRui Ueyama StringRef Name = readParenLiteral(); 1807fc16173cSRui Ueyama return [=] { return Script->getOutputSection(Location, Name)->Alignment; }; 1808fc16173cSRui Ueyama } 1809fc16173cSRui Ueyama if (Tok == "ASSERT") 1810fc16173cSRui Ueyama return readAssert(); 1811708019c4SRui Ueyama if (Tok == "CONSTANT") { 1812b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 18134595df94SRafael Espindola return [=] { return getConstant(Name); }; 1814708019c4SRui Ueyama } 1815708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1816708019c4SRui Ueyama expect("("); 1817708019c4SRui Ueyama Expr E = readExpr(); 1818708019c4SRui Ueyama expect(","); 1819708019c4SRui Ueyama readExpr(); 1820708019c4SRui Ueyama expect(")"); 1821a8dba487SGeorge Rimar return [=] { return alignTo(Script->getDot(), E().getValue()); }; 1822708019c4SRui Ueyama } 1823708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1824708019c4SRui Ueyama expect("("); 1825708019c4SRui Ueyama expect("."); 1826708019c4SRui Ueyama expect(")"); 1827a8dba487SGeorge Rimar return [] { return Script->getDot(); }; 1828708019c4SRui Ueyama } 1829276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1830fc16173cSRui Ueyama // GNU linkers implements more complicated logic to handle 1831fc16173cSRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 1832fc16173cSRui Ueyama // just align to the next page boundary for simplicity. 1833276b4e64SGeorge Rimar expect("("); 183497bdc722SRafael Espindola readExpr(); 1835276b4e64SGeorge Rimar expect(","); 1836276b4e64SGeorge Rimar readExpr(); 1837276b4e64SGeorge Rimar expect(")"); 1838a8dba487SGeorge Rimar return [] { return alignTo(Script->getDot(), Target->PageSize); }; 1839276b4e64SGeorge Rimar } 1840fc16173cSRui Ueyama if (Tok == "DEFINED") { 1841fc16173cSRui Ueyama StringRef Name = readParenLiteral(); 1842fc16173cSRui Ueyama return [=] { return Script->isDefined(Name) ? 1 : 0; }; 1843fc16173cSRui Ueyama } 1844fc16173cSRui Ueyama if (Tok == "LOADADDR") { 1845fc16173cSRui Ueyama StringRef Name = readParenLiteral(); 1846fc16173cSRui Ueyama return [=] { return Script->getOutputSection(Location, Name)->getLMA(); }; 1847fc16173cSRui Ueyama } 1848fc16173cSRui Ueyama if (Tok == "SEGMENT_START") { 1849fc16173cSRui Ueyama expect("("); 1850fc16173cSRui Ueyama skip(); 1851fc16173cSRui Ueyama expect(","); 1852fc16173cSRui Ueyama Expr E = readExpr(); 1853fc16173cSRui Ueyama expect(")"); 1854fc16173cSRui Ueyama return [=] { return E(); }; 1855fc16173cSRui Ueyama } 18569e69450eSGeorge Rimar if (Tok == "SIZEOF") { 1857b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1858a8dba487SGeorge Rimar return [=] { return Script->getOutputSectionSize(Name); }; 18599e69450eSGeorge Rimar } 1860e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 186178aa2700SGeorge Rimar return [=] { return elf::getHeaderSize(); }; 1862708019c4SRui Ueyama 18639f2f7ad9SGeorge Rimar // Tok is a literal number. 18649f2f7ad9SGeorge Rimar uint64_t V; 18659f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 18664595df94SRafael Espindola return [=] { return V; }; 18679f2f7ad9SGeorge Rimar 18689f2f7ad9SGeorge Rimar // Tok is a symbol name. 186930f16b23SPetr Hosek if (Tok != ".") { 187030f16b23SPetr Hosek if (!isValidCIdentifier(Tok)) 1871708019c4SRui Ueyama setError("malformed number: " + Tok); 187230f16b23SPetr Hosek Script->Opt.UndefinedSymbols.push_back(Tok); 187330f16b23SPetr Hosek } 1874a8dba487SGeorge Rimar return [=] { return Script->getSymbolValue(Location, Tok); }; 1875a9c5a528SGeorge Rimar } 1876708019c4SRui Ueyama 1877708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1878708019c4SRui Ueyama Expr L = readExpr(); 1879708019c4SRui Ueyama expect(":"); 1880708019c4SRui Ueyama Expr R = readExpr(); 188172dc195dSRafael Espindola return [=] { return Cond().getValue() ? L() : R(); }; 1882708019c4SRui Ueyama } 1883708019c4SRui Ueyama 18846ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 18856ad7dfccSRui Ueyama expect("("); 18866ad7dfccSRui Ueyama Expr E = readExpr(); 18876ad7dfccSRui Ueyama expect(")"); 18886ad7dfccSRui Ueyama return E; 18896ad7dfccSRui Ueyama } 18906ad7dfccSRui Ueyama 1891bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1892bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1893bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1894bbe38602SEugene Leviant StringRef Tok = next(); 1895da841c16SGeorge Rimar Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 1896bbe38602SEugene Leviant } 1897bbe38602SEugene Leviant return Phdrs; 1898bbe38602SEugene Leviant } 1899bbe38602SEugene Leviant 190095dd718cSGeorge Rimar // Read a program header type name. The next token must be a 190195dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3"). 1902bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1903bbe38602SEugene Leviant StringRef Tok = next(); 190495dd718cSGeorge Rimar uint64_t Val; 190595dd718cSGeorge Rimar if (readInteger(Tok, Val)) 190695dd718cSGeorge Rimar return Val; 190795dd718cSGeorge Rimar 1908b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1909b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1910b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1911b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1912b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1913b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1914b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1915b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1916b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1917b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1918b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1919b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1920270173f2SGeorge Rimar .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1921cc6e567cSGeorge Rimar .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1922a2a32c2cSGeorge Rimar .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 1923b0f6c590SRui Ueyama .Default(-1); 1924bbe38602SEugene Leviant 1925b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1926b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1927b0f6c590SRui Ueyama return PT_NULL; 1928b0f6c590SRui Ueyama } 1929b0f6c590SRui Ueyama return Ret; 1930bbe38602SEugene Leviant } 1931bbe38602SEugene Leviant 1932f5fce486SRui Ueyama // Reads an anonymous version declaration. 193312450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 1934f5fce486SRui Ueyama std::vector<SymbolVersion> Locals; 1935f5fce486SRui Ueyama std::vector<SymbolVersion> Globals; 1936f5fce486SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 1937f5fce486SRui Ueyama 1938f5fce486SRui Ueyama for (SymbolVersion V : Locals) { 1939f5fce486SRui Ueyama if (V.Name == "*") 1940f5fce486SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 1941f5fce486SRui Ueyama else 1942f5fce486SRui Ueyama Config->VersionScriptLocals.push_back(V); 19434524268cSRafael Espindola } 1944f5fce486SRui Ueyama 1945f5fce486SRui Ueyama for (SymbolVersion V : Globals) 1946f5fce486SRui Ueyama Config->VersionScriptGlobals.push_back(V); 1947f5fce486SRui Ueyama 194812450b20SRui Ueyama expect(";"); 194912450b20SRui Ueyama } 195012450b20SRui Ueyama 1951f5fce486SRui Ueyama // Reads a non-anonymous version definition, 1952f5fce486SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };". 1953f5fce486SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 1954f5fce486SRui Ueyama // Read a symbol list. 1955f5fce486SRui Ueyama std::vector<SymbolVersion> Locals; 1956f5fce486SRui Ueyama std::vector<SymbolVersion> Globals; 1957f5fce486SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 1958f5fce486SRui Ueyama 1959e999ddb8SRafael Espindola for (SymbolVersion V : Locals) { 1960f5fce486SRui Ueyama if (V.Name == "*") 1961e999ddb8SRafael Espindola Config->DefaultSymbolVersion = VER_NDX_LOCAL; 1962f5fce486SRui Ueyama else 1963e999ddb8SRafael Espindola Config->VersionScriptLocals.push_back(V); 1964e999ddb8SRafael Espindola } 1965e999ddb8SRafael Espindola 1966f5fce486SRui Ueyama // Create a new version definition and add that to the global symbols. 1967f5fce486SRui Ueyama VersionDefinition Ver; 1968f5fce486SRui Ueyama Ver.Name = VerStr; 1969f5fce486SRui Ueyama Ver.Globals = Globals; 197020b6598cSGeorge Rimar 1971f5fce486SRui Ueyama // User-defined version number starts from 2 because 0 and 1 are 1972f5fce486SRui Ueyama // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. 1973f5fce486SRui Ueyama Ver.Id = Config->VersionDefinitions.size() + 2; 1974f5fce486SRui Ueyama Config->VersionDefinitions.push_back(Ver); 197520b6598cSGeorge Rimar 197612450b20SRui Ueyama // Each version may have a parent version. For example, "Ver2" 197712450b20SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 197812450b20SRui Ueyama // as a parent. This version hierarchy is, probably against your 197912450b20SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 198012450b20SRui Ueyama // at all. In LLD, we simply ignore it. 198112450b20SRui Ueyama if (peek() != ";") 19825424e7c7SJustin Bogner skip(); 198320b6598cSGeorge Rimar expect(";"); 198420b6598cSGeorge Rimar } 198520b6598cSGeorge Rimar 1986f5fce486SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 1987f5fce486SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1988f5fce486SRui Ueyama ScriptParser::readSymbols() { 1989f5fce486SRui Ueyama std::vector<SymbolVersion> Locals; 1990f5fce486SRui Ueyama std::vector<SymbolVersion> Globals; 1991f5fce486SRui Ueyama std::vector<SymbolVersion> *V = &Globals; 1992f5fce486SRui Ueyama 1993f5fce486SRui Ueyama while (!Error) { 1994f5fce486SRui Ueyama if (consume("}")) 1995f5fce486SRui Ueyama break; 1996f5fce486SRui Ueyama if (consumeLabel("local")) { 1997f5fce486SRui Ueyama V = &Locals; 1998f5fce486SRui Ueyama continue; 1999f5fce486SRui Ueyama } 2000f5fce486SRui Ueyama if (consumeLabel("global")) { 2001f5fce486SRui Ueyama V = &Globals; 20021ef90d2fSRafael Espindola continue; 20031ef90d2fSRafael Espindola } 2004e0fc2421SGeorge Rimar 2005f5fce486SRui Ueyama if (consume("extern")) { 2006f5fce486SRui Ueyama std::vector<SymbolVersion> Ext = readVersionExtern(); 2007f5fce486SRui Ueyama V->insert(V->end(), Ext.begin(), Ext.end()); 2008f5fce486SRui Ueyama } else { 20090ee25a69SRui Ueyama StringRef Tok = next(); 2010f5fce486SRui Ueyama V->push_back({unquote(Tok), false, hasWildcard(Tok)}); 2011f5fce486SRui Ueyama } 2012e0fc2421SGeorge Rimar expect(";"); 2013e0fc2421SGeorge Rimar } 2014f5fce486SRui Ueyama return {Locals, Globals}; 2015e0fc2421SGeorge Rimar } 2016e0fc2421SGeorge Rimar 201712450b20SRui Ueyama // Reads an "extern C++" directive, e.g., 201812450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 201912450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 20207e71415cSRafael Espindola StringRef Tok = next(); 20217e71415cSRafael Espindola bool IsCXX = Tok == "\"C++\""; 20227e71415cSRafael Espindola if (!IsCXX && Tok != "\"C\"") 2023d0ebd84cSRafael Espindola setError("Unknown language"); 202420b6598cSGeorge Rimar expect("{"); 202520b6598cSGeorge Rimar 202612450b20SRui Ueyama std::vector<SymbolVersion> Ret; 20270ee25a69SRui Ueyama while (!Error && peek() != "}") { 20280ee25a69SRui Ueyama StringRef Tok = next(); 20290ee25a69SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 20307e71415cSRafael Espindola Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 203120b6598cSGeorge Rimar expect(";"); 203220b6598cSGeorge Rimar } 203320b6598cSGeorge Rimar 203420b6598cSGeorge Rimar expect("}"); 203512450b20SRui Ueyama return Ret; 203620b6598cSGeorge Rimar } 203720b6598cSGeorge Rimar 2038009833d3SGeorge Rimar uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, 2039009833d3SGeorge Rimar StringRef S3) { 204024e626ccSRui Ueyama if (!(consume(S1) || consume(S2) || consume(S3))) { 204124e626ccSRui Ueyama setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 204224e626ccSRui Ueyama return 0; 204324e626ccSRui Ueyama } 204424e626ccSRui Ueyama expect("="); 204524e626ccSRui Ueyama 204624e626ccSRui Ueyama // TODO: Fully support constant expressions. 204724e626ccSRui Ueyama uint64_t Val; 204824e626ccSRui Ueyama if (!readInteger(next(), Val)) 204924e626ccSRui Ueyama setError("nonconstant expression for " + S1); 205024e626ccSRui Ueyama return Val; 205124e626ccSRui Ueyama } 205224e626ccSRui Ueyama 205324e626ccSRui Ueyama // Parse the MEMORY command as specified in: 205424e626ccSRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 205524e626ccSRui Ueyama // 205624e626ccSRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 2057b889744eSMeador Inge void ScriptParser::readMemory() { 2058b889744eSMeador Inge expect("{"); 2059b889744eSMeador Inge while (!Error && !consume("}")) { 2060b889744eSMeador Inge StringRef Name = next(); 206124e626ccSRui Ueyama 2062b889744eSMeador Inge uint32_t Flags = 0; 20638a8a953eSRui Ueyama uint32_t NegFlags = 0; 2064b889744eSMeador Inge if (consume("(")) { 20658a8a953eSRui Ueyama std::tie(Flags, NegFlags) = readMemoryAttributes(); 2066b889744eSMeador Inge expect(")"); 2067b889744eSMeador Inge } 2068b889744eSMeador Inge expect(":"); 2069b889744eSMeador Inge 207024e626ccSRui Ueyama uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 2071b889744eSMeador Inge expect(","); 207224e626ccSRui Ueyama uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 2073b889744eSMeador Inge 2074b889744eSMeador Inge // Add the memory region to the region map (if it doesn't already exist). 2075a34da938SRui Ueyama auto It = Script->Opt.MemoryRegions.find(Name); 2076a34da938SRui Ueyama if (It != Script->Opt.MemoryRegions.end()) 2077b889744eSMeador Inge setError("region '" + Name + "' already defined"); 2078b889744eSMeador Inge else 2079a34da938SRui Ueyama Script->Opt.MemoryRegions[Name] = {Name, Origin, Length, 2080a34da938SRui Ueyama Origin, Flags, NegFlags}; 2081b889744eSMeador Inge } 2082b889744eSMeador Inge } 2083b889744eSMeador Inge 2084b889744eSMeador Inge // This function parses the attributes used to match against section 2085b889744eSMeador Inge // flags when placing output sections in a memory region. These flags 2086b889744eSMeador Inge // are only used when an explicit memory region name is not used. 2087b889744eSMeador Inge std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 2088b889744eSMeador Inge uint32_t Flags = 0; 20898a8a953eSRui Ueyama uint32_t NegFlags = 0; 2090b889744eSMeador Inge bool Invert = false; 2091481ac996SRui Ueyama 2092481ac996SRui Ueyama for (char C : next().lower()) { 2093b889744eSMeador Inge uint32_t Flag = 0; 2094b889744eSMeador Inge if (C == '!') 2095b889744eSMeador Inge Invert = !Invert; 2096481ac996SRui Ueyama else if (C == 'w') 2097b889744eSMeador Inge Flag = SHF_WRITE; 2098481ac996SRui Ueyama else if (C == 'x') 2099b889744eSMeador Inge Flag = SHF_EXECINSTR; 2100481ac996SRui Ueyama else if (C == 'a') 2101b889744eSMeador Inge Flag = SHF_ALLOC; 2102481ac996SRui Ueyama else if (C != 'r') 2103b889744eSMeador Inge setError("invalid memory region attribute"); 2104481ac996SRui Ueyama 2105b889744eSMeador Inge if (Invert) 21068a8a953eSRui Ueyama NegFlags |= Flag; 2107b889744eSMeador Inge else 2108b889744eSMeador Inge Flags |= Flag; 2109b889744eSMeador Inge } 21108a8a953eSRui Ueyama return {Flags, NegFlags}; 2111b889744eSMeador Inge } 2112b889744eSMeador Inge 211307320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 211422375f24SRui Ueyama ScriptParser(MB).readLinkerScript(); 211520b6598cSGeorge Rimar } 211620b6598cSGeorge Rimar 211720b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 211822375f24SRui Ueyama ScriptParser(MB).readVersionScript(); 2119f7c5fbb1SRui Ueyama } 21201ebc8ed7SRui Ueyama 2121d0ebd84cSRafael Espindola void elf::readDynamicList(MemoryBufferRef MB) { 2122d0ebd84cSRafael Espindola ScriptParser(MB).readDynamicList(); 2123d0ebd84cSRafael Espindola } 2124