[lld] r244972 - ELF: Drop the Chunk base class.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 19:16:13 PDT 2015


On Fri, Aug 14, 2015 at 10:36 AM, Rafael EspĂ­ndola <
rafael.espindola at gmail.com> wrote:

> Rui, do you remember why on COFF you made Chunk be the virtual interface?
>
> I tried to use that for the string table, but it was very unnatural.
> We would have an OutputSection with a single StringTableChunk and
> there was no convenient place to call finalize. Everything just worked
> by adding a virtual interface to OutputSeciton.
>

The linker creates non-section-based chunks for thunks which jump to DLL
functions, and we want to put such thunks to .text section along with other
regular chunks. The linker also creates data for DLL names, import tables,
etc, which we want to put into .rdata. So one type of OutputSection
contains various types of chunks.

On 13 August 2015 at 18:21, Rafael Espindola via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> > Author: rafael
> > Date: Thu Aug 13 17:21:37 2015
> > New Revision: 244972
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=244972&view=rev
> > Log:
> > ELF: Drop the Chunk base class.
> >
> > With OutputSection being a virtual interface, each concrete OutputSection
> > handles only one type of chunk and we don't need a base Chunk class.
> >
> > So for we have a class that handles input sections and one that handles
> > the string table, but this extends naturally for other outputs (symbol
> table,
> > merging of SHF_MERGE sections, etc.).
> >
> > Modified:
> >     lld/trunk/ELF/Chunks.h
> >     lld/trunk/ELF/Writer.cpp
> >
> > Modified: lld/trunk/ELF/Chunks.h
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.h?rev=244972&r1=244971&r2=244972&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Chunks.h (original)
> > +++ lld/trunk/ELF/Chunks.h Thu Aug 13 17:21:37 2015
> > @@ -19,51 +19,38 @@ namespace elf2 {
> >  class Defined;
> >  template <class ELFT> class ObjectFile;
> >
> > -// A Chunk represents a chunk of data that will occupy space in the
> > -// output (if the resolver chose that). It may or may not be backed by
> > -// a section of an input file. It could be linker-created data, or
> > -// doesn't even have actual data (if common or bss).
> > -class Chunk {
> > +// A chunk corresponding a section of an input file.
> > +template <class ELFT> class SectionChunk {
> > +  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
> > +  typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
> > +  typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
> > +
> >  public:
> > -  virtual ~Chunk() = default;
> > +  SectionChunk(llvm::object::ELFFile<ELFT> *Obj, const Elf_Shdr
> *Header);
> >
> >    // Returns the size of this chunk (even if this is a common or BSS.)
> > -  virtual size_t getSize() const = 0;
> > +  size_t getSize() const { return Header->sh_size; }
> >
> >    // Write this chunk to a mmap'ed file, assuming Buf is pointing to
> > -  // beginning of the file. Because this function may use VA values
> > -  // of other chunks for relocations, you need to set them properly
> > -  // before calling this function.
> > -  virtual void writeTo(uint8_t *Buf) = 0;
> > +  // beginning of the output section.
> > +  void writeTo(uint8_t *Buf);
> > +
> > +  StringRef getSectionName() const;
> > +  const Elf_Shdr *getSectionHdr() const { return Header; }
> >
> >    // The writer sets and uses the addresses.
> >    uint64_t getOutputSectionOff() { return OutputSectionOff; }
> >    uint32_t getAlign() { return Align; }
> >    void setOutputSectionOff(uint64_t V) { OutputSectionOff = V; }
> >
> > -protected:
> > +private:
> >    // The offset from beginning of the output sections this chunk was
> assigned
> >    // to. The writer sets a value.
> >    uint64_t OutputSectionOff = 0;
> >
> >    // The alignment of this chunk. The writer uses the value.
> >    uint32_t Align = 1;
> > -};
> >
> > -// A chunk corresponding a section of an input file.
> > -template <class ELFT> class SectionChunk : public Chunk {
> > -  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
> > -  typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
> > -  typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
> > -
> > -public:
> > -  SectionChunk(llvm::object::ELFFile<ELFT> *Obj, const Elf_Shdr
> *Header);
> > -  size_t getSize() const override { return Header->sh_size; }
> > -  void writeTo(uint8_t *Buf) override;
> > -  StringRef getSectionName() const;
> > -  const Elf_Shdr *getSectionHdr() const { return Header; }
> > -
> > -private:
> >    // A file this chunk was created from.
> >    llvm::object::ELFFile<ELFT> *Obj;
> >
> >
> > Modified: lld/trunk/ELF/Writer.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=244972&r1=244971&r2=244972&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Writer.cpp (original)
> > +++ lld/trunk/ELF/Writer.cpp Thu Aug 13 17:21:37 2015
> > @@ -66,18 +66,18 @@ protected:
> >    ~OutputSectionBase() = default;
> >  };
> >
> > -template <bool Is64Bits>
> > -class OutputSection final : public OutputSectionBase<Is64Bits> {
> > +template <class ELFT>
> > +class OutputSection final : public OutputSectionBase<ELFT::Is64Bits> {
> >  public:
> > -  typedef typename OutputSectionBase<Is64Bits>::uintX_t uintX_t;
> > +  typedef typename OutputSectionBase<ELFT::Is64Bits>::uintX_t uintX_t;
> >    OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags)
> > -      : OutputSectionBase<Is64Bits>(Name, sh_type, sh_flags) {}
> > +      : OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags) {}
> >
> > -  void addChunk(Chunk *C);
> > +  void addChunk(SectionChunk<ELFT> *C);
> >    void writeTo(uint8_t *Buf) override;
> >
> >  private:
> > -  std::vector<Chunk *> Chunks;
> > +  std::vector<SectionChunk<ELFT> *> Chunks;
> >  };
> >
> >  template <bool Is64Bits>
> > @@ -117,7 +117,7 @@ private:
> >
> >    SymbolTable *Symtab;
> >    std::unique_ptr<llvm::FileOutputBuffer> Buffer;
> > -  llvm::SpecificBumpPtrAllocator<OutputSection<ELFT::Is64Bits>> CAlloc;
> > +  llvm::SpecificBumpPtrAllocator<OutputSection<ELFT>> CAlloc;
> >    std::vector<OutputSectionBase<ELFT::Is64Bits> *> OutputSections;
> >
> >    uintX_t FileSize;
> > @@ -155,7 +155,8 @@ template <class ELFT> void Writer<ELFT>:
> >    error(Buffer->commit());
> >  }
> >
> > -template <bool Is64Bits> void OutputSection<Is64Bits>::addChunk(Chunk
> *C) {
> > +template <class ELFT>
> > +void OutputSection<ELFT>::addChunk(SectionChunk<ELFT> *C) {
> >    Chunks.push_back(C);
> >    uint32_t Align = C->getAlign();
> >    if (Align > this->Header.sh_addralign)
> > @@ -168,8 +169,8 @@ template <bool Is64Bits> void OutputSect
> >    this->Header.sh_size = Off;
> >  }
> >
> > -template <bool Is64Bits> void OutputSection<Is64Bits>::writeTo(uint8_t
> *Buf) {
> > -  for (Chunk *C : Chunks)
> > +template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
> > +  for (SectionChunk<ELFT> *C : Chunks)
> >      C->writeTo(Buf);
> >  }
> >
> > @@ -225,18 +226,17 @@ template <bool Is64Bits> struct DenseMap
> >
> >  // Create output section objects and add them to OutputSections.
> >  template <class ELFT> void Writer<ELFT>::createSections() {
> > -  SmallDenseMap<SectionKey<ELFT::Is64Bits>,
> OutputSection<ELFT::Is64Bits> *>
> > -      Map;
> > +  SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map;
> >    for (std::unique_ptr<ObjectFileBase> &FileB : Symtab->ObjectFiles) {
> >      auto &File = cast<ObjectFile<ELFT>>(*FileB);
> >      for (SectionChunk<ELFT> *C : File.getChunks()) {
> >        const Elf_Shdr *H = C->getSectionHdr();
> >        SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type,
> >                                       H->sh_flags};
> > -      OutputSection<ELFT::Is64Bits> *&Sec = Map[Key];
> > +      OutputSection<ELFT> *&Sec = Map[Key];
> >        if (!Sec) {
> >          Sec = new (CAlloc.Allocate())
> > -            OutputSection<ELFT::Is64Bits>(Key.Name, Key.sh_type,
> Key.sh_flags);
> > +            OutputSection<ELFT>(Key.Name, Key.sh_type, Key.sh_flags);
> >          OutputSections.push_back(Sec);
> >        }
> >        Sec->addChunk(C);
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150814/8cfdc5b0/attachment.html>


More information about the llvm-commits mailing list