[PATCH] [lld][ELF] Add explictly exported atoms and export R_*_COPY'ed atoms.
Michael Spencer
bigcheesegs at gmail.com
Tue Oct 1 12:06:16 PDT 2013
Hi kledzik, shankarke, joerg,
This adds explicitly exported atoms to ELFLinkingContext and uses them to export copied objects properly. With this patch std::cout works (it crashes after, but I have a fix for that).
The problem with this approach is the const_cast on the context. There are a few fixes for this.
* Make LinkingContext non const.
* Make _explicitlyExportedAtoms a pointer to non-const.
* Make explicit exporting an attribute of the Atom.
Personally I like adding it to DefinedAtom.
We also have another problem. In the test we add two checks for x. This is because we have no way to replace the SharedLibraryAtom x with the ObjectAtom x.
http://llvm-reviews.chandlerc.com/D1799
Files:
include/lld/ReaderWriter/ELFLinkingContext.h
lib/ReaderWriter/ELF/OutputELFWriter.h
lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
test/elf/undef-from-main-dso.test
Index: include/lld/ReaderWriter/ELFLinkingContext.h
===================================================================
--- include/lld/ReaderWriter/ELFLinkingContext.h
+++ include/lld/ReaderWriter/ELFLinkingContext.h
@@ -23,6 +23,7 @@
#include "llvm/Support/ELF.h"
#include <memory>
+#include <unordered_set>
namespace lld {
class DefinedAtom;
@@ -206,6 +207,15 @@
return _rpathLinkList;
}
+ void addExplicitlyExportedAtom(const DefinedAtom *a) {
+ _explicitlyExportedAtoms.insert(a);
+ }
+
+ const std::unordered_set<const DefinedAtom *> &
+ getExplicitlyExportedAtoms() const {
+ return _explicitlyExportedAtoms;
+ }
+
private:
ELFLinkingContext() LLVM_DELETED_FUNCTION;
@@ -241,6 +251,10 @@
StringRef _soname;
StringRefVector _rpathList;
StringRefVector _rpathLinkList;
+
+ /// \brief The set of explicitly exported atoms which should be added to the
+ /// dynamic symbol table.
+ std::unordered_set<const DefinedAtom *> _explicitlyExportedAtoms;
};
} // end namespace lld
Index: lib/ReaderWriter/ELF/OutputELFWriter.h
===================================================================
--- lib/ReaderWriter/ELF/OutputELFWriter.h
+++ lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -154,6 +154,14 @@
_dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
_soNeeded.insert(sla->loadName());
}
+ for (auto sec : this->_layout->sections())
+ if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
+ for (const auto &atom : section->atoms()) {
+ const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
+ if (da && _context.getExplicitlyExportedAtoms().count(da))
+ this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+ atom->_virtualAddr, atom);
+ }
for (const auto &loadName : _soNeeded) {
Elf_Dyn dyn;
dyn.d_tag = DT_NEEDED;
Index: lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
===================================================================
--- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
+++ lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
@@ -206,7 +206,7 @@
public:
GOTPLTPass(const ELFLinkingContext &ctx)
- : _file(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
+ : _file(ctx), _ctx(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
_got1(nullptr) {}
/// \brief Do the pass.
@@ -257,6 +257,7 @@
protected:
/// \brief Owner of all the Atoms created by this pass.
ELFPassFile _file;
+ const ELFLinkingContext &_ctx;
/// \brief Map Atoms to their GOT entries.
llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
@@ -371,13 +372,14 @@
return obj->second;
auto oa = new (_file._alloc) ObjectAtom(_file);
- oa->addReference(R_X86_64_COPY, 0, a, 0);
+ oa->addReference(R_X86_64_COPY, 0, oa, 0);
oa->_name = a->name();
oa->_size = a->size();
_objectMap[a] = oa;
_objectVector.push_back(oa);
+ const_cast<ELFLinkingContext &>(_ctx).addExplicitlyExportedAtom(oa);
return oa;
}
Index: test/elf/undef-from-main-dso.test
===================================================================
--- test/elf/undef-from-main-dso.test
+++ test/elf/undef-from-main-dso.test
@@ -1,8 +1,8 @@
RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef.o
-RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
+RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef-pc32.o
-RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
+RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
# DSO source code:
# int x[2] = { 1, 2 };
@@ -30,3 +30,13 @@
CHECK-NEXT: Type: Object (0x1)
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: .bss
+
+CHECK: Name: x@ ({{[0-9]+}}
+
+CHECK: Name: x@ ({{[0-9]+}}
+CHECK-NEXT: Value: 0x{{[1-9A-F][0-9A-F]*}}
+CHECK-NEXT: Size: 8
+CHECK-NEXT: Binding: Global (0x1)
+CHECK-NEXT: Type: Object (0x1)
+CHECK-NEXT: Other: 0
+CHECK-NEXT: Section: .bss
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1799.1.patch
Type: text/x-patch
Size: 4141 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131001/5738e42b/attachment.bin>
More information about the llvm-commits
mailing list