[lld] r256141 - [ELF] - Fixed padding for CIE/FDE entries of .eh_frame section

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 24 12:57:42 PST 2015


Alignment in .eh_frame is quite nasty :-(

The alignment requirement shouldn't need to be to a pointer size. For
example, a 4 byte offset is normally used on x86_64.

When using a linker that just concatenates the .eh_frame sections, the
producer has to be careful to make the size *of the entire section* a
multiple of the pointer size. This is because some other file might
have an .eh_frame with an alignment of 8 and the zero padding would be
read as a terminator.

A side effect of making the section a multiple of 8 is that both MC as
GAS give it an alignment of 8. With that it becomes non trivial for
the linker to know the alignment requirements of each cie/fde and it
has to overcompensate.

I fixed a missed case in r256392: the CIE size was not updated.

Probably by now it is safe for MC to assume every linker processes
.eh_frame. With that it could produce .eh_frame sections with an
alignment of 4 and we could remember the alignment of each cie/fde to
produce a more compact result. (I will open a bug).

Cheers,
Rafael





On 21 December 2015 at 04:38, George Rimar via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: grimar
> Date: Mon Dec 21 03:38:59 2015
> New Revision: 256141
>
> URL: http://llvm.org/viewvc/llvm-project?rev=256141&view=rev
> Log:
> [ELF] - Fixed padding for CIE/FDE entries of .eh_frame section
>
> Spec says both CIE/FDE has "Padding
> Extra bytes to align the CIE structure to an addressing unit size boundary."
> https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
>
> Patch aligns CIE/FDE entries to the size of platform pointer.
>
> Differential revision: http://reviews.llvm.org/D15637
>
> Modified:
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/test/ELF/eh-frame-merge.s
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=256141&r1=256140&r2=256141&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Mon Dec 21 03:38:59 2015
> @@ -971,7 +971,7 @@ void EHOutputSection<ELFT>::addSectionAu
>        auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size()));
>        if (P.second) {
>          Cies.push_back(C);
> -        this->Header.sh_size += Length;
> +        this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t));
>        }
>        OffsetToIndex[Offset] = P.first->second;
>      } else {
> @@ -984,7 +984,7 @@ void EHOutputSection<ELFT>::addSectionAu
>          if (I == OffsetToIndex.end())
>            error("Invalid CIE reference");
>          Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
> -        this->Header.sh_size += Length;
> +        this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t));
>        }
>      }
>
> @@ -1040,15 +1040,16 @@ template <class ELFT> void EHOutputSecti
>      StringRef CieData = C.data();
>      memcpy(Buf + Offset, CieData.data(), CieData.size());
>      C.S->Offsets[C.Index].second = Offset;
> -    Offset += CieData.size();
> +    Offset += RoundUpToAlignment(CieData.size(), sizeof(uintX_t));
>
>      for (const EHRegion<ELFT> &F : C.Fdes) {
>        StringRef FdeData = F.data();
> -      memcpy(Buf + Offset, FdeData.data(), 4);              // Length
> +      uintX_t Len = RoundUpToAlignment(FdeData.size(), sizeof(uintX_t));
> +      write32<E>(Buf + Offset, Len - 4);                    // Length
>        write32<E>(Buf + Offset + 4, Offset + 4 - CieOffset); // Pointer
>        memcpy(Buf + Offset + 8, FdeData.data() + 8, FdeData.size() - 8);
>        F.S->Offsets[F.Index].second = Offset;
> -      Offset += FdeData.size();
> +      Offset += Len;
>      }
>    }
>
>
> Modified: lld/trunk/test/ELF/eh-frame-merge.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/eh-frame-merge.s?rev=256141&r1=256140&r2=256141&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/eh-frame-merge.s (original)
> +++ lld/trunk/test/ELF/eh-frame-merge.s Mon Dec 21 03:38:59 2015
> @@ -27,18 +27,18 @@
>  // CHECK-NEXT: ]
>  // CHECK-NEXT: Address:
>  // CHECK-NEXT: Offset:
> -// CHECK-NEXT: Size:
> +// CHECK-NEXT: Size: 96
>  // CHECK-NEXT: Link: 0
>  // CHECK-NEXT: Info: 0
>  // CHECK-NEXT: AddressAlignment: 8
>  // CHECK-NEXT: EntrySize: 0
>  // CHECK-NEXT: SectionData (
> -// CHECK-NEXT:   0000: 14000000 00000000 017A5200 01781001  |
> -// CHECK-NEXT:   0010: 1B0C0708 90010000 10000000 1C000000  |
> -// CHECK-NEXT:   0020: 180E0000 01000000 00000000 10000000  |
> -// CHECK-NEXT:   0030: 30000000 060E0000 02000000 00000000  |
> -// CHECK-NEXT:   0040: 10000000 44000000 F10D0000 01000000  |
> -// CHECK-NEXT:   0050: 00000000                             |
> +// CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001  |
> +// CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000  |
> +// CHECK-NEXT: 0020: 180E0000 01000000 00000000 00000000  |
> +// CHECK-NEXT: 0030: 14000000 34000000 020E0000 02000000  |
> +// CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000  |
> +// CHECK-NEXT: 0050: E90D0000 01000000 00000000 00000000  |
>  // CHECK-NEXT: )
>
>  // CHECK:      Name: foo
>
>
> _______________________________________________
> 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