Compute section names only once.
This simplifies error handling as there is now only one place in the
code that needs to consider the possibility that the name is
corrupted. Before we would do it in every access.
llvm-svn: 280937
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 209cf20..5fa7aa0 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -137,7 +137,7 @@
// .init and .fini contains instructions that must be executed to
// initialize and finalize the process. They cannot and should not
// be merged.
- StringRef Name = S->getSectionName();
+ StringRef Name = S->Name;
if (Name == ".init" || Name == ".fini")
return false;
@@ -331,10 +331,10 @@
});
if (I == Bound)
continue;
- log("selected " + Head->getSectionName());
+ log("selected " + Head->Name);
while (I != Bound) {
InputSection<ELFT> *S = *I++;
- log(" removed " + S->getSectionName());
+ log(" removed " + S->Name);
Head->replace(S);
}
}
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 4db9907..9589a50 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -233,53 +233,6 @@
case SHT_STRTAB:
case SHT_NULL:
break;
- case SHT_RELA:
- case SHT_REL: {
- // This section contains relocation information.
- // If -r is given, we do not interpret or apply relocation
- // but just copy relocation sections to output.
- if (Config->Relocatable) {
- Sections[I] = new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec);
- break;
- }
-
- // Find the relocation target section and associate this
- // section with it.
- InputSectionBase<ELFT> *Target = getRelocTarget(Sec);
- if (!Target)
- break;
- if (auto *S = dyn_cast<InputSection<ELFT>>(Target)) {
- S->RelocSections.push_back(&Sec);
- break;
- }
- if (auto *S = dyn_cast<EhInputSection<ELFT>>(Target)) {
- if (S->RelocSection)
- fatal(
- getFilename(this) +
- ": multiple relocation sections to .eh_frame are not supported");
- S->RelocSection = &Sec;
- break;
- }
- fatal(getFilename(this) +
- ": relocations pointing to SHF_MERGE are not supported");
- }
- case SHT_ARM_ATTRIBUTES:
- // FIXME: ARM meta-data section. At present attributes are ignored,
- // they can be used to reason about object compatibility.
- Sections[I] = &InputSection<ELFT>::Discarded;
- break;
- case SHT_MIPS_REGINFO:
- MipsReginfo.reset(new MipsReginfoInputSection<ELFT>(this, &Sec));
- Sections[I] = MipsReginfo.get();
- break;
- case SHT_MIPS_OPTIONS:
- MipsOptions.reset(new MipsOptionsInputSection<ELFT>(this, &Sec));
- Sections[I] = MipsOptions.get();
- break;
- case SHT_MIPS_ABIFLAGS:
- MipsAbiFlags.reset(new MipsAbiFlagsInputSection<ELFT>(this, &Sec));
- Sections[I] = MipsAbiFlags.get();
- break;
default:
Sections[I] = createInputSection(Sec);
}
@@ -311,6 +264,49 @@
elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
StringRef Name = check(this->ELFObj.getSectionName(&Sec));
+ switch (Sec.sh_type) {
+ case SHT_ARM_ATTRIBUTES:
+ // FIXME: ARM meta-data section. At present attributes are ignored,
+ // they can be used to reason about object compatibility.
+ return &InputSection<ELFT>::Discarded;
+ case SHT_MIPS_REGINFO:
+ MipsReginfo.reset(new MipsReginfoInputSection<ELFT>(this, &Sec, Name));
+ return MipsReginfo.get();
+ case SHT_MIPS_OPTIONS:
+ MipsOptions.reset(new MipsOptionsInputSection<ELFT>(this, &Sec, Name));
+ return MipsOptions.get();
+ case SHT_MIPS_ABIFLAGS:
+ MipsAbiFlags.reset(new MipsAbiFlagsInputSection<ELFT>(this, &Sec, Name));
+ return MipsAbiFlags.get();
+ case SHT_RELA:
+ case SHT_REL: {
+ // This section contains relocation information.
+ // If -r is given, we do not interpret or apply relocation
+ // but just copy relocation sections to output.
+ if (Config->Relocatable)
+ return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec, Name);
+
+ // Find the relocation target section and associate this
+ // section with it.
+ InputSectionBase<ELFT> *Target = getRelocTarget(Sec);
+ if (!Target)
+ return nullptr;
+ if (auto *S = dyn_cast<InputSection<ELFT>>(Target)) {
+ S->RelocSections.push_back(&Sec);
+ return nullptr;
+ }
+ if (auto *S = dyn_cast<EhInputSection<ELFT>>(Target)) {
+ if (S->RelocSection)
+ fatal(getFilename(this) +
+ ": multiple relocation sections to .eh_frame are not supported");
+ S->RelocSection = &Sec;
+ return nullptr;
+ }
+ fatal(getFilename(this) +
+ ": relocations pointing to SHF_MERGE are not supported");
+ }
+ }
+
// .note.GNU-stack is a marker section to control the presence of
// PT_GNU_STACK segment in outputs. Since the presence of the segment
// is controlled only by the command line option (-z execstack) in LLD,
@@ -330,11 +326,11 @@
// .eh_frame_hdr section for runtime. So we handle them with a special
// class. For relocatable outputs, they are just passed through.
if (Name == ".eh_frame" && !Config->Relocatable)
- return new (EHAlloc.Allocate()) EhInputSection<ELFT>(this, &Sec);
+ return new (EHAlloc.Allocate()) EhInputSection<ELFT>(this, &Sec, Name);
if (shouldMerge(Sec))
- return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec);
- return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec);
+ return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec, Name);
+ return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec, Name);
}
template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index d4f7acb..01d97ed 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -30,8 +30,9 @@
template <class ELFT>
InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
- const Elf_Shdr *Hdr, Kind SectionKind)
- : InputSectionData(SectionKind, Hdr->sh_flags & SHF_COMPRESSED,
+ const Elf_Shdr *Hdr, StringRef Name,
+ Kind SectionKind)
+ : InputSectionData(SectionKind, Name, Hdr->sh_flags & SHF_COMPRESSED,
!Config->GcSections),
Header(Hdr), File(File), Repl(this) {
// The ELF spec states that a value of 0 means the section has
@@ -46,10 +47,6 @@
return Header->sh_size;
}
-template <class ELFT> StringRef InputSectionBase<ELFT>::getSectionName() const {
- return check(File->getObj().getSectionName(this->Header));
-}
-
template <class ELFT>
ArrayRef<uint8_t> InputSectionBase<ELFT>::getSectionData() const {
if (Compressed)
@@ -60,7 +57,7 @@
// Returns a string for an error message.
template <class SectionT> static std::string getName(SectionT *Sec) {
- return (Sec->getFile()->getName() + "(" + Sec->getSectionName() + ")").str();
+ return (Sec->getFile()->getName() + "(" + Sec->Name + ")").str();
}
template <class ELFT>
@@ -84,7 +81,7 @@
// corresponding input section. Redirect it to the produced output section.
if (Offset != 0)
fatal(getName(this) + ": unsupported reference to the middle of '" +
- getSectionName() + "' section");
+ Name + "' section");
return this->OutSec->getVA();
}
llvm_unreachable("invalid section kind");
@@ -121,8 +118,8 @@
template <class ELFT>
InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,
- const Elf_Shdr *Header)
- : InputSectionBase<ELFT>(F, Header, Base::Regular) {}
+ const Elf_Shdr *Header, StringRef Name)
+ : InputSectionBase<ELFT>(F, Header, Name, Base::Regular) {}
template <class ELFT>
bool InputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
@@ -436,8 +433,8 @@
template <class ELFT>
EhInputSection<ELFT>::EhInputSection(elf::ObjectFile<ELFT> *F,
- const Elf_Shdr *Header)
- : InputSectionBase<ELFT>(F, Header, InputSectionBase<ELFT>::EHFrame) {
+ const Elf_Shdr *Header, StringRef Name)
+ : InputSectionBase<ELFT>(F, Header, Name, InputSectionBase<ELFT>::EHFrame) {
// Mark .eh_frame sections as live by default because there are
// usually no relocations that point to .eh_frames. Otherwise,
// the garbage collector would drop all .eh_frame sections.
@@ -552,8 +549,9 @@
template <class ELFT>
MergeInputSection<ELFT>::MergeInputSection(elf::ObjectFile<ELFT> *F,
- const Elf_Shdr *Header)
- : InputSectionBase<ELFT>(F, Header, InputSectionBase<ELFT>::Merge) {}
+ const Elf_Shdr *Header,
+ StringRef Name)
+ : InputSectionBase<ELFT>(F, Header, Name, InputSectionBase<ELFT>::Merge) {}
template <class ELFT> void MergeInputSection<ELFT>::splitIntoPieces() {
ArrayRef<uint8_t> Data = this->getSectionData();
@@ -634,8 +632,10 @@
template <class ELFT>
MipsReginfoInputSection<ELFT>::MipsReginfoInputSection(elf::ObjectFile<ELFT> *F,
- const Elf_Shdr *Hdr)
- : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsReginfo) {
+ const Elf_Shdr *Hdr,
+ StringRef Name)
+ : InputSectionBase<ELFT>(F, Hdr, Name,
+ InputSectionBase<ELFT>::MipsReginfo) {
// Initialize this->Reginfo.
ArrayRef<uint8_t> D = this->getSectionData();
if (D.size() != sizeof(Elf_Mips_RegInfo<ELFT>)) {
@@ -652,8 +652,10 @@
template <class ELFT>
MipsOptionsInputSection<ELFT>::MipsOptionsInputSection(elf::ObjectFile<ELFT> *F,
- const Elf_Shdr *Hdr)
- : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsOptions) {
+ const Elf_Shdr *Hdr,
+ StringRef Name)
+ : InputSectionBase<ELFT>(F, Hdr, Name,
+ InputSectionBase<ELFT>::MipsOptions) {
// Find ODK_REGINFO option in the section's content.
ArrayRef<uint8_t> D = this->getSectionData();
while (!D.empty()) {
@@ -677,8 +679,9 @@
template <class ELFT>
MipsAbiFlagsInputSection<ELFT>::MipsAbiFlagsInputSection(
- elf::ObjectFile<ELFT> *F, const Elf_Shdr *Hdr)
- : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsAbiFlags) {
+ elf::ObjectFile<ELFT> *F, const Elf_Shdr *Hdr, StringRef Name)
+ : InputSectionBase<ELFT>(F, Hdr, Name,
+ InputSectionBase<ELFT>::MipsAbiFlags) {
// Initialize this->Flags.
ArrayRef<uint8_t> D = this->getSectionData();
if (D.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
@@ -695,7 +698,7 @@
template <class ELFT>
CommonInputSection<ELFT>::CommonInputSection(std::vector<DefinedCommon *> Syms)
- : InputSection<ELFT>(nullptr, &Hdr) {
+ : InputSection<ELFT>(nullptr, &Hdr, "") {
Hdr.sh_size = 0;
Hdr.sh_type = SHT_NOBITS;
Hdr.sh_flags = SHF_ALLOC | SHF_WRITE;
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 9e66c6c..f11dc67 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -42,8 +42,9 @@
// The garbage collector sets sections' Live bits.
// If GC is disabled, all sections are considered live by default.
- InputSectionData(Kind SectionKind, bool Compressed, bool Live)
- : SectionKind(SectionKind), Live(Live), Compressed(Compressed) {}
+ InputSectionData(Kind SectionKind, StringRef Name, bool Compressed, bool Live)
+ : SectionKind(SectionKind), Live(Live), Compressed(Compressed),
+ Name(Name) {}
private:
unsigned SectionKind : 3;
@@ -58,6 +59,8 @@
uint32_t Alignment;
+ StringRef Name;
+
// If a section is compressed, this vector has uncompressed section data.
SmallVector<char, 0> Uncompressed;
@@ -79,10 +82,11 @@
ObjectFile<ELFT> *File;
public:
- InputSectionBase() : InputSectionData(Regular, false, false), Repl(this) {}
+ InputSectionBase()
+ : InputSectionData(Regular, "", false, false), Repl(this) {}
InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
- Kind SectionKind);
+ StringRef Name, Kind SectionKind);
OutputSectionBase<ELFT> *OutSec = nullptr;
// This pointer points to the "real" instance of this instance.
@@ -97,7 +101,6 @@
static InputSectionBase<ELFT> Discarded;
- StringRef getSectionName() const;
const Elf_Shdr *getSectionHdr() const { return Header; }
ObjectFile<ELFT> *getFile() const { return File; }
uintX_t getOffset(const DefinedRegular<ELFT> &Sym) const;
@@ -145,7 +148,8 @@
typedef typename ELFT::Shdr Elf_Shdr;
public:
- MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
+ MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header,
+ StringRef Name);
static bool classof(const InputSectionBase<ELFT> *S);
void splitIntoPieces();
@@ -185,7 +189,7 @@
public:
typedef typename ELFT::Shdr Elf_Shdr;
typedef typename ELFT::uint uintX_t;
- EhInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
+ EhInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);
static bool classof(const InputSectionBase<ELFT> *S);
void split();
template <class RelTy> void split(ArrayRef<RelTy> Rels);
@@ -209,7 +213,7 @@
typedef typename ELFT::uint uintX_t;
public:
- InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
+ InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);
// Write this section to a mmap'ed file, assuming Buf is pointing to
// beginning of the output section.
@@ -264,7 +268,8 @@
typedef typename ELFT::Shdr Elf_Shdr;
public:
- MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
+ MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr,
+ StringRef Name);
static bool classof(const InputSectionBase<ELFT> *S);
const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
@@ -275,7 +280,8 @@
typedef typename ELFT::Shdr Elf_Shdr;
public:
- MipsOptionsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
+ MipsOptionsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr,
+ StringRef Name);
static bool classof(const InputSectionBase<ELFT> *S);
const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
@@ -286,7 +292,8 @@
typedef typename ELFT::Shdr Elf_Shdr;
public:
- MipsAbiFlagsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
+ MipsAbiFlagsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr,
+ StringRef Name);
static bool classof(const InputSectionBase<ELFT> *S);
const llvm::object::Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 943a4ab..7af2a1a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -99,7 +99,7 @@
template <class ELFT>
bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
for (Regex *Re : Opt.KeptSections)
- if (Re->match(S->getSectionName()))
+ if (Re->match(S->Name))
return true;
return false;
}
@@ -121,7 +121,7 @@
if (fileMatches(I, sys::path::filename(F->getName())))
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S) && !S->OutSec &&
- const_cast<Regex &>(Re).match(S->getSectionName()))
+ const_cast<Regex &>(Re).match(S->Name))
Ret.push_back(S);
}
@@ -132,7 +132,7 @@
template <class ELFT>
static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
- return A->getSectionName() < B->getSectionName();
+ return A->Name < B->Name;
}
template <class ELFT>
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 4277b79..c231608 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -174,7 +174,7 @@
case SHT_PREINIT_ARRAY:
return true;
default:
- StringRef S = Sec->getSectionName();
+ StringRef S = Sec->Name;
// We do not want to reclaim sections if they can be referred
// by __start_* and __stop_* symbols.
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 4eda445..97ccb95 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -931,7 +931,7 @@
std::vector<Pair> V;
for (InputSection<ELFT> *S : Sections)
- V.push_back({getPriority(S->getSectionName()), S});
+ V.push_back({getPriority(S->Name), S});
std::stable_sort(V.begin(), V.end(), Comp);
Sections.clear();
for (Pair &P : V)
@@ -980,8 +980,8 @@
bool EndB = isCrtend(B->getFile()->getName());
if (EndA != EndB)
return EndB;
- StringRef X = A->getSectionName();
- StringRef Y = B->getSectionName();
+ StringRef X = A->Name;
+ StringRef Y = B->Name;
assert(X.startswith(".ctors") || X.startswith(".dtors"));
assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
X = X.substr(6);
@@ -1032,7 +1032,7 @@
ArrayRef<RelTy> Rels) {
const endianness E = ELFT::TargetEndianness;
if (read32<E>(Piece.data().data() + 4) != 0)
- fatal("CIE expected at beginning of .eh_frame: " + Sec->getSectionName());
+ fatal("CIE expected at beginning of .eh_frame: " + Sec->Name);
SymbolBody *Personality = nullptr;
unsigned FirstRelI = Piece.FirstRelocation;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index ba58330..17d3d85 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -89,7 +89,7 @@
template <class ELFT>
StringRef elf::getOutputSectionName(InputSectionBase<ELFT> *S) {
- StringRef Name = S->getSectionName();
+ StringRef Name = S->Name;
for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.",
".init_array.", ".fini_array.", ".ctors.", ".dtors.",
".tbss.", ".gcc_except_table.", ".tdata.", ".ARM.exidx."})
@@ -101,8 +101,8 @@
template <class ELFT> void elf::reportDiscarded(InputSectionBase<ELFT> *IS) {
if (!Config->PrintGcSections || !IS || IS->Live)
return;
- errs() << "removing unused section from '" << IS->getSectionName()
- << "' in file '" << IS->getFile()->getName() << "'\n";
+ errs() << "removing unused section from '" << IS->Name << "' in file '"
+ << IS->getFile()->getName() << "'\n";
}
template <class ELFT> static bool needsInterpSection() {