[libcxx-commits] [PATCH] D75781: Rework findUnwindSectionsByPhdr to be more optimal.

Sterling Augustine via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Mar 6 16:02:58 PST 2020


saugustine created this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.

- Executable segment is usually segment 3. Look there for the address first.
- GNU_EH_FRAME_HEADER segment is usually near the end. Iterate from the end.
- Exit early if both phdrs have been found.

This is the last cl before a patch to cache the information this function
finds.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75781

Files:
  libunwind/src/AddressSpace.hpp


Index: libunwind/src/AddressSpace.hpp
===================================================================
--- libunwind/src/AddressSpace.hpp
+++ libunwind/src/AddressSpace.hpp
@@ -452,31 +452,38 @@
     #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
   #endif
 
-int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t, void *data) {
-  auto *cbdata = static_cast<dl_iterate_cb_data *>(data);
-  bool found_obj = false;
-  bool found_hdr = false;
-
-  assert(cbdata);
-  assert(cbdata->sects);
+static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,
+                               dl_iterate_cb_data *cbdata) {
+  if (phdr->p_type == PT_LOAD) {
+    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;
+      cbdata->sects->dwarf_section_length = phdr->p_memsz;
+      return true;
+    }
+  }
+  return false;
+}
 
-  if (cbdata->targetAddr < pinfo->dlpi_addr)
+int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t, void *data) {
+  auto cbdata = static_cast<dl_iterate_cb_data *>(data);
+  if (pinfo->dlpi_phnum == 0)
     return 0;
 
   Elf_Addr image_base = calculateImageBase(pinfo);
-  size_t object_length;
+  bool found_obj = false;
+  bool found_hdr = false;
 
-  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 = image_base + phdr->p_vaddr;
-      uintptr_t end = begin + phdr->p_memsz;
-      if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
-        cbdata->sects->dso_base = begin;
-        object_length = phdr->p_memsz;
-        found_obj = true;
-      }
-    } else if (phdr->p_type == PT_GNU_EH_FRAME) {
+  // Third phdr is usually the executable phdr.
+  if (pinfo->dlpi_phnum > 2)
+    found_obj = checkAddrInSegment(&pinfo->dlpi_phdr[2], image_base, cbdata);
+
+  // PT_GNU_EH_FRAME is usually near the end. Iterate backward. We already know
+  // that there is one or more phdrs.
+  for (Elf_Half i = pinfo->dlpi_phnum; i > 0; i--) {
+    const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i - 1];
+    if (!found_hdr && phdr->p_type == PT_GNU_EH_FRAME) {
       EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
       uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr;
       cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
@@ -486,15 +493,14 @@
           hdrInfo);
       if (found_hdr)
         cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
+    } else if (!found_obj) {
+      found_obj = checkAddrInSegment(phdr, image_base, cbdata);
     }
+    if (found_obj && found_hdr)
+      return 1;
   }
-
-  if (found_obj && found_hdr) {
-    cbdata->sects->dwarf_section_length = object_length;
-    return true;
-  } else {
-    return false;
-  }
+  cbdata->sects->dwarf_section_length = 0;
+  return 0;
 }
 
 #else  // defined(LIBUNWIND_SUPPORT_DWARF_UNWIND)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75781.248856.patch
Type: text/x-patch
Size: 3067 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20200307/78144156/attachment-0001.bin>


More information about the libcxx-commits mailing list