diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h index 6321a550774f..27521667bad2 100644 --- a/lld/lib/ReaderWriter/ELF/Atoms.h +++ b/lld/lib/ReaderWriter/ELF/Atoms.h @@ -16,6 +16,7 @@ #include "lld/ReaderWriter/Simple.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringSwitch.h" #include #include @@ -376,9 +377,20 @@ public: // Do we have a choice for ELF? All symbols live in explicit sections. virtual SectionChoice sectionChoice() const { - if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE) - return sectionBasedOnContent; - + switch (contentType()) { + case typeCode: + case typeData: + case typeZeroFill: + case typeThreadZeroFill: + case typeThreadData: + case typeConstant: + if ((_sectionName == ".text") || (_sectionName == ".data") || + (_sectionName == ".bss") || (_sectionName == ".rodata") || + (_sectionName == ".tdata") || (_sectionName == ".tbss")) + return sectionBasedOnContent; + default: + break; + } return sectionCustomRequired; } diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index e8255c8c22d3..c473d64dbcc8 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -172,8 +172,7 @@ public: int32_t contentPermissions); /// \brief This maps the input sections to the output section names - virtual StringRef getSectionName(StringRef name, const int32_t contentType, - const int32_t contentPermissions); + virtual StringRef getSectionName(const DefinedAtom *da) const; /// \brief Gets or creates a section. AtomSection *getSection( @@ -372,29 +371,35 @@ Layout::SectionOrder DefaultLayout::getSectionOrder( /// \brief This maps the input sections to the output section names template -StringRef DefaultLayout::getSectionName( - StringRef name, const int32_t contentType, - const int32_t contentPermissions) { - if ((contentType == DefinedAtom::typeZeroFill) || - (contentType == DefinedAtom::typeZeroFillFast)) - return ".bss"; - if (name.startswith(".text")) - return ".text"; - if (name.startswith(".rodata")) - return ".rodata"; - if (name.startswith(".gcc_except_table")) - return ".gcc_except_table"; - if (name.startswith(".data.rel.ro")) - return ".data.rel.ro"; - if (name.startswith(".data.rel.local")) - return ".data.rel.local"; - if (name.startswith(".data")) - return ".data"; - if (name.startswith(".tdata")) - return ".tdata"; - if (name.startswith(".tbss")) - return ".tbss"; - return name; +StringRef DefaultLayout::getSectionName(const DefinedAtom *da) const { + if (da->sectionChoice() == DefinedAtom::sectionBasedOnContent) { + switch (da->contentType()) { + case DefinedAtom::typeCode: + return ".text"; + case DefinedAtom::typeData: + return ".data"; + case DefinedAtom::typeConstant: + return ".rodata"; + case DefinedAtom::typeZeroFill: + return ".bss"; + case DefinedAtom::typeThreadData: + return ".tdata"; + case DefinedAtom::typeThreadZeroFill: + return ".tbss"; + default: + break; + } + } + return llvm::StringSwitch(da->customSectionName()) + .StartsWith(".text", ".text") + .StartsWith(".rodata", ".rodata") + .StartsWith(".gcc_except_table", ".gcc_except_table") + .StartsWith(".data.rel.ro", ".data.rel.ro") + .StartsWith(".data.rel.local", ".data.rel.local") + .StartsWith(".data", ".data") + .StartsWith(".tdata", ".tdata") + .StartsWith(".tbss", ".tbss") + .Default(da->customSectionName()); } /// \brief Gets the segment for a output section @@ -519,12 +524,11 @@ ErrorOr DefaultLayout::addAtom(const Atom *atom) // -noinhibit-exec. if (definedAtom->contentType() == DefinedAtom::typeUnknown) return make_error_code(llvm::errc::invalid_argument); - StringRef sectionName = definedAtom->customSectionName(); const DefinedAtom::ContentPermissions permissions = definedAtom->permissions(); const DefinedAtom::ContentType contentType = definedAtom->contentType(); - sectionName = getSectionName(sectionName, contentType, permissions); + StringRef sectionName = getSectionName(definedAtom); AtomSection *section = getSection(sectionName, contentType, permissions); // Add runtime relocations to the .rela section. diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h index d8c325d0d86c..9797bf483987 100644 --- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h @@ -103,13 +103,15 @@ public: } /// \brief This maps the input sections to the output section names - virtual StringRef getSectionName(StringRef name, const int32_t contentType, - const int32_t contentPermissions) { - if ((contentType == DefinedAtom::typeDataFast) || - (contentType == DefinedAtom::typeZeroFillFast)) + virtual StringRef getSectionName(const DefinedAtom *da) const { + switch (da->contentType()) { + case DefinedAtom::typeDataFast: + case DefinedAtom::typeZeroFillFast: return ".sdata"; - return DefaultLayout::getSectionName(name, contentType, - contentPermissions); + default: + break; + } + return DefaultLayout::getSectionName(da); } /// \brief Gets or creates a section. diff --git a/lld/test/elf/X86_64/sectionchoice.test b/lld/test/elf/X86_64/sectionchoice.test new file mode 100644 index 000000000000..7b6c9a23e500 --- /dev/null +++ b/lld/test/elf/X86_64/sectionchoice.test @@ -0,0 +1,7 @@ +# This tests that we are able to properly set the sectionChoice for DefinedAtoms +RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/zerosizedsection.o \ +RUN: --noinhibit-exec -o %t -emit-yaml +RUN: FileCheck %s < %t + +CHECK-NOT: section-choice: sectionCustomRequired + diff --git a/lld/test/elf/mergeconstants.test b/lld/test/elf/mergeconstants.test index abe132fc13b9..08d41073e60f 100644 --- a/lld/test/elf/mergeconstants.test +++ b/lld/test/elf/mergeconstants.test @@ -12,8 +12,6 @@ mergeAtoms: scope: global mergeAtoms: type: data mergeAtoms: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] mergeAtoms: alignment: 2^3 -mergeAtoms: section-choice: custom-required -mergeAtoms: section-name: .data mergeAtoms: references: mergeAtoms: - kind: R_X86_64_64 mergeAtoms: offset: 3