diff options
author | Rui Ueyama <ruiu@google.com> | 2016-02-12 21:47:28 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2016-02-12 21:47:28 +0000 |
commit | 1ebc8ed78ac5df1ad5ba68eb8d8974c1cea1bffa (patch) | |
tree | 76d7ab09c995345f315b6b62ce3a2a43c789d31b /lld/ELF/Writer.cpp | |
parent | 595c13771d4bfdeea5f2e95a0bc82c5049f65f11 (diff) | |
download | bcm5719-llvm-1ebc8ed78ac5df1ad5ba68eb8d8974c1cea1bffa.tar.gz bcm5719-llvm-1ebc8ed78ac5df1ad5ba68eb8d8974c1cea1bffa.zip |
ELF: Add wildcard pattern matching to SECTIONS linker script command.
Each rule in SECTIONS commands is something like ".foo *(.baz.*)",
which instructs the linker to collect all sections whose name matches
".baz.*" from all files and put them into .foo section.
Previously, we didn't recognize the wildcard character. This patch
adds that feature.
Performance impact is a bit concerning because a linker script can
contain hundreds of SECTIONS rules, and doing pattern matching against
each rule would be too expensive. We could merge all patterns into
single DFA so that it takes O(n) to the input size. However, it is
probably too much at this moment -- we don't know whether the
performance of pattern matching matters or not. So I chose to
implement the simplest algorithm in this patch. I hope this simple
pattern matcher is sufficient.
llvm-svn: 260745
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r-- | lld/ELF/Writer.cpp | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index e41b299ec20..0ea780e58e0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -74,7 +74,7 @@ private: void writeHeader(); void writeSections(); bool isDiscarded(InputSectionBase<ELFT> *IS) const; - StringRef getOutputSectionName(StringRef S) const; + StringRef getOutputSectionName(InputSectionBase<ELFT> *S) const; bool needsInterpSection() const { return !Symtab.getSharedFiles().empty() && !Config->DynamicLinker.empty(); } @@ -726,16 +726,17 @@ void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) { } template <class ELFT> -StringRef Writer<ELFT>::getOutputSectionName(StringRef S) const { - StringRef Out = Script->getOutputSection(S); - if (!Out.empty()) - return Out; +StringRef Writer<ELFT>::getOutputSectionName(InputSectionBase<ELFT> *S) const { + StringRef Dest = Script->getOutputSection<ELFT>(S); + if (!Dest.empty()) + return Dest; + StringRef Name = S->getSectionName(); for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors."}) - if (S.startswith(V)) + if (Name.startswith(V)) return V.drop_back(); - return S; + return Name; } template <class ELFT> @@ -750,7 +751,7 @@ void reportDiscarded(InputSectionBase<ELFT> *IS, template <class ELFT> bool Writer<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) const { return !S || !S->isLive() || S == &InputSection<ELFT>::Discarded || - Script->isDiscarded(S->getSectionName()); + Script->isDiscarded(S); } // The beginning and the ending of .rel[a].plt section are marked @@ -934,8 +935,7 @@ template <class ELFT> bool Writer<ELFT>::createSections() { } OutputSectionBase<ELFT> *Sec; bool IsNew; - std::tie(Sec, IsNew) = - Factory.create(C, getOutputSectionName(C->getSectionName())); + std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C)); if (IsNew) { OwningSections.emplace_back(Sec); OutputSections.push_back(Sec); |