[PATCH] D31664: [LLD][ELF] Prefer placing ThunkSections before non ThunkSections

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri May 5 11:20:14 PDT 2017


I would probably delay it until it can be tested.

Cheers,
Rafael

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

> peter.smith created this revision.
> Herald added subscribers: rengolin, aemerson.
>
> When there is an inline thunks such as the Mips LA25 and a non inline thunk in the same OutputSection at the same OutSecOff we must make sure that we output the inline thunk last as control may drop through.
>
> At present we haven't implemented any ARM inline thunks yet, and there aren't any non-inline thunks for Mips so this change may not be necessary just yet.
>
>
> https://reviews.llvm.org/D31664
>
> Files:
>   ELF/Relocations.cpp
>
>
> Index: ELF/Relocations.cpp
> ===================================================================
> --- ELF/Relocations.cpp
> +++ ELF/Relocations.cpp
> @@ -949,6 +949,14 @@
>  
>      // Order Thunks in ascending OutSecOff
>      auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
> +      if (A->OutSecOff == B->OutSecOff) {
> +        // If we have two ThunkSections at the same address and one has a
> +        // specific Target then the specific Target comes last as control may
> +        // fall through from the Thunk to the Target
> +        if (!A->getTargetInputSection() && B->getTargetInputSection())
> +          return true;
> +        return false;
> +      }
>        return A->OutSecOff < B->OutSecOff;
>      };
>      std::stable_sort(ThunkBegin, ThunkEnd, ThunkCmp);
> @@ -960,12 +968,18 @@
>        // std::merge requires a strict weak ordering.
>        if (A->OutSecOff < B->OutSecOff)
>          return true;
> -      if (A->OutSecOff == B->OutSecOff)
> +      if (A->OutSecOff == B->OutSecOff) {
> +        auto *TA = dyn_cast<ThunkSection>(A);
> +        auto *TB = dyn_cast<ThunkSection>(B);
>          // Check if Thunk is immediately before any specific Target InputSection
>          // for example Mips LA25 Thunks.
> -        if (auto *TA = dyn_cast<ThunkSection>(A))
> -          if (TA && TA->getTargetInputSection() == B)
> -            return true;
> +        if (TA && TA->getTargetInputSection() == B)
> +          return true;
> +        else if (TA && !TB && !TA->getTargetInputSection())
> +          // In general place Thunk Sections without specific targets before
> +          // non-Thunk Sections
> +          return true;
> +      }
>        return false;
>      };
>      std::merge(OS->Sections.begin(), OS->Sections.end(), ThunkBegin, ThunkEnd,
>
>
> Index: ELF/Relocations.cpp
> ===================================================================
> --- ELF/Relocations.cpp
> +++ ELF/Relocations.cpp
> @@ -949,6 +949,14 @@
>  
>      // Order Thunks in ascending OutSecOff
>      auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
> +      if (A->OutSecOff == B->OutSecOff) {
> +        // If we have two ThunkSections at the same address and one has a
> +        // specific Target then the specific Target comes last as control may
> +        // fall through from the Thunk to the Target
> +        if (!A->getTargetInputSection() && B->getTargetInputSection())
> +          return true;
> +        return false;
> +      }
>        return A->OutSecOff < B->OutSecOff;
>      };
>      std::stable_sort(ThunkBegin, ThunkEnd, ThunkCmp);
> @@ -960,12 +968,18 @@
>        // std::merge requires a strict weak ordering.
>        if (A->OutSecOff < B->OutSecOff)
>          return true;
> -      if (A->OutSecOff == B->OutSecOff)
> +      if (A->OutSecOff == B->OutSecOff) {
> +        auto *TA = dyn_cast<ThunkSection>(A);
> +        auto *TB = dyn_cast<ThunkSection>(B);
>          // Check if Thunk is immediately before any specific Target InputSection
>          // for example Mips LA25 Thunks.
> -        if (auto *TA = dyn_cast<ThunkSection>(A))
> -          if (TA && TA->getTargetInputSection() == B)
> -            return true;
> +        if (TA && TA->getTargetInputSection() == B)
> +          return true;
> +        else if (TA && !TB && !TA->getTargetInputSection())
> +          // In general place Thunk Sections without specific targets before
> +          // non-Thunk Sections
> +          return true;
> +      }
>        return false;
>      };
>      std::merge(OS->Sections.begin(), OS->Sections.end(), ThunkBegin, ThunkEnd,


More information about the llvm-commits mailing list