diff options
-rw-r--r-- | lld/include/lld/Core/DefinedAtom.h | 13 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Atoms.h | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 8 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/Native/NativeFileFormat.h | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/Native/ReaderNative.cpp | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/Native/WriterNative.cpp | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp | 16 | ||||
-rw-r--r-- | lld/test/elf/undef-from-main-dso.test | 16 |
8 files changed, 56 insertions, 5 deletions
diff --git a/lld/include/lld/Core/DefinedAtom.h b/lld/include/lld/Core/DefinedAtom.h index 1f499c881bf..4be7fac7b24 100644 --- a/lld/include/lld/Core/DefinedAtom.h +++ b/lld/include/lld/Core/DefinedAtom.h @@ -185,6 +185,14 @@ public: deadStripAlways // linker must remove this atom if unused }; + enum DynamicExport { + /// \brief The linker may or may not export this atom dynamically depending + /// on the output type and other context of the link. + dynamicExportNormal, + /// \brief The linker will always export this atom dynamically. + dynamicExportAlways, + }; + struct Alignment { Alignment(int p2, int m = 0) : powerOf2(p2) @@ -252,6 +260,11 @@ public: /// \brief constraints on whether the linker may dead strip away this atom. virtual DeadStripKind deadStrip() const = 0; + /// \brief Under which conditions should this atom be dynamically exported. + virtual DynamicExport dynamicExport() const { + return dynamicExportNormal; + } + /// \brief Returns the OS memory protections required for this atom's content /// at runtime. /// diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h index d1153e7868c..d6ed6c91965 100644 --- a/lld/lib/ReaderWriter/ELF/Atoms.h +++ b/lld/lib/ReaderWriter/ELF/Atoms.h @@ -809,6 +809,8 @@ public: virtual uint64_t size() const { return _size; } + virtual DynamicExport dynamicExport() const { return dynamicExportAlways; } + virtual ContentPermissions permissions() const { return permRW_; } virtual ArrayRef<uint8_t> rawContent() const { diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index d8319da09df..9789250928c 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -151,6 +151,14 @@ void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) { template <class ELFT> void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) { ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable"); + 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 && da->dynamicExport() == DefinedAtom::dynamicExportAlways) + _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), + atom->_virtualAddr, atom); + } for (const auto sla : file.sharedLibrary()) { _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); _soNeeded.insert(sla->loadName()); diff --git a/lld/lib/ReaderWriter/Native/NativeFileFormat.h b/lld/lib/ReaderWriter/Native/NativeFileFormat.h index 1dd1551f893..834cbfc1d0a 100644 --- a/lld/lib/ReaderWriter/Native/NativeFileFormat.h +++ b/lld/lib/ReaderWriter/Native/NativeFileFormat.h @@ -152,6 +152,7 @@ struct NativeAtomAttributesV1 { uint8_t contentType; uint8_t sectionChoiceAndPosition; // high nibble is choice, low is position uint8_t deadStrip; + uint8_t dynamicExport; uint8_t permissions; uint8_t alias; }; diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp index e614637faec..d1102431913 100644 --- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp +++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp @@ -91,6 +91,10 @@ public: return (DefinedAtom::DeadStripKind)(attributes().deadStrip); } + virtual DynamicExport dynamicExport() const { + return (DynamicExport)attributes().dynamicExport; + } + virtual DefinedAtom::ContentPermissions permissions() const { return (DefinedAtom::ContentPermissions)(attributes().permissions); } diff --git a/lld/lib/ReaderWriter/Native/WriterNative.cpp b/lld/lib/ReaderWriter/Native/WriterNative.cpp index c0bc28d83cd..06b587b7370 100644 --- a/lld/lib/ReaderWriter/Native/WriterNative.cpp +++ b/lld/lib/ReaderWriter/Native/WriterNative.cpp @@ -444,6 +444,7 @@ private: attrs.sectionChoiceAndPosition = atom.sectionChoice() << 4 | atom.sectionPosition(); attrs.deadStrip = atom.deadStrip(); + attrs.dynamicExport = atom.dynamicExport(); attrs.permissions = atom.permissions(); attrs.alias = atom.isAlias(); } diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp index 8a7eb4c5296..9fb136ff0af 100644 --- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp +++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp @@ -384,6 +384,13 @@ template <> struct ScalarEnumerationTraits<lld::DefinedAtom::DeadStripKind> { } }; +template <> struct ScalarEnumerationTraits<lld::DefinedAtom::DynamicExport> { + static void enumeration(IO &io, lld::DefinedAtom::DynamicExport &value) { + io.enumCase(value, "normal", lld::DefinedAtom::dynamicExportNormal); + io.enumCase(value, "always", lld::DefinedAtom::dynamicExportAlways); + } +}; + template <> struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> { static void enumeration(IO &io, lld::DefinedAtom::ContentPermissions &value) { @@ -812,8 +819,9 @@ template <> struct MappingTraits<const lld::DefinedAtom *> { _merge(atom->merge()), _contentType(atom->contentType()), _alignment(atom->alignment()), _sectionChoice(atom->sectionChoice()), _sectionPosition(atom->sectionPosition()), - _deadStrip(atom->deadStrip()), _permissions(atom->permissions()), - _size(atom->size()), _sectionName(atom->customSectionName()) { + _deadStrip(atom->deadStrip()), _dynamicExport(atom->dynamicExport()), + _permissions(atom->permissions()), _size(atom->size()), + _sectionName(atom->customSectionName()) { for (const lld::Reference *r : *atom) _references.push_back(r); if (!atom->occupiesDiskSpace()) @@ -862,6 +870,7 @@ template <> struct MappingTraits<const lld::DefinedAtom *> { virtual StringRef customSectionName() const { return _sectionName; } virtual SectionPosition sectionPosition() const { return _sectionPosition; } virtual DeadStripKind deadStrip() const { return _deadStrip; } + virtual DynamicExport dynamicExport() const { return _dynamicExport; } virtual ContentPermissions permissions() const { return _permissions; } virtual bool isAlias() const { return false; } ArrayRef<uint8_t> rawContent() const { @@ -905,6 +914,7 @@ template <> struct MappingTraits<const lld::DefinedAtom *> { SectionChoice _sectionChoice; SectionPosition _sectionPosition; DeadStripKind _deadStrip; + DynamicExport _dynamicExport; ContentPermissions _permissions; uint32_t _ordinal; std::vector<ImplicitHex8> _content; @@ -949,6 +959,8 @@ template <> struct MappingTraits<const lld::DefinedAtom *> { lld::DefinedAtom::sectionPositionAny); io.mapOptional("dead-strip", keys->_deadStrip, lld::DefinedAtom::deadStripNormal); + io.mapOptional("dynamic-export", keys->_dynamicExport, + lld::DefinedAtom::dynamicExportNormal); // default permissions based on content type io.mapOptional("permissions", keys->_permissions, lld::DefinedAtom::permissions(keys->_contentType)); diff --git a/lld/test/elf/undef-from-main-dso.test b/lld/test/elf/undef-from-main-dso.test index ff2093ecc4d..6a218a5288a 100644 --- a/lld/test/elf/undef-from-main-dso.test +++ b/lld/test/elf/undef-from-main-dso.test @@ -1,10 +1,10 @@ RUN: lld -flavor gnu -target x86_64 -e main -o %t -L%p/Inputs \ RUN: %p/Inputs/undef.o -lundef -RUN: llvm-readobj -relocations -symbols %t | FileCheck %s +RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s RUN: lld -flavor gnu -target x86_64 -e main -o %t -L%p/Inputs \ RUN: %p/Inputs/undef-pc32.o -lundef -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 }; @@ -21,7 +21,7 @@ RUN: llvm-readobj -relocations -symbols %t | FileCheck %s CHECK: Relocations [ CHECK-NEXT: Section ({{[0-9]+}}) .rela.dyn { -CHECK-NEXT: 0x{{[1-9A-F][0-9A-F]*}} R_X86_64_COPY - 0x0 +CHECK-NEXT: 0x{{[1-9A-F][0-9A-F]*}} R_X86_64_COPY x 0x0 CHECK-NEXT: } CHECK-NEXT: ] @@ -32,3 +32,13 @@ CHECK-NEXT: Binding: Global (0x1) CHECK-NEXT: Type: Object (0x1) CHECK-NEXT: Other: 0 CHECK-NEXT: Section: .bss + +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 + +CHECK: Name: x@ ({{[0-9]+}} |