This is an archive of the discontinued LLVM Phabricator instance.

[UNWIND] Handle non-existing FDE count / search table
Needs ReviewPublic

Authored by Bluerise on Sep 4 2016, 8:25 AM.

Details

Reviewers
emaste
joerg
Summary

On OpenBSD the binutils 2.17 linker in combination with clang++ 3.8.1 seems to produce an EH frame for statically linked binaries that does omit the fde count and the binary table. Unfortunately the code does not handle this scenario and will blow up. If we just return when it's omitted the fallback code will look through the full table and there the unwinding works.

Diff Detail

Repository
rL LLVM

Event Timeline

Bluerise updated this revision to Diff 70290.Sep 4 2016, 8:25 AM
Bluerise retitled this revision from to [UNWIND] Handle non-existing FDE count / search table.
Bluerise updated this object.
Bluerise set the repository for this revision to rL LLVM.
Bluerise added a subscriber: llvm-commits.
Bluerise updated this object.
joerg edited edge metadata.Sep 5 2016, 3:44 PM

The first chunk matches something I have in the NetBSD version, that one is fine. The rest looks like bugs in ld...

Not sure. binutils seems to only conditionally set fde_count.

joerg added a comment.Sep 5 2016, 3:57 PM

Let me qualify that a bit. A FDE count of 0 can happen, if a DSO absolutely has no FDE entries at all. That's all the short cut that should be needed. A table entry format of DW_EH_PE_omit is only ever valid in combination with FDE count of 0, so that should be an assert at most. I'm trying to remember if table encodings other than sdata4+datarel are valid at all, but I can't find the specification right now.

Do you have a diff that you'd propose?

emaste edited edge metadata.Sep 8 2016, 7:21 AM

For future uploads can you please include context (git diff -U9999, svn diff --diff-cmd=diff -x -U999999 etc.)

src/AddressSpace.hpp
224–226

This is the one in NetBSD already (although as return 0). @joerg also has another case there:

  if (encoding == DW_EH_PE_omit)
    return 0;
  if (encoding == DW_EH_PE_aligned) {
    addr = (addr + sizeof(pint_t) - 1) & sizeof(pint_t);
    return getP(addr);
  }

// first get value

@joerg would you upstream these changes from NetBSD's copy?