[PATCH] D133846: [libunwind] Fix usage of `_dl_find_object` on 32-bit x86

Adrian Vogelsgesang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 14 03:42:33 PDT 2022


avogelsgesang created this revision.
Herald added subscribers: libcxx-commits, pengfei.
Herald added projects: libunwind, All.
Herald added a reviewer: libunwind.
avogelsgesang requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

On 32-bit x86, `_dl_find_object` also returns a `dlfo_eh_dbase` address
which is the base address for all DW_EH_PE_datarel relocations. So far,
compiling against a version of `_dl_find_object` which returns a
`dlfo_eh_dbase` was blocked using a `#if` + `#error`.

This commit now adds partial support for `_dl_find_object` such that
libunwind works on 32-bit x86 again. We do so by asserting that
`dlfo_eh_dbase` equals `dlfo_map_start`, because this is the only case
currently supported by libunwind.

My reasoning that libunwind only supports `dlfo_eh_dbase == dlfo_map_start`:

- Looking at `LocalAddressSpace::getEncodedP`, we see that `DW_EH_PE_datarel` is only supported if `datarelBase` is set.
- The only places which passes a non-zero `datarelBase` are `EHHeaderParser<A>::{decodeEHHdr,findFDE}`. Both those invocations pass `ehHdrStart` as `datarelBase`.
- The invocations of `EHHeaderParser<A>::{decodeEHHdr,findFDE}` pass `info.dwarf_index_section` as `ehHdrStart`.
- `info.dwarf_index_section` is identical to `dlfo_map_start`.

Hence, in case `dlfo_eh_dbase != dlfo_map_start`, libunwind would apply
invalid relocations for `DW_EH_PE_datarel`. The `assert` added in this
change guards against this.

Fixes #57733


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133846

Files:
  libunwind/src/AddressSpace.hpp


Index: libunwind/src/AddressSpace.hpp
===================================================================
--- libunwind/src/AddressSpace.hpp
+++ libunwind/src/AddressSpace.hpp
@@ -584,11 +584,6 @@
   // support for _dl_find_object on other unwind formats is not implemented,
   // yet.
 #if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
-  // We expect to run on a platform which does not use a base address for
-  // exception information.
-#if DLFO_STRUCT_HAS_EH_DBASE
-#error dlfo_eh_dbase is not supported for DWARF-based unwinding
-#endif
   // We expect `_dl_find_object` to return PT_GNU_EH_FRAME.
 #if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME
 #error _dl_find_object retrieves an unexpected section type
@@ -611,6 +606,11 @@
       // Found an entry for `targetAddr`, but there is no unwind info.
       return false;
     }
+#if DLFO_STRUCT_HAS_EH_DBASE
+    assert(findResult.dlfo_eh_dbase == findResult.dlfo_map_start &&
+          "libunwind expects the base address for DW_EH_PE_datarel to be identical"
+          "with the start address of the PT_GNU_EH_FRAME segment") ;
+#endif
     info.dso_base = reinterpret_cast<uintptr_t>(findResult.dlfo_map_start);
     info.text_segment_length = static_cast<size_t>(
         (char *)findResult.dlfo_map_end - (char *)findResult.dlfo_map_start);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D133846.460026.patch
Type: text/x-patch
Size: 1333 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220914/7a9df98b/attachment.bin>


More information about the llvm-commits mailing list