[lld] r258723 - Avoid almost duplication in .dynamic finalize and write.

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 27 04:00:50 PST 2016


On Tue, Jan 26, 2016 at 12:32 AM, Rafael Espindola via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: rafael
> Date: Mon Jan 25 15:32:04 2016
> New Revision: 258723
>
> URL: http://llvm.org/viewvc/llvm-project?rev=258723&view=rev
> Log:
> Avoid almost duplication in .dynamic finalize and write.
>
> There are a few cases where we have almost duplicated code.
>
> This patches fixes the simplest: the finalize and write of dynamic
> section. Right now they have to have exactly the same structure to
> decide if a DT_* entry is needed and then to actually write it.
>
> We cannot just write it to a std::vector in the first pass since
> addresses have not been computed yet.
>
> Modified:
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/ELF/OutputSections.h
>     lld/trunk/ELF/Writer.cpp
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=258723&r1=258722&r2=258723&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Mon Jan 25 15:32:04 2016
> @@ -593,61 +593,76 @@ template <class ELFT> void DynamicSectio
>    Elf_Shdr &Header = this->Header;
>    Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
>
> -  unsigned NumEntries = 0;
> +  // Reserve strings. We know that these are the last string to be added to
> +  // DynStrTab and doing this here allows this function to set DT_STRSZ.
> +  if (!Config->RPath.empty())
> +    Out<ELFT>::DynStrTab->reserve(Config->RPath);
> +  if (!Config->SoName.empty())
> +    Out<ELFT>::DynStrTab->reserve(Config->SoName);
> +  for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles())
> +    if (F->isNeeded())
> +      Out<ELFT>::DynStrTab->reserve(F->getSoName());
> +  Out<ELFT>::DynStrTab->finalize();
> +
>    if (Out<ELFT>::RelaDyn->hasRelocs()) {
> -    ++NumEntries; // DT_RELA / DT_REL
> -    ++NumEntries; // DT_RELASZ / DT_RELSZ
> -    ++NumEntries; // DT_RELAENT / DT_RELENT
> +    bool IsRela = Out<ELFT>::RelaDyn->isRela();
> +    Entries.push_back({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
> +    Entries.push_back(
> +        {IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->getSize()});
> +    Entries.push_back({IsRela ? DT_RELAENT : DT_RELENT,
> +                       uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
>    }
>    if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
> -    ++NumEntries; // DT_JMPREL
> -    ++NumEntries; // DT_PLTRELSZ
> -    ++NumEntries; // DT_PLTGOT / DT_MIPS_PLTGOT
> -    ++NumEntries; // DT_PLTREL
> +    Entries.push_back({DT_JMPREL, Out<ELFT>::RelaPlt});
> +    Entries.push_back({DT_PLTRELSZ, Out<ELFT>::RelaPlt->getSize()});

Size of RelocationSection is calculated in the
RelocationSection::finalize() method. Before this commit we called the
RelocationSection::getSize() method from the DynamicSection::writeTo()
method and so we could be sure that size of the RelocationSection is
calculated already. Now value of DT_PLTRELSZ depends on the order of
finalize() calls. If RelocationSection::finalize() is called after the
DynamicSection::finalize(), the DT_PLTRELSZ will be zero.

-- 
Simon Atanasyan


More information about the llvm-commits mailing list