summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2015-07-03 11:25:37 +0000
committerSimon Atanasyan <simon@atanasyan.com>2015-07-03 11:25:37 +0000
commita87c17a2019986614fea015288f4cea4b7b173aa (patch)
treef4122facaffec7681d988f7d74988c40b3cd6040 /lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp
parentcec93c355a7b2f1a6be436f233b043bd2632d4bd (diff)
downloadbcm5719-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/OutputELFWriter.cpp')
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.cpp46
1 files changed, 33 insertions, 13 deletions
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>;
OpenPOWER on IntegriCloud