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

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 18:36:06 PDT 2015


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.

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


More information about the llvm-commits mailing list