}
void BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {
- error("Cannot write '" + Sec.Name + "' out to binary");
-}
-
-void BinarySectionWriter::visit(const GroupSection &Sec) {
- error("Cannot write '" + Sec.Name + "' out to binary");
+ error("Cannot write '.gnu_debuglink' out to binary");
}
void SectionWriter::visit(const Section &Sec) {
llvm_unreachable("Symbol with invalid ShndxType encountered");
}
-void SymbolTableSection::assignIndices() {
- uint32_t Index = 0;
- for (auto &Sym : Symbols)
- Sym->Index = Index++;
-}
-
void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
SectionBase *DefinedIn, uint64_t Value,
uint8_t Visibility, uint16_t Shndx,
[=](const SymPtr &Sym) { return Sym->DefinedIn == Sec; });
Size -= (std::end(Symbols) - Iter) * this->EntrySize;
Symbols.erase(Iter, std::end(Symbols));
- assignIndices();
}
void SymbolTableSection::localize(
std::stable_partition(
std::begin(Symbols), std::end(Symbols),
[](const SymPtr &Sym) { return Sym->Binding == STB_LOCAL; });
- assignIndices();
+
+ // Lastly we fix the symbol indexes.
+ uint32_t Index = 0;
+ for (auto &Sym : Symbols)
+ Sym->Index = Index++;
}
void SymbolTableSection::initialize(SectionTableRef SecTable) {
void RelocSectionWithSymtabBase<SymTabType>::removeSectionReferences(
const SectionBase *Sec) {
if (Symbols == Sec) {
- error("Symbol table " + Symbols->Name +
- " cannot be removed because it is "
- "referenced by the relocation "
- "section " +
+ error("Symbol table " + Symbols->Name + " cannot be removed because it is "
+ "referenced by the relocation "
+ "section " +
this->Name);
}
}
" is not a symbol table"));
if (Info != SHN_UNDEF)
- setSection(SecTable.getSection(Info, "Info field value " + Twine(Info) +
- " in section " + Name +
- " is invalid"));
+ setSection(SecTable.getSection(Info,
+ "Info field value " + Twine(Info) +
+ " in section " + Name + " is invalid"));
else
setSection(nullptr);
}
void SectionWithStrTab::removeSectionReferences(const SectionBase *Sec) {
if (StrTab == Sec) {
- error("String table " + StrTab->Name +
- " cannot be removed because it is "
- "referenced by the section " +
+ error("String table " + StrTab->Name + " cannot be removed because it is "
+ "referenced by the section " +
this->Name);
}
}
-void GroupSection::initialize(SectionTableRef SecTable) {
- SymTab = SecTable.getSectionOfType<SymbolTableSection>(
- Link,
- "Link field value " + Twine(Link) + " in section " + Name + " is invalid",
- "Link field value " + Twine(Link) + " in section " + Name +
- " is not a symbol table");
- Sym = SymTab->getSymbolByIndex(Info);
- if (!Sym)
- error("Info field value " + Twine(Info) + " in section " + Name +
- " is not a valid symbol index");
- if (Contents.size() % sizeof(ELF::Elf32_Word) || Contents.empty())
- error("The content of the section " + Name + " is malformed");
- const ELF::Elf32_Word *Word =
- reinterpret_cast<const ELF::Elf32_Word *>(Contents.data());
- const ELF::Elf32_Word *End = Word + Contents.size() / sizeof(ELF::Elf32_Word);
- FlagWord = *Word++;
- for (; Word != End; ++Word) {
- GroupMembers.push_back(
- SecTable.getSection(*Word, "Group member index " + Twine(*Word) +
- " in section " + Name + " is invalid"));
- }
-}
-
-void GroupSection::finalize() {
- this->Info = Sym->Index;
- this->Link = SymTab->Index;
-}
-
bool SectionWithStrTab::classof(const SectionBase *S) {
return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S);
}
void SectionWithStrTab::initialize(SectionTableRef SecTable) {
- auto StrTab =
- SecTable.getSection(Link, "Link field value " + Twine(Link) +
- " in section " + Name + " is invalid");
+ auto StrTab = SecTable.getSection(Link,
+ "Link field value " + Twine(Link) +
+ " in section " + Name + " is invalid");
if (StrTab->Type != SHT_STRTAB) {
error("Link field value " + Twine(Link) + " in section " + Name +
" is not a string table");
Visitor.visit(*this);
}
-template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {
- ELF::Elf32_Word *Buf =
- reinterpret_cast<ELF::Elf32_Word *>(Out.getBufferStart() + Sec.Offset);
- *Buf++ = Sec.FlagWord;
- for (const auto *S : Sec.GroupMembers)
- *Buf++ = S->Index;
-}
-
-void GroupSection::accept(SectionVisitor &Visitor) const {
- Visitor.visit(*this);
-}
-
// Returns true IFF a section is wholly inside the range of a segment
static bool sectionWithinSegment(const SectionBase &Section,
const Segment &Segment) {
return A->Index < B->Index;
}
-template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
+template <class ELFT>
+void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
for (auto &Parent : Obj.segments()) {
// Every segment will overlap with itself but we don't want a segment to
// be it's own parent so we avoid that situation.
PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = Ehdr.e_phoff;
PrHdr.PAddr = 0;
PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
- // The spec requires us to naturally align all the fields.
+ // The spec requires us to naturally align all the fields.
PrHdr.Align = sizeof(Elf_Addr);
PrHdr.Index = Index++;
}
} else if (Sym.st_shndx != SHN_UNDEF) {
DefSection = Obj.sections().getSection(
- Sym.st_shndx, "Symbol '" + Name +
- "' is defined in invalid section with index " +
- Twine(Sym.st_shndx));
+ Sym.st_shndx,
+ "Symbol '" + Name + "' is defined in invalid section with index " +
+ Twine(Sym.st_shndx));
}
SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
// Because of this we don't need to mess with the hash tables either.
Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
return Obj.addSection<Section>(Data);
- case SHT_GROUP:
- Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
- return Obj.addSection<GroupSection>(Data);
case SHT_DYNSYM:
Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
return Obj.addSection<DynamicSymbolTableSection>(Data);
class RelocationSection;
class DynamicRelocationSection;
class GnuDebugLinkSection;
-class GroupSection;
class Segment;
class Object;
class SectionTableRef {
+private:
MutableArrayRef<std::unique_ptr<SectionBase>> Sections;
public:
using iterator = pointee_iterator<std::unique_ptr<SectionBase> *>;
- explicit SectionTableRef(MutableArrayRef<std::unique_ptr<SectionBase>> Secs)
+ SectionTableRef(MutableArrayRef<std::unique_ptr<SectionBase>> Secs)
: Sections(Secs) {}
SectionTableRef(const SectionTableRef &) = default;
virtual void visit(const RelocationSection &Sec) = 0;
virtual void visit(const DynamicRelocationSection &Sec) = 0;
virtual void visit(const GnuDebugLinkSection &Sec) = 0;
- virtual void visit(const GroupSection &Sec) = 0;
};
class SectionWriter : public SectionVisitor {
virtual void visit(const SymbolTableSection &Sec) override = 0;
virtual void visit(const RelocationSection &Sec) override = 0;
virtual void visit(const GnuDebugLinkSection &Sec) override = 0;
- virtual void visit(const GroupSection &Sec) override = 0;
SectionWriter(FileOutputBuffer &Buf) : Out(Buf) {}
};
void visit(const SymbolTableSection &Sec) override;
void visit(const RelocationSection &Sec) override;
void visit(const GnuDebugLinkSection &Sec) override;
- void visit(const GroupSection &Sec) override;
ELFSectionWriter(FileOutputBuffer &Buf) : SectionWriter(Buf) {}
};
void visit(const SymbolTableSection &Sec) override;
void visit(const RelocationSection &Sec) override;
void visit(const GnuDebugLinkSection &Sec) override;
- void visit(const GroupSection &Sec) override;
-
BinarySectionWriter(FileOutputBuffer &Buf) : SectionWriter(Buf) {}
};
uint64_t OriginalOffset;
Segment *ParentSegment = nullptr;
- explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
+ Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
Segment() {}
const SectionBase *firstSection() const {
class Section : public SectionBase {
MAKE_SEC_WRITER_FRIEND
+private:
ArrayRef<uint8_t> Contents;
public:
- explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
+ Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
void accept(SectionVisitor &Visitor) const override;
};
class OwnedDataSection : public SectionBase {
MAKE_SEC_WRITER_FRIEND
+private:
std::vector<uint8_t> Data;
public:
class StringTableSection : public SectionBase {
MAKE_SEC_WRITER_FRIEND
+private:
StringTableBuilder StrTabBuilder;
public:
MAKE_SEC_WRITER_FRIEND
void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
- void assignIndices();
protected:
std::vector<std::unique_ptr<Symbol>> Symbols;
// that code between the two symbol table types.
template <class SymTabType>
class RelocSectionWithSymtabBase : public RelocationSectionBase {
+private:
SymTabType *Symbols = nullptr;
void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
: public RelocSectionWithSymtabBase<SymbolTableSection> {
MAKE_SEC_WRITER_FRIEND
+private:
std::vector<Relocation> Relocations;
public:
}
};
-// TODO: The way stripping and groups interact is complicated
-// and still needs to be worked on.
-
-class GroupSection : public SectionBase {
- MAKE_SEC_WRITER_FRIEND
- // TODO: Contents is present in several classes of the hierarchy.
- // This needs to be refactored to avoid duplication.
- ArrayRef<uint8_t> Contents;
- ELF::Elf32_Word FlagWord;
- SmallVector<SectionBase *, 3> GroupMembers;
- const SymbolTableSection *SymTab = nullptr;
- const Symbol *Sym = nullptr;
-
-public:
- explicit GroupSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
-
- void initialize(SectionTableRef SecTable) override;
- void accept(SectionVisitor &) const override;
- void finalize() override;
-
- static bool classof(const SectionBase *S) {
- return S->Type == ELF::SHT_GROUP;
- }
-};
-
class SectionWithStrTab : public Section {
+private:
const SectionBase *StrTab = nullptr;
- void setStrTab(const SectionBase *StringTable) { StrTab = StringTable; }
public:
- explicit SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {}
+ SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {}
+
+ void setStrTab(const SectionBase *StringTable) { StrTab = StringTable; }
void removeSectionReferences(const SectionBase *Sec) override;
void initialize(SectionTableRef SecTable) override;
void finalize() override;
class DynamicSymbolTableSection : public SectionWithStrTab {
public:
- explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data)
- : SectionWithStrTab(Data) {}
+ DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
static bool classof(const SectionBase *S) {
return S->Type == ELF::SHT_DYNSYM;
class DynamicSection : public SectionWithStrTab {
public:
- explicit DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
+ DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
static bool classof(const SectionBase *S) {
return S->Type == ELF::SHT_DYNAMIC;
ArrayRef<uint8_t> Contents;
public:
- explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
+ DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
void accept(SectionVisitor &) const override;
MAKE_SEC_WRITER_FRIEND
private:
+
StringRef FileName;
uint32_t CRC32;
public:
// If we add this section from an external source we can use this ctor.
- explicit GnuDebugLinkSection(StringRef File);
+ GnuDebugLinkSection(StringRef File);
void accept(SectionVisitor &Visitor) const override;
};
virtual std::unique_ptr<Object> create() const = 0;
};
+using object::OwningBinary;
using object::Binary;
using object::ELFFile;
using object::ELFObjectFile;
-using object::OwningBinary;
template <class ELFT> class ELFBuilder {
private:
StringTableSection *SectionNames = nullptr;
SymbolTableSection *SymbolTable = nullptr;
- explicit Object(std::shared_ptr<MemoryBuffer> Data)
- : OwnedData(std::move(Data)) {}
+ Object(std::shared_ptr<MemoryBuffer> Data) : OwnedData(Data) {}
virtual ~Object() = default;
void sortSections();