This is an archive of the discontinued LLVM Phabricator instance.

Add a CIE with length 0 unconditionally.
ClosedPublic

Authored by MaskRay on May 7 2018, 5:35 PM.

Details

Summary

This is not technically required, but glibc unwind-dw2-fde.c classify_object_over_fdes expects there is a CIE record length 0 as a terminator.

Diff Detail

Repository
rLLD LLVM Linker

Event Timeline

MaskRay created this revision.May 7 2018, 5:35 PM
ruiu accepted this revision.May 7 2018, 5:38 PM

LGTM

Thanks!

ELF/SyntheticSections.cpp
502

one -> a terminator

This revision is now accepted and ready to land.May 7 2018, 5:38 PM
This revision was automatically updated to reflect the committed changes.
grimar added a subscriber: grimar.May 10 2018, 2:35 AM

I would like tounderstand why this is needed.
You wrote: "This is not technically required, but glibc unwind-dw2-fde.c classify_object_over_fdes expects there is a CIE record length 0 as a terminator.".

Can you please point me on a line of code in glibc that needs this change in the linker? What is the current behavior of LLD linked binaries?

ELF/SyntheticSections.cpp
502

I think would be nice for that comment to contain some additional information, like:

  1. A version of glibc code this code is targeted to fix.
  2. Current date at which we are observing the issue.
  3. Reference to a corresponding bug in their bug tracker.
  4. Maybe information about what GNU linkers do can be also useful to have.

https://code.woboq.org/userspace/glibc/sysdeps/generic/unwind-dw2-fde.c.html#645

for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))

last_fde is defined at https://code.woboq.org/userspace/glibc/sysdeps/generic/unwind-dw2-fde.h.html#162 . It does not check whether it reaches the end of .eh_frame (DWARF2_OBJECT_END_PTR_EXTENSION seems not defined). If there is no length=0 terminator, the pointer will run beyond the end of .eh_frame and run into successive sections (out-of-bound read), segfault or stop somewhere. This issue is usually latent/benign and I can only catch this in some internal statically-linked configuration. I don't have time to read the whole source code of how glibc/libgcc_s libunwind to understand why this routine is sometimes called but sometimes not.

This is not a bug in glibc if we don't take behavior difference as a bug. bfd/gold seem to add a CIE of length=0 anyway so this piece of glibc/libgcc_s libunwind code won't go wrong.