You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.425
Former-commit-id: 56934f10a9ad11e3eb75c21da859e02f54766140
This commit is contained in:
parent
693afccc61
commit
2927bc3cc3
@@ -163,7 +163,10 @@ mono_type_get_desc (GString *res, MonoType *type, gboolean include_namespace)
|
||||
break;
|
||||
case MONO_TYPE_ARRAY:
|
||||
mono_type_get_desc (res, &type->data.array->eklass->byval_arg, include_namespace);
|
||||
g_string_append_printf (res, "[%d]", type->data.array->rank);
|
||||
g_string_append_c (res, '[');
|
||||
for (i = 1; i < type->data.array->rank; ++i)
|
||||
g_string_append_c (res, ',');
|
||||
g_string_append_c (res, ']');
|
||||
break;
|
||||
case MONO_TYPE_SZARRAY:
|
||||
mono_type_get_desc (res, &type->data.klass->byval_arg, include_namespace);
|
||||
|
||||
@@ -25,4 +25,10 @@ mono_exception_from_token_two_strings_checked (MonoImage *image, uint32_t token,
|
||||
MonoString *a1, MonoString *a2,
|
||||
MonoError *error);
|
||||
|
||||
|
||||
typedef int (*MonoGetSeqPointFunc) (MonoDomain *domain, MonoMethod *method, gint32 native_offset);
|
||||
|
||||
void
|
||||
mono_install_get_seq_point (MonoGetSeqPointFunc func);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1 +1 @@
|
||||
deecd47028339a9eccb62c62fcbb37e6f7ab5357
|
||||
4eb9a6416a9d3d3b7e5830b49dd0629e4c81cc9a
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <mono/metadata/gc-internals.h>
|
||||
#include <mono/metadata/mempool.h>
|
||||
#include <mono/metadata/debug-mono-ppdb.h>
|
||||
#include <mono/metadata/exception-internals.h>
|
||||
#include <mono/metadata/runtime.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
|
||||
@@ -861,6 +863,14 @@ mono_debug_free_source_location (MonoDebugSourceLocation *location)
|
||||
}
|
||||
}
|
||||
|
||||
static int (*get_seq_point) (MonoDomain *domain, MonoMethod *method, gint32 native_offset);
|
||||
|
||||
void
|
||||
mono_install_get_seq_point (MonoGetSeqPointFunc func)
|
||||
{
|
||||
get_seq_point = func;
|
||||
}
|
||||
|
||||
/**
|
||||
* mono_debug_print_stack_frame:
|
||||
* @native_offset: Native offset within the @method's machine code.
|
||||
@@ -891,10 +901,22 @@ mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDom
|
||||
offset = -1;
|
||||
}
|
||||
|
||||
if (offset < 0 && get_seq_point)
|
||||
offset = get_seq_point (domain, method, native_offset);
|
||||
|
||||
if (offset < 0)
|
||||
res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
|
||||
else
|
||||
res = g_strdup_printf ("at %s <IL 0x%05x, 0x%05x>", fname, offset, native_offset);
|
||||
else {
|
||||
char *mvid = mono_guid_to_string_minimal ((uint8_t*)method->klass->image->heap_guid.data);
|
||||
char *aotid = mono_runtime_get_aotid ();
|
||||
if (aotid)
|
||||
res = g_strdup_printf ("at %s [0x%05x] in <%s#%s>:0" , fname, offset, mvid, aotid);
|
||||
else
|
||||
res = g_strdup_printf ("at %s [0x%05x] in <%s>:0" , fname, offset, mvid);
|
||||
|
||||
g_free (aotid);
|
||||
g_free (mvid);
|
||||
}
|
||||
g_free (fname);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -140,3 +140,24 @@ mono_runtime_init_tls (void)
|
||||
mono_marshal_init_tls ();
|
||||
mono_thread_init_tls ();
|
||||
}
|
||||
|
||||
char*
|
||||
mono_runtime_get_aotid (void)
|
||||
{
|
||||
int i;
|
||||
guint8 aotid_sum = 0;
|
||||
MonoDomain* domain = mono_domain_get ();
|
||||
|
||||
if (!domain->entry_assembly || !domain->entry_assembly->image)
|
||||
return NULL;
|
||||
|
||||
guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
aotid_sum |= (*aotid)[i];
|
||||
|
||||
if (aotid_sum == 0)
|
||||
return NULL;
|
||||
|
||||
return mono_guid_to_string ((guint8*) aotid);
|
||||
}
|
||||
@@ -21,6 +21,8 @@ gboolean mono_runtime_is_critical_method (MonoMethod *method);
|
||||
gboolean mono_runtime_try_shutdown (void);
|
||||
|
||||
void mono_runtime_init_tls (void);
|
||||
|
||||
char* mono_runtime_get_aotid (void);
|
||||
MONO_END_DECLS
|
||||
|
||||
#endif /* _MONO_METADATA_RUNTIME_H_ */
|
||||
|
||||
@@ -439,7 +439,6 @@ common_sources = \
|
||||
graph.c \
|
||||
mini-codegen.c \
|
||||
mini-exceptions.c \
|
||||
mini-exceptions-native-unwinder.c \
|
||||
mini-trampolines.c \
|
||||
branch-opts.c \
|
||||
mini-generic-sharing.c \
|
||||
@@ -860,7 +859,7 @@ EXTRA_DIST = TestDriver.cs \
|
||||
Makefile.am.in
|
||||
|
||||
version.h: Makefile
|
||||
echo "#define FULL_VERSION \"Stable 4.8.0.395/df81fe4\"" > version.h
|
||||
echo "#define FULL_VERSION \"Stable 4.8.0.425/038ff4a\"" > version.h
|
||||
|
||||
# Utility target for patching libtool to speed up linking
|
||||
patch-libtool:
|
||||
|
||||
@@ -439,7 +439,6 @@ common_sources = \
|
||||
graph.c \
|
||||
mini-codegen.c \
|
||||
mini-exceptions.c \
|
||||
mini-exceptions-native-unwinder.c \
|
||||
mini-trampolines.c \
|
||||
branch-opts.c \
|
||||
mini-generic-sharing.c \
|
||||
@@ -860,7 +859,7 @@ EXTRA_DIST = TestDriver.cs \
|
||||
Makefile.am.in
|
||||
|
||||
version.h: Makefile
|
||||
echo "#define FULL_VERSION \"Stable 4.8.0.395/df81fe4\"" > version.h
|
||||
echo "#define FULL_VERSION \"Stable 4.8.0.425/038ff4a\"" > version.h
|
||||
|
||||
# Utility target for patching libtool to speed up linking
|
||||
patch-libtool:
|
||||
|
||||
@@ -1 +1 @@
|
||||
2128ee71f4bedcfbe65320e1befa9d3044dd5a0b
|
||||
63cf5db27f8b0ab65c05c36143e0abcf52bcdcf6
|
||||
@@ -1 +1 @@
|
||||
ab39180f7b19cdd884bb41bddd68fd3a34b1c44d
|
||||
4758c4dcfbe3bc5d33d3541f4cd96367f80f5f92
|
||||
@@ -1 +1 @@
|
||||
b2470bd1725bddc8d4b773a0150fdace813b5560
|
||||
989d1ceee9a69e6fa24b8a468e3ee04693b4a338
|
||||
@@ -1 +1 @@
|
||||
135519aac6d9aac84c8ac83259d5bb8ea8cc9c61
|
||||
8b0b61e62ad3a349c2c1721e0d36365f3697eccf
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* mini-exceptions-native-unwinder.c: libcorkscrew-based native unwinder
|
||||
*
|
||||
* Authors:
|
||||
* Alex Rønne Petersen (alexrp@xamarin.com)
|
||||
*
|
||||
* Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
#include <mono/utils/mono-logger-internals.h>
|
||||
|
||||
/*
|
||||
* Attempt to handle native SIGSEGVs with libunwind or libcorkscrew.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <mono/utils/mono-signal-handler.h>
|
||||
#include "mini.h"
|
||||
|
||||
#if defined (PLATFORM_ANDROID)
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <mono/utils/mono-dl.h>
|
||||
|
||||
#define UNW_LOCAL_ONLY
|
||||
#undef _U /* ctype.h apparently defines this and it screws up the libunwind headers. */
|
||||
#include "../../external/android-libunwind/include/libunwind.h"
|
||||
#define _U 0x01
|
||||
|
||||
#define FUNC_NAME_LENGTH 512
|
||||
#define FRAMES_TO_UNWIND 256
|
||||
|
||||
/* Expand the SYM argument. */
|
||||
#define LOAD_SYM(DL, ERR, SYM, VAR) _LOAD_SYM(DL, ERR, SYM, VAR)
|
||||
#define _LOAD_SYM(DL, ERR, SYM, VAR) \
|
||||
do { \
|
||||
if ((ERR = mono_dl_symbol (DL, #SYM, (void **) &VAR))) { \
|
||||
mono_dl_close (DL); \
|
||||
return ERR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef int (*unw_init_local_t) (unw_cursor_t *, unw_context_t *);
|
||||
typedef int (*unw_get_reg_t) (unw_cursor_t *, int, unw_word_t *);
|
||||
typedef int (*unw_get_proc_name_t) (unw_cursor_t *, char *, size_t, unw_word_t *);
|
||||
typedef int (*unw_step_t) (unw_cursor_t *);
|
||||
|
||||
static char *
|
||||
mono_extension_handle_native_sigsegv_libunwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info)
|
||||
{
|
||||
char *dl_err;
|
||||
int unw_err;
|
||||
|
||||
unw_init_local_t unw_init_local_fn;
|
||||
unw_get_reg_t unw_get_reg_fn;
|
||||
unw_get_proc_name_t unw_get_proc_name_fn;
|
||||
unw_step_t unw_step_fn;
|
||||
|
||||
unw_cursor_t cursor;
|
||||
|
||||
size_t frames = 0;
|
||||
|
||||
MonoDl *dl = mono_dl_open ("libunwind.so", MONO_DL_LAZY, &dl_err);
|
||||
|
||||
if (!dl)
|
||||
return dl_err;
|
||||
|
||||
LOAD_SYM (dl, dl_err, UNW_OBJ (init_local), unw_init_local_fn);
|
||||
LOAD_SYM (dl, dl_err, UNW_OBJ (get_reg), unw_get_reg_fn);
|
||||
LOAD_SYM (dl, dl_err, UNW_OBJ (get_proc_name), unw_get_proc_name_fn);
|
||||
LOAD_SYM (dl, dl_err, UNW_OBJ (step), unw_step_fn);
|
||||
|
||||
if ((unw_err = unw_init_local_fn (&cursor, ctx))) {
|
||||
mono_dl_close (dl);
|
||||
|
||||
return g_strdup_printf ("unw_init_local () returned %d", unw_err);
|
||||
}
|
||||
|
||||
do {
|
||||
int reg_err;
|
||||
|
||||
unw_word_t ip, off;
|
||||
char name [FUNC_NAME_LENGTH];
|
||||
|
||||
if ((reg_err = unw_get_reg_fn (&cursor, UNW_REG_IP, &ip))) {
|
||||
mono_runtime_printf_err ("unw_get_reg (UNW_REG_IP) returned %d", reg_err);
|
||||
break;
|
||||
}
|
||||
|
||||
reg_err = unw_get_proc_name_fn (&cursor, name, FUNC_NAME_LENGTH, &off);
|
||||
|
||||
if (reg_err == -UNW_ENOINFO)
|
||||
strcpy (name, "???");
|
||||
|
||||
mono_runtime_printf_err (" at %s+%zu [0x%zx]", name, off, ip);
|
||||
|
||||
unw_err = unw_step_fn (&cursor);
|
||||
frames++;
|
||||
} while (unw_err > 0 && frames < FRAMES_TO_UNWIND);
|
||||
|
||||
if (unw_err < 0)
|
||||
mono_runtime_printf_err ("unw_step () returned %d", unw_err);
|
||||
|
||||
mono_dl_close (dl);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This code is based on the AOSP header system/core/include/corkscrew/backtrace.h.
|
||||
*
|
||||
* This is copied here because libcorkscrew is not a stable library and the header (and
|
||||
* other headers that it depends on) will eventually go away.
|
||||
*
|
||||
* We can probably remove this one day when libunwind becomes the norm.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uintptr_t absolute_pc;
|
||||
uintptr_t stack_top;
|
||||
size_t stack_size;
|
||||
} backtrace_frame_t;
|
||||
|
||||
typedef struct {
|
||||
uintptr_t relative_pc;
|
||||
uintptr_t relative_symbol_addr;
|
||||
char *map_name;
|
||||
char *symbol_name;
|
||||
char *demangled_name;
|
||||
} backtrace_symbol_t;
|
||||
|
||||
typedef void (*get_backtrace_symbols_t) (const backtrace_frame_t *backtrace, size_t frames, backtrace_symbol_t *backtrace_symbols);
|
||||
typedef void (*free_backtrace_symbols_t) (backtrace_symbol_t *backtrace_symbols, size_t frames);
|
||||
|
||||
enum {
|
||||
MAX_BACKTRACE_LINE_LENGTH = 800,
|
||||
};
|
||||
|
||||
/* Internals that we're exploiting to work in a signal handler. Only works on ARM/x86. */
|
||||
|
||||
typedef struct map_info_t map_info_t;
|
||||
|
||||
typedef ssize_t (*unwind_backtrace_signal_arch_t) (siginfo_t *si, void *sc, const map_info_t *lst, backtrace_frame_t *bt, size_t ignore_depth, size_t max_depth);
|
||||
typedef map_info_t *(*acquire_my_map_info_list_t) (void);
|
||||
typedef void (*release_my_map_info_list_t) (map_info_t *milist);
|
||||
|
||||
static char *
|
||||
mono_extension_handle_native_sigsegv_libcorkscrew (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info)
|
||||
{
|
||||
#if defined (__arm__) || defined (__i386__)
|
||||
char *dl_err;
|
||||
|
||||
get_backtrace_symbols_t get_backtrace_symbols;
|
||||
free_backtrace_symbols_t free_backtrace_symbols;
|
||||
unwind_backtrace_signal_arch_t unwind_backtrace_signal_arch;
|
||||
acquire_my_map_info_list_t acquire_my_map_info_list;
|
||||
release_my_map_info_list_t release_my_map_info_list;
|
||||
|
||||
backtrace_frame_t frames [FRAMES_TO_UNWIND];
|
||||
backtrace_symbol_t symbols [FRAMES_TO_UNWIND];
|
||||
|
||||
map_info_t *map_info;
|
||||
ssize_t frames_unwound;
|
||||
size_t i;
|
||||
|
||||
MonoDl *dl = mono_dl_open ("libcorkscrew.so", MONO_DL_LAZY, &dl_err);
|
||||
|
||||
if (!dl)
|
||||
return dl_err;
|
||||
|
||||
LOAD_SYM (dl, dl_err, get_backtrace_symbols, get_backtrace_symbols);
|
||||
LOAD_SYM (dl, dl_err, free_backtrace_symbols, free_backtrace_symbols);
|
||||
LOAD_SYM (dl, dl_err, unwind_backtrace_signal_arch, unwind_backtrace_signal_arch);
|
||||
LOAD_SYM (dl, dl_err, acquire_my_map_info_list, acquire_my_map_info_list);
|
||||
LOAD_SYM (dl, dl_err, release_my_map_info_list, release_my_map_info_list);
|
||||
|
||||
map_info = acquire_my_map_info_list ();
|
||||
frames_unwound = unwind_backtrace_signal_arch (info, ctx, map_info, frames, 0, FRAMES_TO_UNWIND);
|
||||
release_my_map_info_list (map_info);
|
||||
|
||||
if (frames_unwound == -1) {
|
||||
mono_dl_close (dl);
|
||||
|
||||
return g_strdup ("unwind_backtrace_signal_arch () returned -1");
|
||||
}
|
||||
|
||||
get_backtrace_symbols (frames, frames_unwound, symbols);
|
||||
|
||||
for (i = 0; i < frames_unwound; i++) {
|
||||
backtrace_frame_t *frame = frames + i;
|
||||
backtrace_symbol_t *symbol = symbols + i;
|
||||
|
||||
const char *name = symbol->demangled_name ? symbol->demangled_name : (symbol->symbol_name ? symbol->symbol_name : "???");
|
||||
uintptr_t off = symbol->relative_pc - symbol->relative_symbol_addr;
|
||||
uintptr_t ip = frame->absolute_pc;
|
||||
|
||||
mono_runtime_printf_err (" at %s+%zu [0x%zx]", name, off, ip);
|
||||
}
|
||||
|
||||
free_backtrace_symbols (symbols, frames_unwound);
|
||||
|
||||
mono_dl_close (dl);
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
return g_strdup ("libcorkscrew is only supported on 32-bit ARM/x86");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mono_exception_native_unwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info)
|
||||
{
|
||||
char *unwind_err, *corkscrew_err;
|
||||
|
||||
mono_runtime_printf_err ("\nAttempting native Android stacktrace:\n");
|
||||
|
||||
unwind_err = mono_extension_handle_native_sigsegv_libunwind (ctx, info);
|
||||
|
||||
if (unwind_err) {
|
||||
corkscrew_err = mono_extension_handle_native_sigsegv_libcorkscrew (ctx, info);
|
||||
|
||||
if (corkscrew_err) {
|
||||
mono_runtime_printf_err ("\tCould not unwind with `libunwind.so`: %s", unwind_err);
|
||||
mono_runtime_printf_err ("\tCould not unwind with `libcorkscrew.so`: %s", corkscrew_err);
|
||||
mono_runtime_printf_err ("\n\tNo options left to get a native stacktrace :-(");
|
||||
|
||||
g_free (corkscrew_err);
|
||||
}
|
||||
|
||||
g_free (unwind_err);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
mono_exception_native_unwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -96,6 +96,15 @@ static void mono_raise_exception_with_ctx (MonoException *exc, MonoContext *ctx)
|
||||
static void mono_runtime_walk_stack_with_ctx (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data);
|
||||
static gboolean mono_current_thread_has_handle_block_guard (void);
|
||||
|
||||
static int
|
||||
mono_get_seq_point_for_native_offset (MonoDomain *domain, MonoMethod *method, gint32 native_offset)
|
||||
{
|
||||
SeqPoint sp;
|
||||
if (mono_find_prev_seq_point_for_native_offset (domain, method, native_offset, NULL, &sp))
|
||||
return sp.il_offset;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
mono_exceptions_init (void)
|
||||
{
|
||||
@@ -139,6 +148,7 @@ mono_exceptions_init (void)
|
||||
cbs.mono_install_handler_block_guard = mono_install_handler_block_guard;
|
||||
cbs.mono_current_thread_has_handle_block_guard = mono_current_thread_has_handle_block_guard;
|
||||
mono_install_eh_callbacks (&cbs);
|
||||
mono_install_get_seq_point (mono_get_seq_point_for_native_offset);
|
||||
}
|
||||
|
||||
gpointer
|
||||
@@ -2336,6 +2346,34 @@ print_stack_frame_to_string (StackFrameInfo *frame, MonoContext *ctx, gpointer d
|
||||
|
||||
#ifndef MONO_CROSS_COMPILE
|
||||
|
||||
static void print_process_map ()
|
||||
{
|
||||
#ifdef __linux__
|
||||
FILE *fp = fopen ("/proc/self/maps", "r");
|
||||
char line [256];
|
||||
|
||||
if (fp == NULL) {
|
||||
mono_runtime_printf_err ("no /proc/self/maps, not on linux?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mono_runtime_printf_err ("/proc/self/maps:");
|
||||
|
||||
while (fgets (line, sizeof (line), fp)) {
|
||||
// strip newline
|
||||
size_t len = strlen (line) - 1;
|
||||
if (len >= 0 && line [len] == '\n')
|
||||
line [len] = '\0';
|
||||
|
||||
mono_runtime_printf_err ("%s", line);
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
#else
|
||||
/* do nothing */
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean handling_sigsegv = FALSE;
|
||||
|
||||
/*
|
||||
@@ -2379,6 +2417,8 @@ mono_handle_native_sigsegv (int signal, void *ctx, MONO_SIG_HANDLER_INFO_TYPE *i
|
||||
mono_walk_stack (print_stack_frame_to_stderr, MONO_UNWIND_LOOKUP_IL_OFFSET, NULL);
|
||||
}
|
||||
|
||||
print_process_map ();
|
||||
|
||||
#ifdef HAVE_BACKTRACE_SYMBOLS
|
||||
{
|
||||
void *array [256];
|
||||
@@ -2431,7 +2471,15 @@ mono_handle_native_sigsegv (int signal, void *ctx, MONO_SIG_HANDLER_INFO_TYPE *i
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
mono_exception_native_unwind (ctx, info);
|
||||
#ifdef PLATFORM_ANDROID
|
||||
/* set DUMPABLE for this process so debuggerd can attach with ptrace(2), see:
|
||||
* https://android.googlesource.com/platform/bionic/+/151da681000c07da3c24cd30a3279b1ca017f452/linker/debugger.cpp#206
|
||||
* this has changed on later versions of Android. Also, we don't want to
|
||||
* set this on start-up as DUMPABLE has security implications. */
|
||||
prctl (PR_SET_DUMPABLE, 1);
|
||||
|
||||
mono_runtime_printf_err ("\nNo native Android stacktrace (see debuggerd output).\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -1 +1 @@
|
||||
aca368c9dba9e1ad8ef382fa8e7532a93981ffe5
|
||||
7897b982a8180aac7e6fdccf0703ebcdb62cc1b7
|
||||
@@ -1 +1 @@
|
||||
fa3a3b738e36916c6cd30fdf6def572c1a1506cd
|
||||
d5708a12125a5eb71fbc4b6a8acf8209bf6561ca
|
||||
@@ -46,19 +46,19 @@ static int unwind_info_size;
|
||||
|
||||
#ifdef TARGET_AMD64
|
||||
static int map_hw_reg_to_dwarf_reg [] = { 0, 2, 1, 3, 7, 6, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
||||
#define NUM_REGS AMD64_NREG
|
||||
#define NUM_DWARF_REGS AMD64_NREG
|
||||
#define DWARF_DATA_ALIGN (-8)
|
||||
#define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (AMD64_RIP))
|
||||
#elif defined(TARGET_ARM)
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
|
||||
/* Assign d8..d15 to hregs 16..24 (dwarf regs 264..271) */
|
||||
static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 264, 265, 266, 267, 268, 269, 270, 271 };
|
||||
#define NUM_REGS 272
|
||||
#define NUM_DWARF_REGS 272
|
||||
#define DWARF_DATA_ALIGN (-4)
|
||||
#define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (ARMREG_LR))
|
||||
#define IS_DOUBLE_REG(dwarf_reg) (((dwarf_reg) >= 264) && ((dwarf_reg) <= 271))
|
||||
#elif defined(TARGET_ARM64)
|
||||
#define NUM_REGS 96
|
||||
#define NUM_DWARF_REGS 96
|
||||
#define DWARF_DATA_ALIGN (-8)
|
||||
/* LR */
|
||||
#define DWARF_PC_REG 30
|
||||
@@ -75,7 +75,7 @@ static int map_hw_reg_to_dwarf_reg [] = {
|
||||
*/
|
||||
static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 5, 4, 6, 7, 8 };
|
||||
/* + 1 is for IP */
|
||||
#define NUM_REGS X86_NREG + 1
|
||||
#define NUM_DWARF_REGS (X86_NREG + 1)
|
||||
#define DWARF_DATA_ALIGN (-4)
|
||||
#define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (X86_NREG))
|
||||
#elif defined (TARGET_POWERPC)
|
||||
@@ -84,12 +84,12 @@ static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 29, 30, 31 };
|
||||
#define NUM_REGS 110
|
||||
#define NUM_DWARF_REGS 110
|
||||
#define DWARF_DATA_ALIGN (-(gint32)sizeof (mgreg_t))
|
||||
#define DWARF_PC_REG 108
|
||||
#elif defined (TARGET_S390X)
|
||||
static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
#define NUM_REGS 16
|
||||
#define NUM_DWARF_REGS 16
|
||||
#define DWARF_DATA_ALIGN (-8)
|
||||
#define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (14))
|
||||
#elif defined (TARGET_MIPS)
|
||||
@@ -100,23 +100,25 @@ static int map_hw_reg_to_dwarf_reg [32] = {
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31
|
||||
};
|
||||
#define NUM_REGS 32
|
||||
#define NUM_DWARF_REGS 32
|
||||
#define DWARF_DATA_ALIGN (-(gint32)sizeof (mgreg_t))
|
||||
#define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (mips_ra))
|
||||
#else
|
||||
static int map_hw_reg_to_dwarf_reg [16];
|
||||
#define NUM_REGS 16
|
||||
#define NUM_DWARF_REGS 16
|
||||
#define DWARF_DATA_ALIGN 0
|
||||
#define DWARF_PC_REG -1
|
||||
#endif
|
||||
|
||||
#define NUM_HW_REGS (sizeof (map_hw_reg_to_dwarf_reg) / sizeof (int))
|
||||
|
||||
#ifndef IS_DOUBLE_REG
|
||||
#define IS_DOUBLE_REG(dwarf_reg) 0
|
||||
#endif
|
||||
|
||||
static gboolean dwarf_reg_to_hw_reg_inited;
|
||||
|
||||
static int map_dwarf_reg_to_hw_reg [NUM_REGS];
|
||||
static int map_dwarf_reg_to_hw_reg [NUM_DWARF_REGS];
|
||||
|
||||
/*
|
||||
* mono_hw_reg_to_dwarf_reg:
|
||||
@@ -130,10 +132,10 @@ mono_hw_reg_to_dwarf_reg (int reg)
|
||||
if (reg == ppc_lr)
|
||||
return 108;
|
||||
else
|
||||
g_assert (reg < NUM_REGS);
|
||||
g_assert (reg < NUM_HW_REGS);
|
||||
#endif
|
||||
|
||||
if (NUM_REGS == 0) {
|
||||
if (NUM_HW_REGS == 0) {
|
||||
g_assert_not_reached ();
|
||||
return -1;
|
||||
} else {
|
||||
@@ -146,8 +148,8 @@ init_reg_map (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_assert (NUM_REGS > 0);
|
||||
for (i = 0; i < sizeof (map_hw_reg_to_dwarf_reg) / sizeof (int); ++i) {
|
||||
g_assert (NUM_HW_REGS > 0);
|
||||
for (i = 0; i < NUM_HW_REGS; ++i) {
|
||||
map_dwarf_reg_to_hw_reg [mono_hw_reg_to_dwarf_reg (i)] = i;
|
||||
}
|
||||
|
||||
@@ -479,8 +481,8 @@ print_dwarf_state (int cfa_reg, int cfa_offset, int ip, int nregs, Loc *location
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Loc locations [NUM_REGS];
|
||||
guint8 reg_saved [NUM_REGS];
|
||||
Loc locations [NUM_HW_REGS];
|
||||
guint8 reg_saved [NUM_HW_REGS];
|
||||
int cfa_reg, cfa_offset;
|
||||
} UnwindState;
|
||||
|
||||
@@ -501,9 +503,9 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
|
||||
mgreg_t **save_locations, int save_locations_len,
|
||||
guint8 **out_cfa)
|
||||
{
|
||||
Loc locations [NUM_REGS];
|
||||
guint8 reg_saved [NUM_REGS];
|
||||
int i, pos, reg, cfa_reg = -1, cfa_offset = 0, offset;
|
||||
Loc locations [NUM_HW_REGS];
|
||||
guint8 reg_saved [NUM_HW_REGS];
|
||||
int pos, reg, hwreg, cfa_reg = -1, cfa_offset = 0, offset;
|
||||
guint8 *p;
|
||||
guint8 *cfa_val;
|
||||
UnwindState state_stack [1];
|
||||
@@ -528,11 +530,11 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
|
||||
p ++;
|
||||
break;
|
||||
case DW_CFA_offset:
|
||||
reg = *p & 0x3f;
|
||||
hwreg = mono_dwarf_reg_to_hw_reg (*p & 0x3f);
|
||||
p ++;
|
||||
reg_saved [reg] = TRUE;
|
||||
locations [reg].loc_type = LOC_OFFSET;
|
||||
locations [reg].offset = decode_uleb128 (p, &p) * DWARF_DATA_ALIGN;
|
||||
reg_saved [hwreg] = TRUE;
|
||||
locations [hwreg].loc_type = LOC_OFFSET;
|
||||
locations [hwreg].offset = decode_uleb128 (p, &p) * DWARF_DATA_ALIGN;
|
||||
break;
|
||||
case 0: {
|
||||
int ext_op = *p;
|
||||
@@ -550,23 +552,25 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
|
||||
break;
|
||||
case DW_CFA_offset_extended_sf:
|
||||
reg = decode_uleb128 (p, &p);
|
||||
hwreg = mono_dwarf_reg_to_hw_reg (reg);
|
||||
offset = decode_sleb128 (p, &p);
|
||||
g_assert (reg < NUM_REGS);
|
||||
reg_saved [reg] = TRUE;
|
||||
locations [reg].loc_type = LOC_OFFSET;
|
||||
locations [reg].offset = offset * DWARF_DATA_ALIGN;
|
||||
g_assert (reg < NUM_DWARF_REGS);
|
||||
reg_saved [hwreg] = TRUE;
|
||||
locations [hwreg].loc_type = LOC_OFFSET;
|
||||
locations [hwreg].offset = offset * DWARF_DATA_ALIGN;
|
||||
break;
|
||||
case DW_CFA_offset_extended:
|
||||
reg = decode_uleb128 (p, &p);
|
||||
hwreg = mono_dwarf_reg_to_hw_reg (reg);
|
||||
offset = decode_uleb128 (p, &p);
|
||||
g_assert (reg < NUM_REGS);
|
||||
reg_saved [reg] = TRUE;
|
||||
locations [reg].loc_type = LOC_OFFSET;
|
||||
locations [reg].offset = offset * DWARF_DATA_ALIGN;
|
||||
g_assert (reg < NUM_DWARF_REGS);
|
||||
reg_saved [hwreg] = TRUE;
|
||||
locations [hwreg].loc_type = LOC_OFFSET;
|
||||
locations [hwreg].offset = offset * DWARF_DATA_ALIGN;
|
||||
break;
|
||||
case DW_CFA_same_value:
|
||||
reg = decode_uleb128 (p, &p);
|
||||
locations [reg].loc_type = LOC_SAME;
|
||||
hwreg = mono_dwarf_reg_to_hw_reg (decode_uleb128 (p, &p));
|
||||
locations [hwreg].loc_type = LOC_SAME;
|
||||
break;
|
||||
case DW_CFA_advance_loc1:
|
||||
pos += *p;
|
||||
@@ -615,16 +619,16 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
|
||||
|
||||
g_assert (cfa_reg != -1);
|
||||
cfa_val = (guint8*)regs [mono_dwarf_reg_to_hw_reg (cfa_reg)] + cfa_offset;
|
||||
for (i = 0; i < NUM_REGS; ++i) {
|
||||
if (reg_saved [i] && locations [i].loc_type == LOC_OFFSET) {
|
||||
int hreg = mono_dwarf_reg_to_hw_reg (i);
|
||||
g_assert (hreg < nregs);
|
||||
if (IS_DOUBLE_REG (i))
|
||||
regs [hreg] = *(guint64*)(cfa_val + locations [i].offset);
|
||||
for (hwreg = 0; hwreg < NUM_HW_REGS; ++hwreg) {
|
||||
if (reg_saved [hwreg] && locations [hwreg].loc_type == LOC_OFFSET) {
|
||||
int dwarfreg = mono_hw_reg_to_dwarf_reg (hwreg);
|
||||
g_assert (hwreg < nregs);
|
||||
if (IS_DOUBLE_REG (dwarfreg))
|
||||
regs [hwreg] = *(guint64*)(cfa_val + locations [hwreg].offset);
|
||||
else
|
||||
regs [hreg] = *(mgreg_t*)(cfa_val + locations [i].offset);
|
||||
if (save_locations && hreg < save_locations_len)
|
||||
save_locations [hreg] = (mgreg_t*)(cfa_val + locations [i].offset);
|
||||
regs [hwreg] = *(mgreg_t*)(cfa_val + locations [hwreg].offset);
|
||||
if (save_locations && hwreg < save_locations_len)
|
||||
save_locations [hwreg] = (mgreg_t*)(cfa_val + locations [hwreg].offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define FULL_VERSION "Stable 4.8.0.395/df81fe4"
|
||||
#define FULL_VERSION "Stable 4.8.0.425/038ff4a"
|
||||
|
||||
Reference in New Issue
Block a user