// .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;
});
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);
}
}
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);
}
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,
// .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() {
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
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)
// 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>
// 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");
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) {
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.
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();
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>)) {
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()) {
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>)) {
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;
// 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;
uint32_t Alignment;
+ StringRef Name;
+
// If a section is compressed, this vector has uncompressed section data.
SmallVector<char, 0> Uncompressed;
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.
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;
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();
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);
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.
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;
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;
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;
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;
}
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);
}
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>
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.
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)
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);
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;
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."})
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() {