[lld] r299615 - Create GOT and PLT entries early in scanRelocs().

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 6 13:05:41 PDT 2017


On 5 April 2017 at 23:30, Rui Ueyama via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: ruiu
> Date: Wed Apr  5 22:30:51 2017
> New Revision: 299615
>
> URL: http://llvm.org/viewvc/llvm-project?rev=299615&view=rev
> Log:
> Create GOT and PLT entries early in scanRelocs().
>
> scanRelocs() does a lot of things. It fills InputSection's Relocations vector,
> making a decision whether a TLS relocation should be relaxed or not,
> and making a decision whether a GOT/PLT slot needs to be created or not.
>
> They don't actually have to be done in a single loop. I want to separate
> them so that some of them can be run concurently. As a first step, this
> patch moves PLT/GOT slot assignment to beginning of the loop, so that
> they just fall through to the next statements. This should make it clear
> that that code doesn't affect other parts of the loop.

Please just be careful in the future work to benchmark the single
threaded case. Doing more loops over relocations can be very
expensive.

Cheers,
Rafael


> Modified:
>     lld/trunk/ELF/Relocations.cpp
>
> Modified: lld/trunk/ELF/Relocations.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=299615&r1=299614&r2=299615&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Relocations.cpp (original)
> +++ lld/trunk/ELF/Relocations.cpp Wed Apr  5 22:30:51 2017
> @@ -81,9 +81,8 @@ static std::string getLocation(InputSect
>
>  static bool refersToGotEntry(RelExpr Expr) {
>    return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
> -                        R_MIPS_GOT_OFF32, R_MIPS_TLSGD, R_MIPS_TLSLD,
> -                        R_GOT_PAGE_PC, R_GOT_PC, R_GOT_FROM_END, R_TLSGD,
> -                        R_TLSGD_PC, R_TLSDESC, R_TLSDESC_PAGE>(Expr);
> +                        R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,
> +                        R_GOT_FROM_END>(Expr);
>  }
>
>  static bool isPreemptible(const SymbolBody &Body, uint32_t Type) {
> @@ -250,6 +249,9 @@ handleTlsRelocation(uint32_t Type, Symbo
>          {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body});
>      return 1;
>    }
> +
> +  if (Expr == R_TLSDESC_CALL)
> +    return 1;
>    return 0;
>  }
>
> @@ -817,18 +819,47 @@ static void scanRelocs(InputSectionBase
>                         R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
>        In<ELFT>::Got->HasGotOffRel = true;
>
> +    // Read an addend.
>      int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data());
>      if (Config->EMachine == EM_MIPS)
>        Addend += computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
>
> +    // Process some TLS relocations, including relaxing TLS relocations.
> +    // Note that this function does not handle all TLS relocations.
>      if (unsigned Processed =
>              handleTlsRelocation<ELFT>(Type, Body, Sec, Offset, Addend, Expr)) {
>        I += (Processed - 1);
>        continue;
>      }
>
> -    if (Expr == R_TLSDESC_CALL)
> -      continue;
> +    // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
> +    if (needsPlt(Expr) && !Body.isInPlt()) {
> +      if (Body.isGnuIFunc() && !Preemptible)
> +        addPltEntry(InX::Iplt, In<ELFT>::IgotPlt, In<ELFT>::RelaIplt,
> +                    Target->IRelativeRel, Body, true);
> +      else
> +        addPltEntry(InX::Plt, In<ELFT>::GotPlt, In<ELFT>::RelaPlt,
> +                    Target->PltRel, Body, !Preemptible);
> +    }
> +
> +    // Create a GOT slot if a relocation needs GOT.
> +    if (refersToGotEntry(Expr)) {
> +      if (Config->EMachine == EM_MIPS) {
> +        // MIPS ABI has special rules to process GOT entries and doesn't
> +        // require relocation entries for them. A special case is TLS
> +        // relocations. In that case dynamic loader applies dynamic
> +        // relocations to initialize TLS GOT entries.
> +        // See "Global Offset Table" in Chapter 5 in the following document
> +        // for detailed description:
> +        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
> +        In<ELFT>::MipsGot->addEntry(Body, Addend, Expr);
> +        if (Body.isTls() && Body.isPreemptible())
> +          In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::MipsGot,
> +                                       Body.getGotOffset(), false, &Body, 0});
> +      } else if (!Body.isInGot()) {
> +        addGotEntry<ELFT>(Body, Preemptible);
> +      }
> +    }
>
>      if (!needsPlt(Expr) && !refersToGotEntry(Expr) &&
>          isPreemptible(Body, Type)) {
> @@ -863,7 +894,7 @@ static void scanRelocs(InputSectionBase
>      }
>
>      // If the relocation points to something in the file, we can process it.
> -    bool Constant =
> +    bool IsConstant =
>          isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, Sec, Rel.r_offset);
>
>      // If the output being produced is position independent, the final value
> @@ -871,53 +902,15 @@ static void scanRelocs(InputSectionBase
>      // dynamic linker. We can however do better than just copying the incoming
>      // relocation. We can process some of it and and just ask the dynamic
>      // linker to add the load address.
> -    if (!Constant)
> +    if (!IsConstant)
>        In<ELFT>::RelaDyn->addReloc(
>            {Target->RelativeRel, &Sec, Offset, true, &Body, Addend});
>
>      // If the produced value is a constant, we just remember to write it
>      // when outputting this section. We also have to do it if the format
>      // uses Elf_Rel, since in that case the written value is the addend.
> -    if (Constant || !RelTy::IsRela)
> +    if (IsConstant || !RelTy::IsRela)
>        Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
> -
> -    // At this point we are done with the relocated position. Some relocations
> -    // also require us to create a got or plt entry.
> -
> -    // If a relocation needs PLT, we create a PLT and a GOT slot for the symbol.
> -    if (needsPlt(Expr)) {
> -      if (Body.isInPlt())
> -        continue;
> -
> -      if (Body.isGnuIFunc() && !Preemptible)
> -        addPltEntry(InX::Iplt, In<ELFT>::IgotPlt, In<ELFT>::RelaIplt,
> -                    Target->IRelativeRel, Body, true);
> -      else
> -        addPltEntry(InX::Plt, In<ELFT>::GotPlt, In<ELFT>::RelaPlt,
> -                    Target->PltRel, Body, !Preemptible);
> -      continue;
> -    }
> -
> -    if (refersToGotEntry(Expr)) {
> -      if (Config->EMachine == EM_MIPS) {
> -        // MIPS ABI has special rules to process GOT entries and doesn't
> -        // require relocation entries for them. A special case is TLS
> -        // relocations. In that case dynamic loader applies dynamic
> -        // relocations to initialize TLS GOT entries.
> -        // See "Global Offset Table" in Chapter 5 in the following document
> -        // for detailed description:
> -        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
> -        In<ELFT>::MipsGot->addEntry(Body, Addend, Expr);
> -        if (Body.isTls() && Body.isPreemptible())
> -          In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::MipsGot,
> -                                       Body.getGotOffset(), false, &Body, 0});
> -        continue;
> -      }
> -
> -      if (!Body.isInGot())
> -        addGotEntry<ELFT>(Body, Preemptible);
> -      continue;
> -    }
>    }
>  }
>
>
>
> _______________________________________________
> 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