[PATCH] D29664: [LLD][ELF] Refactor PltSection and IPltSection common code into a base class NFC

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 7 12:39:04 PST 2017


I think this is an improvement. Rui, do you agree?

Cheers,
Rafael

Peter Smith via Phabricator <reviews at reviews.llvm.org> writes:

> peter.smith created this revision.
>
> In a comment via email on https://reviews.llvm.org/D28956 Rafael suggested:
> "Would it be possible to add a common base class to PltSection and Ipltsection and share this code?"
>
> This is an attempt to add a common base class PltSectionBase that moves out most of the more complex code into the base class. It is using the same logic and interface as previously.
>
>
> https://reviews.llvm.org/D29664
>
> Files:
>   ELF/SyntheticSections.cpp
>   ELF/SyntheticSections.h
>
> Index: ELF/SyntheticSections.h
> ===================================================================
> --- ELF/SyntheticSections.h
> +++ ELF/SyntheticSections.h
> @@ -457,33 +457,47 @@
>    size_t Size = 0;
>  };
>  
> -template <class ELFT> class PltSection final : public SyntheticSection<ELFT> {
> +// Common base class for Plt and IPlt.
> +template <class ELFT> class PltSectionBase : public SyntheticSection<ELFT> {
>  public:
> -  PltSection();
> +  PltSectionBase(size_t HeaderSize, RelocationSection<ELFT> *PltRelSec);
>    void writeTo(uint8_t *Buf) override;
>    size_t getSize() const override;
>    void addEntry(SymbolBody &Sym);
>    bool empty() const override { return Entries.empty(); }
>    void addSymbols();
>  
>  private:
> +  virtual void writeHeader(uint8_t *Buf){};
> +  virtual void addHeaderSymbols(){};
> +  virtual unsigned getPltRelocOff() const = 0;
>    std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
> +  // IPlt always has HeaderSize of 0
> +  size_t HeaderSize;
> +  RelocationSection<ELFT> *PltRelocSection;
> +};
> +
> +// The traditional Plt section for non GNU Ifunc symbols. This always has a
> +// header as the first entry to facilitate lazy binding at run time.
> +template <class ELFT> class PltSection final : public PltSectionBase<ELFT> {
> +public:
> +  PltSection();
> +
> +private:
> +  virtual void writeHeader(uint8_t *Buf) override;
> +  virtual void addHeaderSymbols() override;
> +  virtual unsigned getPltRelocOff() const override { return 0; }
>  };
>  
>  // The IpltSection is a variant of Plt for recording entries for GNU Ifunc
>  // symbols that will be subject to a Target->IRelativeRel
>  // The IpltSection immediately follows the Plt section in the Output Section
> -template <class ELFT> class IpltSection final : public SyntheticSection<ELFT> {
> +template <class ELFT> class IpltSection final : public PltSectionBase<ELFT> {
>  public:
>    IpltSection();
> -  void writeTo(uint8_t *Buf) override;
> -  size_t getSize() const override;
> -  void addEntry(SymbolBody &Sym);
> -  bool empty() const override { return Entries.empty(); }
> -  void addSymbols();
>  
>  private:
> -  std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
> +  virtual unsigned getPltRelocOff() const override;
>  };
>  
>  template <class ELFT>
> Index: ELF/SyntheticSections.cpp
> ===================================================================
> --- ELF/SyntheticSections.cpp
> +++ ELF/SyntheticSections.cpp
> @@ -1427,83 +1427,74 @@
>  }
>  
>  template <class ELFT>
> -PltSection<ELFT>::PltSection()
> +PltSectionBase<ELFT>::PltSectionBase(size_t S,
> +                                     RelocationSection<ELFT> *PltRelSec)
>      : SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
> -                             ".plt") {}
> +                             ".plt"),
> +      HeaderSize(S), PltRelocSection(PltRelSec) {}
>  
> -template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) {
> -  // At beginning of PLT, we have code to call the dynamic linker
> -  // to resolve dynsyms at runtime. Write such code.
> -  Target->writePltHeader(Buf);
> -  size_t Off = Target->PltHeaderSize;
> +template <class ELFT> void PltSectionBase<ELFT>::writeTo(uint8_t *Buf) {
> +  // At beginning of PLT but not the IPLT, we have code to call the dynamic
> +  // linker to resolve dynsyms at runtime. Write such code.
> +  writeHeader(Buf);
> +  size_t Off = HeaderSize;
> +  // The IPlt is immediately after the Plt, account for this in RelOff
> +  unsigned PltOff = getPltRelocOff();
>  
>    for (auto &I : Entries) {
>      const SymbolBody *B = I.first;
> -    unsigned RelOff = I.second;
> +    unsigned RelOff = I.second + PltOff;
>      uint64_t Got = B->getGotPltVA<ELFT>();
>      uint64_t Plt = this->getVA() + Off;
>      Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
>      Off += Target->PltEntrySize;
>    }
>  }
>  
> -template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody &Sym) {
> +template <class ELFT> void PltSectionBase<ELFT>::addEntry(SymbolBody &Sym) {
>    Sym.PltIndex = Entries.size();
> -  unsigned RelOff = In<ELFT>::RelaPlt->getRelocOffset();
> +  unsigned RelOff = PltRelocSection->getRelocOffset();
> +  Sym.IsInIplt = HeaderSize == 0;
>    Entries.push_back(std::make_pair(&Sym, RelOff));
>  }
>  
> -template <class ELFT> size_t PltSection<ELFT>::getSize() const {
> -  return Target->PltHeaderSize + Entries.size() * Target->PltEntrySize;
> +template <class ELFT> size_t PltSectionBase<ELFT>::getSize() const {
> +  return HeaderSize + Entries.size() * Target->PltEntrySize;
>  }
>  
>  // Some architectures such as additional symbols in the PLT section. For
>  // example ARM uses mapping symbols to aid disassembly
> -template <class ELFT> void PltSection<ELFT>::addSymbols() {
> -  Target->addPltHeaderSymbols(this);
> -  size_t Off = Target->PltHeaderSize;
> +template <class ELFT> void PltSectionBase<ELFT>::addSymbols() {
> +  // The PLT may have symbols defined for the Header, the IPLT has no header
> +  addHeaderSymbols();
> +  size_t Off = HeaderSize;
> +
>    for (size_t I = 0; I < Entries.size(); ++I) {
>      Target->addPltSymbols(this, Off);
>      Off += Target->PltEntrySize;
>    }
>  }
>  
>  template <class ELFT>
> -IpltSection<ELFT>::IpltSection()
> -    : SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
> -                             ".plt") {}
> +PltSection<ELFT>::PltSection()
> +    : PltSectionBase<ELFT>(Target->PltHeaderSize, In<ELFT>::RelaPlt) {}
>  
> -template <class ELFT> void IpltSection<ELFT>::writeTo(uint8_t *Buf) {
> -  // The IRelative relocations do not support lazy binding so no header is
> -  // needed
> -  size_t Off = 0;
> -  for (auto &I : Entries) {
> -    const SymbolBody *B = I.first;
> -    unsigned RelOff = I.second + In<ELFT>::Plt->getSize();
> -    uint64_t Got = B->getGotPltVA<ELFT>();
> -    uint64_t Plt = this->getVA() + Off;
> -    Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
> -    Off += Target->PltEntrySize;
> -  }
> +template <class ELFT> void PltSection<ELFT>::writeHeader(uint8_t *Buf) {
> +  Target->writePltHeader(Buf);
>  }
>  
> -template <class ELFT> void IpltSection<ELFT>::addEntry(SymbolBody &Sym) {
> -  Sym.PltIndex = Entries.size();
> -  Sym.IsInIplt = true;
> -  unsigned RelOff = In<ELFT>::RelaIplt->getRelocOffset();
> -  Entries.push_back(std::make_pair(&Sym, RelOff));
> +// Some architectures such as additional symbols in the PLT section. For
> +// example ARM uses mapping symbols to aid disassembly
> +template <class ELFT> void PltSection<ELFT>::addHeaderSymbols() {
> +  Target->addPltHeaderSymbols(this);
>  }
>  
> -template <class ELFT> size_t IpltSection<ELFT>::getSize() const {
> -  return Entries.size() * Target->PltEntrySize;
> -}
> +template <class ELFT>
> +IpltSection<ELFT>::IpltSection()
> +    : PltSectionBase<ELFT>(0, In<ELFT>::RelaIplt) {}
>  
> -template <class ELFT> void IpltSection<ELFT>::addSymbols() {
> -  size_t Off = 0;
> -  for (size_t I = 0; I < Entries.size(); ++I) {
> -    Target->addPltSymbols(this, Off);
> -    Off += Target->PltEntrySize;
> -  }
> +template <class ELFT> unsigned IpltSection<ELFT>::getPltRelocOff() const {
> +  return In<ELFT>::Plt->getSize();
>  }
>  
>  template <class ELFT>
> @@ -2101,6 +2092,11 @@
>  template class elf::HashTableSection<ELF64LE>;
>  template class elf::HashTableSection<ELF64BE>;
>  
> +template class elf::PltSectionBase<ELF32LE>;
> +template class elf::PltSectionBase<ELF32BE>;
> +template class elf::PltSectionBase<ELF64LE>;
> +template class elf::PltSectionBase<ELF64BE>;
> +
>  template class elf::PltSection<ELF32LE>;
>  template class elf::PltSection<ELF32BE>;
>  template class elf::PltSection<ELF64LE>;


More information about the llvm-commits mailing list