[libcxx-commits] [PATCH] D68971: [libunwind][Android] Improve workaround for PIE zero-dlpi_addr bug

Ryan Prichard via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 15 00:48:10 PDT 2019


rprichard updated this revision to Diff 224962.
rprichard added a comment.

Exclude an unrelated change from the base revision.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68971/new/

https://reviews.llvm.org/D68971

Files:
  libunwind/src/AddressSpace.hpp


Index: libunwind/src/AddressSpace.hpp
===================================================================
--- libunwind/src/AddressSpace.hpp
+++ libunwind/src/AddressSpace.hpp
@@ -497,32 +497,40 @@
 #if !defined(Elf_Phdr)
         typedef ElfW(Phdr) Elf_Phdr;
 #endif
+#if !defined(Elf_Addr)
+        typedef ElfW(Addr) Elf_Addr;
+#endif
+
+        Elf_Addr image_base = pinfo->dlpi_addr;
+
+#if defined(__ANDROID__) && __ANDROID_API__ < 18
+        if (image_base == 0) {
+          // Normally, an image base of 0 indicates a non-PIE executable. On
+          // versions of Android prior to API 18, the dynamic linker reported a
+          // dlpi_addr of 0 for PIE executables. Compute the true image base
+          // using the PT_PHDR segment.
+          // See https://github.com/android/ndk/issues/505.
+          for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
+            const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
+            if (phdr->p_type == PT_PHDR) {
+              image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
+                  phdr->p_vaddr;
+              break;
+            }
+          }
+        }
+#endif
 
  #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
    #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
   #endif
         size_t object_length;
-#if defined(__ANDROID__)
-#if !defined(Elf_Addr)
-        typedef ElfW(Addr) Elf_Addr;
-#endif
-        Elf_Addr image_base =
-            pinfo->dlpi_phnum
-                ? reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
-                      reinterpret_cast<const Elf_Phdr *>(pinfo->dlpi_phdr)
-                          ->p_offset
-                : 0;
-#endif
 
         for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
           const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
           if (phdr->p_type == PT_LOAD) {
-            uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
-#if defined(__ANDROID__)
-            if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base)
-              begin = begin + image_base;
-#endif
+            uintptr_t begin = image_base + phdr->p_vaddr;
             uintptr_t end = begin + phdr->p_memsz;
             if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
               cbdata->sects->dso_base = begin;
@@ -531,11 +539,7 @@
             }
           } else if (phdr->p_type == PT_GNU_EH_FRAME) {
             EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
-            uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr;
-#if defined(__ANDROID__)
-            if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base)
-              eh_frame_hdr_start = eh_frame_hdr_start + image_base;
-#endif
+            uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr;
             cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
             cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
             found_hdr = EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
@@ -556,12 +560,12 @@
         for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
           const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
           if (phdr->p_type == PT_LOAD) {
-            uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
+            uintptr_t begin = image_base + phdr->p_vaddr;
             uintptr_t end = begin + phdr->p_memsz;
             if (cbdata->targetAddr >= begin && cbdata->targetAddr < end)
               found_obj = true;
           } else if (phdr->p_type == PT_ARM_EXIDX) {
-            uintptr_t exidx_start = pinfo->dlpi_addr + phdr->p_vaddr;
+            uintptr_t exidx_start = image_base + phdr->p_vaddr;
             cbdata->sects->arm_section = exidx_start;
             cbdata->sects->arm_section_length = phdr->p_memsz;
             found_hdr = true;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D68971.224962.patch
Type: text/x-patch
Size: 3874 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20191015/8e149c58/attachment-0001.bin>


More information about the libcxx-commits mailing list