diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-06-01 01:16:50 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-06-01 01:16:50 +0000 |
| commit | 05c4f67cf3e99a897077595626261ec44c40f99e (patch) | |
| tree | 1581a8e46be937ad0bdcd50dc61091f211e97069 /lld/ELF/LinkerScript.cpp | |
| parent | 050e79e958caa6583af15dae5768d9894e62e1c5 (diff) | |
| download | bcm5719-llvm-05c4f67cf3e99a897077595626261ec44c40f99e.tar.gz bcm5719-llvm-05c4f67cf3e99a897077595626261ec44c40f99e.zip | |
Move name lookup to script parsing time.
We were looking up sections by name during expression evaluation. By
keeping track of forward declarations we can do the lookup during
script parsing.
Doing the lookup earlier will be more efficient when assignAddresses
is run twice and removes two uses of OutputSections.
llvm-svn: 304381
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index eecbe9cef18..ec3f282e565 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -84,29 +84,28 @@ template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) { return Sym->body(); } -OutputSection *LinkerScript::getOutputSection(const Twine &Loc, - StringRef Name) { - for (OutputSection *Sec : *OutputSections) - if (Sec->Name == Name) - return Sec; - - static OutputSection Dummy("", 0, 0); - if (ErrorOnMissingSection) - error(Loc + ": undefined section " + Name); - return &Dummy; +OutputSectionCommand * +LinkerScript::createOutputSectionCommand(StringRef Name, StringRef Location) { + OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name]; + OutputSectionCommand *Cmd; + if (CmdRef && CmdRef->Location.empty()) { + // There was a forward reference. + Cmd = CmdRef; + } else { + Cmd = make<OutputSectionCommand>(Name); + if (!CmdRef) + CmdRef = Cmd; + } + Cmd->Location = Location; + return Cmd; } -// This function is essentially the same as getOutputSection(Name)->Size, -// but it won't print out an error message if a given section is not found. -// -// Linker script does not create an output section if its content is empty. -// We want to allow SIZEOF(.foo) where .foo is a section which happened to -// be empty. That is why this function is different from getOutputSection(). -uint64_t LinkerScript::getOutputSectionSize(StringRef Name) { - for (OutputSection *Sec : *OutputSections) - if (Sec->Name == Name) - return Sec->Size; - return 0; +OutputSectionCommand * +LinkerScript::getOrCreateOutputSectionCommand(StringRef Name) { + OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name]; + if (!CmdRef) + CmdRef = make<OutputSectionCommand>(Name); + return CmdRef; } void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { @@ -456,7 +455,7 @@ void LinkerScript::fabricateDefaultCommands() { // For each OutputSection that needs a VA fabricate an OutputSectionCommand // with an InputSectionDescription describing the InputSections for (OutputSection *Sec : *OutputSections) { - auto *OSCmd = make<OutputSectionCommand>(Sec->Name); + auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>"); OSCmd->Sec = Sec; SecToCommand[Sec] = OSCmd; @@ -843,7 +842,7 @@ void LinkerScript::placeOrphanSections() { // representations agree on which input sections to use. OutputSectionCommand *Cmd = getCmd(Sec); if (!Cmd) { - Cmd = make<OutputSectionCommand>(Name); + Cmd = createOutputSectionCommand(Name, "<internal>"); Opt.Commands.insert(CmdIter, Cmd); ++CmdIndex; |

