fix _dyld_find_unwind_sections() for pre-10.7. Patch by Jeremy Sequoia
authorNick Kledzik <kledzik@apple.com>
Mon, 31 Oct 2016 21:04:17 +0000 (21:04 +0000)
committerNick Kledzik <kledzik@apple.com>
Mon, 31 Oct 2016 21:04:17 +0000 (21:04 +0000)
llvm-svn: 285636

libunwind/src/AddressSpace.hpp

index 2792e0e..67aa664 100644 (file)
@@ -321,28 +321,34 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
     // In 10.7.0 or later, libSystem.dylib implements this function.
     extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
   #else
-    // In 10.6.x and earlier, we need to implement this functionality.
+    // In 10.6.x and earlier, we need to implement this functionality. Note
+    // that this requires a newer version of libmacho (from cctools) than is
+    // present in libSystem on 10.6.x (for getsectiondata).
     static inline bool _dyld_find_unwind_sections(void* addr, 
                                                     dyld_unwind_sections* info) {
       // Find mach-o image containing address.
       Dl_info dlinfo;
       if (!dladdr(addr, &dlinfo))
         return false;
-      const mach_header *mh = (const mach_header *)dlinfo.dli_saddr;
-      
-      // Find DWARF unwind section in that image.
-      unsigned long size;
-      const uint8_t *p = getsectiondata(mh, "__TEXT", "__eh_frame", &size);
-      if (!p)
-        return false;
-      
-      // Fill in return struct.
-      info->mh = mh;
-      info->dwarf_section = p;
-      info->dwarf_section_length = size;
-      info->compact_unwind_section = 0;
-      info->compact_unwind_section_length = 0;
-     
+#if __LP64__
+      const struct mach_header_64 *mh = (const struct mach_header_64 *)dlinfo.dli_fbase;
+#else
+      const struct mach_header *mh = (const struct mach_header *)dlinfo.dli_fbase;
+#endif
+
+      // Initialize the return struct
+      info->mh = (const struct mach_header *)mh;
+      info->dwarf_section = getsectiondata(mh, "__TEXT", "__eh_frame", &info->dwarf_section_length);
+      info->compact_unwind_section = getsectiondata(mh, "__TEXT", "__unwind_info", &info->compact_unwind_section_length);
+
+      if (!info->dwarf_section) {
+        info->dwarf_section_length = 0;
+      }
+
+      if (!info->compact_unwind_section) {
+        info->compact_unwind_section_length = 0;
+      }
+
       return true;
     }
   #endif