[PATCH][cxxabi] Add support for Bitrig

Patrick Wildt mail at patrick-wildt.de
Sun Apr 27 11:11:43 PDT 2014


Hi,

I've been working on porting libc++/libc++abi to Bitrig.

The following patch adds an unwind config for Bitrig and
support for parsing the ELF's eh_frame_hdr to find the eh_frame.

The ELF part probably works for other OSes, too.  Still, I have fenced
it under __Bitrig__, as I have not tested it on other systems.

I'd be glad if someone had the chance to try it on other OSes.

\Patrick

diff --git a/src/Unwind/AddressSpace.hpp b/src/Unwind/AddressSpace.hpp
index ceab016..353fe2d 100644
--- a/src/Unwind/AddressSpace.hpp
+++ b/src/Unwind/AddressSpace.hpp
@@ -289,6 +289,85 @@ inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
   #endif
 #endif
 
+#if __Bitrig__
+  #include <link_elf.h>
+  #define PT_EH_FRAME_HDR (PT_LOOS + 0x474e550)
+
+  struct dl_unwind_sections
+  {
+    uintptr_t			 base;
+    const void			*dwarf_section;
+    uintptr_t			 dwarf_section_length;
+    const void			*compact_unwind_section;
+    uintptr_t			 compact_unwind_section_length;
+  };
+
+  struct eh_frame_hdr
+  {
+    uint8_t			 version;
+    uint8_t			 eh_frame_ptr_enc;
+    uint8_t			 fde_count_enc;
+    uint8_t			 table_enc;
+    uint8_t			 data[0];
+  };
+
+  struct _dl_iterate_struct
+  {
+    Elf_Addr			 addr;
+    Elf_Addr			 base;
+    Elf_Phdr			*eh_frame_hdr;
+  };
+
+  static int _dl_iterate_cb(struct dl_phdr_info *dlpi, size_t size, void* data) {
+    struct _dl_iterate_struct *dlis = (struct _dl_iterate_struct *)data;
+    Elf_Phdr *phdr = (Elf_Phdr *)dlpi->dlpi_phdr;
+    int idx, found = 0;
+
+    for (idx = 0; idx < dlpi->dlpi_phnum; idx++, phdr++) {
+      if (phdr->p_type == PT_LOAD) {
+        Elf_Addr vaddr = dlpi->dlpi_addr + phdr->p_vaddr;
+        if (dlis->addr >= vaddr && dlis->addr < (vaddr + phdr->p_memsz))
+          found = 1;
+      } else if (phdr->p_type == PT_EH_FRAME_HDR)
+        dlis->eh_frame_hdr = phdr;
+    }
+
+    dlis->base = dlpi->dlpi_addr;
+    return found;
+  }
+
+  static inline bool _dl_find_unwind_sections(void *addr,
+      dl_unwind_sections *info) {
+
+    LocalAddressSpace::pint_t encoded, end;
+    struct _dl_iterate_struct dlis;
+    struct eh_frame_hdr *ehfh;
+    Elf_Phdr *phdr;
+    int idx;
+
+    dlis.addr = (Elf_Addr)addr;
+    if (!dl_iterate_phdr(_dl_iterate_cb, &dlis))
+      return false;
+
+    phdr = (Elf_Phdr *)dlis.eh_frame_hdr;
+    ehfh = (struct eh_frame_hdr *)(dlis.base + phdr->p_vaddr);
+
+    encoded = (LocalAddressSpace::pint_t)&ehfh->data;
+    end = (LocalAddressSpace::pint_t)ehfh + phdr->p_memsz;
+
+    // Fill in return struct.
+    info->base = dlis.base;
+    info->dwarf_section = (const void *)LocalAddressSpace::sThisAddressSpace
+        .getEncodedP(encoded, end, ehfh->eh_frame_ptr_enc);
+    /* XXX: We don't know how big it is, shouldn't be bigger than this. */
+    info->dwarf_section_length = 0x00ffffff;
+    info->compact_unwind_section = 0;
+    info->compact_unwind_section_length = 0;
+
+    return true;
+  }
+#endif
+
 inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
                                                   UnwindInfoSections &info) {
 #if __APPLE__
@@ -303,6 +382,18 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
     info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length;
     return true;
   }
+#elif __Bitrig__
+  dl_unwind_sections dlInfo;
+  if (_dl_find_unwind_sections((void *)targetAddr, &dlInfo)) {
+    info.dso_base                      = (uintptr_t)dlInfo.base;
+ #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
+    info.dwarf_section                 = (uintptr_t)dlInfo.dwarf_section;
+    info.dwarf_section_length          = dlInfo.dwarf_section_length;
+ #endif
+    info.compact_unwind_section        = (uintptr_t)dlInfo.compact_unwind_section;
+    info.compact_unwind_section_length = dlInfo.compact_unwind_section_length;
+    return true;
+  }
 #else
   // TO DO
 
diff --git a/src/Unwind/config.h b/src/Unwind/config.h
index 7d7e6bf..fdae1de 100644
--- a/src/Unwind/config.h
+++ b/src/Unwind/config.h
@@ -56,6 +56,17 @@
     #define _LIBUNWIND_SUPPORT_DWARF_INDEX    0
   #endif
 
+#elif __Bitrig__
+  #define _LIBUNWIND_BUILD_ZERO_COST_APIS (__i386__ || __x86_64__ || __arm64__)
+  #define _LIBUNWIND_BUILD_SJLJ_APIS      (__arm__)
+  #define _LIBUNWIND_SUPPORT_FRAME_APIS   (__i386__ || __x86_64__)
+  #define _LIBUNWIND_EXPORT               __attribute__((visibility("default")))
+  #define _LIBUNWIND_HIDDEN               __attribute__((visibility("hidden")))
+  #define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
+  #define _LIBUNWIND_ABORT(msg) __assert2(__FILE__, __LINE__, __func__, msg)
+  #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
+  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
+  #define _LIBUNWIND_SUPPORT_DWARF_INDEX    0
 #else
   // #define _LIBUNWIND_BUILD_ZERO_COST_APIS
   // #define _LIBUNWIND_BUILD_SJLJ_APIS




More information about the cfe-commits mailing list