#include "mini-unwind.h"
#include <mono/utils/mono-counters.h>
+#include <mono/utils/freebsd-dwarf.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/mono-endian.h>
dwarf_reg_to_hw_reg_inited = TRUE;
}
-static inline int
+int
mono_dwarf_reg_to_hw_reg (int reg)
{
if (!dwarf_reg_to_hw_reg_inited)
* Decode the Language Specific Data Area generated by LLVM.
*/
static void
-decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info)
+decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info, int *this_reg, int *this_offset)
{
gint32 ttype_offset, call_site_length;
gint32 ttype_encoding, call_site_encoding;
*/
p = lsda;
- /* Read @LPStart */
- g_assert (*p == DW_EH_PE_omit);
- p ++;
+ if (*p == DW_EH_PE_udata4) {
+ /* This is the modified LSDA generated by the LLVM mono branch */
+ guint32 mono_magic, version;
+ gint32 op, reg, offset;
+
+ p ++;
+ mono_magic = decode_uleb128 (p, &p);
+ g_assert (mono_magic == 0x4d4fef4f);
+ version = decode_uleb128 (p, &p);
+ g_assert (version == 1);
+
+ /* 'this' location */
+ op = *p;
+ g_assert (op == DW_OP_bregx);
+ p ++;
+ reg = decode_uleb128 (p, &p);
+ offset = decode_sleb128 (p, &p);
+
+ *this_reg = mono_dwarf_reg_to_hw_reg (reg);
+ *this_offset = offset;
+ } else {
+ /* Read @LPStart */
+ g_assert (*p == DW_EH_PE_omit);
+ p ++;
+
+ *this_reg = -1;
+ *this_offset = -1;
+ }
/* Read @TType */
ttype_encoding = *p;
* LSDA.
*/
guint8*
-mono_unwind_decode_fde (guint8 *fde, guint32 *out_len, guint32 *code_len, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info)
+mono_unwind_decode_fde (guint8 *fde, guint32 *out_len, guint32 *code_len, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info, int *this_reg, int *this_offset)
{
guint8 *p, *cie, *fde_current, *fde_aug, *code, *fde_cfi, *cie_cfi;
gint32 fde_len, cie_offset, pc_begin, pc_range, aug_len, fde_data_len;
* http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
*/
+ *this_reg = -1;
+ *this_offset = -1;
+
/* Decode FDE */
p = fde;
if (lsda_offset != 0) {
lsda = fde_aug + *(gint32*)fde_aug;
- decode_lsda (lsda, code, ex_info, ex_info_len, type_info);
+ decode_lsda (lsda, code, ex_info, ex_info_len, type_info, this_reg, this_offset);
}
}