[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