diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 98 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 65 |
2 files changed, 43 insertions, 120 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index 0c2153e4c51..b3ad7329bb6 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -77,11 +77,7 @@ void BinarySectionWriter::visit(const RelocationSection &Sec) { } 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) { @@ -159,12 +155,6 @@ uint16_t Symbol::getShndx() const { 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, @@ -199,7 +189,6 @@ void SymbolTableSection::removeSectionReferences(const SectionBase *Sec) { [=](const SymPtr &Sym) { return Sym->DefinedIn == Sec; }); Size -= (std::end(Symbols) - Iter) * this->EntrySize; Symbols.erase(Iter, std::end(Symbols)); - assignIndices(); } void SymbolTableSection::localize( @@ -214,7 +203,11 @@ 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) { @@ -281,10 +274,9 @@ template <class SymTabType> 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); } } @@ -299,9 +291,9 @@ void RelocSectionWithSymtabBase<SymTabType>::initialize( " 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); } @@ -355,49 +347,20 @@ void DynamicRelocationSection::accept(SectionVisitor &Visitor) const { 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"); @@ -453,19 +416,6 @@ void GnuDebugLinkSection::accept(SectionVisitor &Visitor) const { 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) { @@ -505,7 +455,8 @@ static bool compareSegmentsByPAddr(const Segment *A, const Segment *B) { 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. @@ -571,7 +522,7 @@ template <class ELFT> void ELFBuilder<ELFT>::readProgramHeaders() { 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++; @@ -601,9 +552,9 @@ void ELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) { } } 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, @@ -672,9 +623,6 @@ SectionBase &ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) { // 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); diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 36bd65b8cf2..27beafc0ce6 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -35,17 +35,17 @@ class SymbolTableSection; 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; @@ -71,7 +71,6 @@ public: 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 { @@ -88,7 +87,6 @@ public: 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) {} }; @@ -104,7 +102,6 @@ public: 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) {} }; @@ -120,8 +117,6 @@ public: 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) {} }; @@ -242,7 +237,7 @@ public: 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 { @@ -258,10 +253,11 @@ public: 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; }; @@ -269,6 +265,7 @@ public: class OwnedDataSection : public SectionBase { MAKE_SEC_WRITER_FRIEND +private: std::vector<uint8_t> Data; public: @@ -294,6 +291,7 @@ public: class StringTableSection : public SectionBase { MAKE_SEC_WRITER_FRIEND +private: StringTableBuilder StrTabBuilder; public: @@ -346,7 +344,6 @@ class SymbolTableSection : public SectionBase { MAKE_SEC_WRITER_FRIEND void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } - void assignIndices(); protected: std::vector<std::unique_ptr<Symbol>> Symbols; @@ -405,6 +402,7 @@ public: // 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; } @@ -421,6 +419,7 @@ class RelocationSection : public RelocSectionWithSymtabBase<SymbolTableSection> { MAKE_SEC_WRITER_FRIEND +private: std::vector<Relocation> Relocations; public: @@ -434,37 +433,14 @@ 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; @@ -473,8 +449,7 @@ public: 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; @@ -483,7 +458,7 @@ public: 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; @@ -498,7 +473,7 @@ private: 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; @@ -513,6 +488,7 @@ class GnuDebugLinkSection : public SectionBase { MAKE_SEC_WRITER_FRIEND private: + StringRef FileName; uint32_t CRC32; @@ -520,7 +496,7 @@ private: 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; }; @@ -530,10 +506,10 @@ public: 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: @@ -606,8 +582,7 @@ public: 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(); |