[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