aboutsummaryrefslogtreecommitdiff
path: root/Marlin/src/HAL/shared/backtrace/unwinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Marlin/src/HAL/shared/backtrace/unwinder.cpp')
-rw-r--r--Marlin/src/HAL/shared/backtrace/unwinder.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/Marlin/src/HAL/shared/backtrace/unwinder.cpp b/Marlin/src/HAL/shared/backtrace/unwinder.cpp
new file mode 100644
index 0000000..0f88e2a
--- /dev/null
+++ b/Marlin/src/HAL/shared/backtrace/unwinder.cpp
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
+ * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle
+ *
+ * This program is PUBLIC DOMAIN.
+ * This means that there is no copyright and anyone is able to take a copy
+ * for free and use it as they wish, with or without modifications, and in
+ * any context, commercially or otherwise. The only limitation is that I
+ * don't guarantee that the software is fit for any purpose or accept any
+ * liability for its use or misuse - this software is without warranty.
+ ***************************************************************************
+ * File Description: Implementation of the interface into the ARM unwinder.
+ **************************************************************************/
+
+#if defined(__arm__) || defined(__thumb__)
+
+#define MODULE_NAME "UNWINDER"
+
+#include <stdio.h>
+#include <string.h>
+#include "unwinder.h"
+#include "unwarm.h"
+#include "unwarmbytab.h"
+
+/* These symbols point to the unwind index and should be provide by the linker script */
+extern "C" const UnwTabEntry __exidx_start[];
+extern "C" const UnwTabEntry __exidx_end[];
+
+// Detect if unwind information is present or not
+static int HasUnwindTableInfo() {
+ // > 16 because there are default entries we can't supress
+ return ((char*)(&__exidx_end) - (char*)(&__exidx_start)) > 16 ? 1 : 0;
+}
+
+UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data) {
+ if (HasUnwindTableInfo()) {
+ /* We have unwind information tables */
+ return UnwindByTableStart(frame, cb, data);
+ }
+ else {
+
+ /* We don't have unwind information tables */
+ UnwState state;
+
+ /* Initialize the unwinding state */
+ UnwInitState(&state, cb, data, frame->pc, frame->sp);
+
+ /* Check the Thumb bit */
+ return (frame->pc & 0x1) ? UnwStartThumb(&state) : UnwStartArm(&state);
+ }
+}
+#endif