[libunwind] r299575 - Fix invalid memory access on android x86

Saleem Abdulrasool via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 5 11:33:24 PDT 2017


Author: compnerd
Date: Wed Apr  5 13:33:23 2017
New Revision: 299575

URL: http://llvm.org/viewvc/llvm-project?rev=299575&view=rev
Log:
Fix invalid memory access on android x86

On certain versions of android x86, the main module `app_process` is not
built as PIE.  When accessing the PT_GNU_EH_FRAME_HDR in such a
scenario, the `dlpi_addr` is 0, but the virtual address is not
relocated.  Manually rebase the address to avoid an invalid memory
access.

Modified:
    libunwind/trunk/src/AddressSpace.hpp

Modified: libunwind/trunk/src/AddressSpace.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=299575&r1=299574&r2=299575&view=diff
==============================================================================
--- libunwind/trunk/src/AddressSpace.hpp (original)
+++ libunwind/trunk/src/AddressSpace.hpp Wed Apr  5 13:33:23 2017
@@ -383,16 +383,29 @@ inline bool LocalAddressSpace::findUnwin
 #if !defined(Elf_Phdr)
         typedef ElfW(Phdr) Elf_Phdr;
 #endif
+#if !defined(Elf_Addr)
+        typedef ElfW(Addr) Elf_Addr;
+#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__)
+        Elf_Addr image_base =
+            reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
+            reinterpret_cast<const Elf_Phdr *>(pinfo->dlpi_phdr)->p_offset;
+#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 end = begin + phdr->p_memsz;
             if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
               cbdata->sects->dso_base = begin;
@@ -402,6 +415,10 @@ inline bool LocalAddressSpace::findUnwin
           } 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
             cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
             cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
             EHHeaderParser<LocalAddressSpace>::decodeEHHdr(




More information about the cfe-commits mailing list