[libcxx-commits] [PATCH] D133846: [libunwind] Fix usage of `_dl_find_object` on 32-bit x86
Adrian Vogelsgesang via Phabricator via libcxx-commits
libcxx-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/libcxx-commits/attachments/20220914/7a9df98b/attachment.bin>
More information about the libcxx-commits
mailing list