diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2015-07-03 11:25:37 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2015-07-03 11:25:37 +0000 |
| commit | a87c17a2019986614fea015288f4cea4b7b173aa (patch) | |
| tree | f4122facaffec7681d988f7d74988c40b3cd6040 /lld/lib/ReaderWriter/ELF | |
| parent | cec93c355a7b2f1a6be436f233b043bd2632d4bd (diff) | |
| download | bcm5719-llvm-a87c17a2019986614fea015288f4cea4b7b173aa.tar.gz bcm5719-llvm-a87c17a2019986614fea015288f4cea4b7b173aa.zip | |
[ELF] Define __start_XXX/__stop_XXX symbols where XXX is a section name
This is GNU ELF linker extension used particularly by LibC code.
If input object files contain section named XXX, and the XXX is a valid C
identifier, and there are undefined or weak symbols __start_XXX/__stop_XXX,
linker should define __start_XXX/__stop_XXX symbols point to the begin/end
of the XXX section correspondingly.
For example, without support of this extension statically linked executables
for X86_64 and Mips (maybe other) targets do not flush IO buffers at the end
of executing.
llvm-svn: 241341
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h | 2 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFFile.cpp | 4 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 9 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp | 46 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 3 |
5 files changed, 50 insertions, 14 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h index 45e0aff1f18..974dab63a12 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h @@ -50,6 +50,8 @@ void ARMExecutableWriter::createImplicitFiles( void ARMExecutableWriter::processUndefinedSymbol( StringRef symName, RuntimeFile<ELF32LE> &file) const { + ARMELFWriter<ExecutableWriter<ELF32LE>>::processUndefinedSymbol(symName, + file); if (symName == gotSymbol) { file.addAbsoluteAtom(gotSymbol); } else if (symName.startswith("__exidx")) { diff --git a/lld/lib/ReaderWriter/ELF/ELFFile.cpp b/lld/lib/ReaderWriter/ELF/ELFFile.cpp index 0e35e458f18..4e1fd818bde 100644 --- a/lld/lib/ReaderWriter/ELF/ELFFile.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFFile.cpp @@ -152,6 +152,10 @@ std::error_code ELFFile<ELFT>::createAtomizableSections() { _relocationReferences[sHdr] = make_range(ri, re); totalRelocs += std::distance(ri, re); } else { + auto sectionName = _objFile->getSectionName(§ion); + if (std::error_code ec = sectionName.getError()) + return ec; + _ctx.notifyInputSectionName(*sectionName); _sectionSymbols[§ion]; } } diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index 5e734b2f88c..361bd509fa8 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -247,4 +247,13 @@ void ELFLinkingContext::setUndefinesResolver(std::unique_ptr<File> resolver) { _resolver = std::move(resolver); } +void ELFLinkingContext::notifyInputSectionName(StringRef name) { + // Save sections names which can be represented as a C identifier. + if (name.find_first_not_of("0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "_") == StringRef::npos) + _cidentSections.insert(name); +} + } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp b/lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp index 14cd3c4323d..78729393393 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp @@ -246,6 +246,14 @@ template <class ELFT> void OutputELFWriter<ELFT>::finalizeDefaultAtomValues() { assert(a); a->_virtualAddr = res; } + // If there is a section named XXX, and XXX is a valid C identifier, + // and there are undefined or weak __start_XXX/__stop_XXX symbols, + // set the symbols values to the begin/end of the XXX section + // correspondingly. + for (const auto &name : _ctx.cidentSectionNames()) + updateScopeAtomValues((Twine("__start_") + name.getKey()).str(), + (Twine("__stop_") + name.getKey()).str(), + name.getKey()); } template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() { @@ -455,23 +463,35 @@ std::error_code OutputELFWriter<ELFT>::writeFile(const File &file, } template <class ELFT> +void OutputELFWriter<ELFT>::processUndefinedSymbol( + StringRef symName, RuntimeFile<ELFT> &file) const { + if (symName.startswith("__start_")) { + if (_ctx.cidentSectionNames().count(symName.drop_front(8))) + file.addAbsoluteAtom(symName); + } else if (symName.startswith("__stop_")) { + if (_ctx.cidentSectionNames().count(symName.drop_front(7))) + file.addAbsoluteAtom(symName); + } +} + +template <class ELFT> void OutputELFWriter<ELFT>::updateScopeAtomValues(StringRef sym, StringRef sec) { - std::string start = ("__" + sym + "_start").str(); - std::string end = ("__" + sym + "_end").str(); + updateScopeAtomValues(("__" + sym + "_start").str().c_str(), + ("__" + sym + "_end").str().c_str(), sec); +} + +template <class ELFT> +void OutputELFWriter<ELFT>::updateScopeAtomValues(StringRef start, + StringRef end, + StringRef sec) { AtomLayout *s = _layout.findAbsoluteAtom(start); AtomLayout *e = _layout.findAbsoluteAtom(end); - OutputSection<ELFT> *section = _layout.findOutputSection(sec); - if (!s || !e) - return; - - if (section) { - s->_virtualAddr = section->virtualAddr(); - e->_virtualAddr = section->virtualAddr() + section->memSize(); - } else { - s->_virtualAddr = 0; - e->_virtualAddr = 0; - } + const OutputSection<ELFT> *section = _layout.findOutputSection(sec); + if (s) + s->_virtualAddr = section ? section->virtualAddr() : 0; + if (e) + e->_virtualAddr = section ? section->virtualAddr() + section->memSize() : 0; } template class OutputELFWriter<ELF32LE>; diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index c7909f5f75d..bb390101063 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -113,7 +113,7 @@ protected: /// \brief Process undefined symbols that left after resolution step. virtual void processUndefinedSymbol(StringRef symName, - RuntimeFile<ELFT> &file) const {} + RuntimeFile<ELFT> &file) const; /// \brief Assign addresses to atoms marking section's start and end. void updateScopeAtomValues(StringRef sym, StringRef sec); @@ -144,6 +144,7 @@ protected: private: static StringRef maybeGetSOName(Node *node); + void updateScopeAtomValues(StringRef start, StringRef end, StringRef sec); }; } // namespace elf |

