[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 "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringSwitch.h"
#include <memory>
#include <vector>
@ -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)
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;
}

View File

@ -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<ELFT> *getSection(
@ -372,29 +371,35 @@ Layout::SectionOrder DefaultLayout<ELFT>::getSectionOrder(
/// \brief This maps the input sections to the output section names
template <class ELFT>
StringRef DefaultLayout<ELFT>::getSectionName(
StringRef name, const int32_t contentType,
const int32_t contentPermissions) {
if ((contentType == DefinedAtom::typeZeroFill) ||
(contentType == DefinedAtom::typeZeroFillFast))
return ".bss";
if (name.startswith(".text"))
StringRef DefaultLayout<ELFT>::getSectionName(const DefinedAtom *da) const {
if (da->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
switch (da->contentType()) {
case DefinedAtom::typeCode:
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"))
case DefinedAtom::typeData:
return ".data";
if (name.startswith(".tdata"))
case DefinedAtom::typeConstant:
return ".rodata";
case DefinedAtom::typeZeroFill:
return ".bss";
case DefinedAtom::typeThreadData:
return ".tdata";
if (name.startswith(".tbss"))
case DefinedAtom::typeThreadZeroFill:
return ".tbss";
return name;
default:
break;
}
}
return llvm::StringSwitch<StringRef>(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<const lld::AtomLayout &> DefaultLayout<ELFT>::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<ELFT> *section =
getSection(sectionName, contentType, permissions);
// 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
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<HexagonELFType>::getSectionName(name, contentType,
contentPermissions);
default:
break;
}
return DefaultLayout<HexagonELFType>::getSectionName(da);
}
/// \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: 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