[lld][ELF] Assign sectionChoice properly to ELF atoms

This sets the sectionChoice property for DefinedAtoms. The output section name
is derived by the property of the atom. This also decreases native file size.

Adds a test.

llvm-svn: 190840
This commit is contained in:
Shankar Easwaran 2013-09-17 02:56:22 +00:00
parent 36399e6b68
commit 063b75013f
5 changed files with 61 additions and 38 deletions

View File

@ -16,6 +16,7 @@
#include "lld/ReaderWriter/Simple.h" #include "lld/ReaderWriter/Simple.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringSwitch.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -376,9 +377,20 @@ public:
// Do we have a choice for ELF? All symbols live in explicit sections. // Do we have a choice for ELF? All symbols live in explicit sections.
virtual SectionChoice sectionChoice() const { virtual SectionChoice sectionChoice() const {
if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE) switch (contentType()) {
return sectionBasedOnContent; 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; return sectionCustomRequired;
} }

View File

@ -172,8 +172,7 @@ public:
int32_t contentPermissions); int32_t contentPermissions);
/// \brief This maps the input sections to the output section names /// \brief This maps the input sections to the output section names
virtual StringRef getSectionName(StringRef name, const int32_t contentType, virtual StringRef getSectionName(const DefinedAtom *da) const;
const int32_t contentPermissions);
/// \brief Gets or creates a section. /// \brief Gets or creates a section.
AtomSection<ELFT> *getSection( AtomSection<ELFT> *getSection(
@ -372,29 +371,35 @@ Layout::SectionOrder DefaultLayout<ELFT>::getSectionOrder(
/// \brief This maps the input sections to the output section names /// \brief This maps the input sections to the output section names
template <class ELFT> template <class ELFT>
StringRef DefaultLayout<ELFT>::getSectionName( StringRef DefaultLayout<ELFT>::getSectionName(const DefinedAtom *da) const {
StringRef name, const int32_t contentType, if (da->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
const int32_t contentPermissions) { switch (da->contentType()) {
if ((contentType == DefinedAtom::typeZeroFill) || case DefinedAtom::typeCode:
(contentType == DefinedAtom::typeZeroFillFast)) return ".text";
return ".bss"; case DefinedAtom::typeData:
if (name.startswith(".text")) return ".data";
return ".text"; case DefinedAtom::typeConstant:
if (name.startswith(".rodata")) return ".rodata";
return ".rodata"; case DefinedAtom::typeZeroFill:
if (name.startswith(".gcc_except_table")) return ".bss";
return ".gcc_except_table"; case DefinedAtom::typeThreadData:
if (name.startswith(".data.rel.ro")) return ".tdata";
return ".data.rel.ro"; case DefinedAtom::typeThreadZeroFill:
if (name.startswith(".data.rel.local")) return ".tbss";
return ".data.rel.local"; default:
if (name.startswith(".data")) break;
return ".data"; }
if (name.startswith(".tdata")) }
return ".tdata"; return llvm::StringSwitch<StringRef>(da->customSectionName())
if (name.startswith(".tbss")) .StartsWith(".text", ".text")
return ".tbss"; .StartsWith(".rodata", ".rodata")
return name; .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 /// \brief Gets the segment for a output section
@ -519,12 +524,11 @@ ErrorOr<const lld::AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom)
// -noinhibit-exec. // -noinhibit-exec.
if (definedAtom->contentType() == DefinedAtom::typeUnknown) if (definedAtom->contentType() == DefinedAtom::typeUnknown)
return make_error_code(llvm::errc::invalid_argument); return make_error_code(llvm::errc::invalid_argument);
StringRef sectionName = definedAtom->customSectionName();
const DefinedAtom::ContentPermissions permissions = const DefinedAtom::ContentPermissions permissions =
definedAtom->permissions(); definedAtom->permissions();
const DefinedAtom::ContentType contentType = definedAtom->contentType(); const DefinedAtom::ContentType contentType = definedAtom->contentType();
sectionName = getSectionName(sectionName, contentType, permissions); StringRef sectionName = getSectionName(definedAtom);
AtomSection<ELFT> *section = AtomSection<ELFT> *section =
getSection(sectionName, contentType, permissions); getSection(sectionName, contentType, permissions);
// Add runtime relocations to the .rela section. // Add runtime relocations to the .rela section.

View File

@ -103,13 +103,15 @@ public:
} }
/// \brief This maps the input sections to the output section names /// \brief This maps the input sections to the output section names
virtual StringRef getSectionName(StringRef name, const int32_t contentType, virtual StringRef getSectionName(const DefinedAtom *da) const {
const int32_t contentPermissions) { switch (da->contentType()) {
if ((contentType == DefinedAtom::typeDataFast) || case DefinedAtom::typeDataFast:
(contentType == DefinedAtom::typeZeroFillFast)) case DefinedAtom::typeZeroFillFast:
return ".sdata"; return ".sdata";
return DefaultLayout<HexagonELFType>::getSectionName(name, contentType, default:
contentPermissions); break;
}
return DefaultLayout<HexagonELFType>::getSectionName(da);
} }
/// \brief Gets or creates a section. /// \brief Gets or creates a section.

View File

@ -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

View File

@ -12,8 +12,6 @@ mergeAtoms: scope: global
mergeAtoms: type: data mergeAtoms: type: data
mergeAtoms: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] mergeAtoms: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
mergeAtoms: alignment: 2^3 mergeAtoms: alignment: 2^3
mergeAtoms: section-choice: custom-required
mergeAtoms: section-name: .data
mergeAtoms: references: mergeAtoms: references:
mergeAtoms: - kind: R_X86_64_64 mergeAtoms: - kind: R_X86_64_64
mergeAtoms: offset: 3 mergeAtoms: offset: 3