1f9f848faSopenharmony_ci/* $NetBSD: unwind.c,v 1.3 2019/01/30 22:46:49 mrg Exp $ */ 2f9f848faSopenharmony_ci 3f9f848faSopenharmony_ci/*- 4f9f848faSopenharmony_ci * Copyright (c) 2012 The NetBSD Foundation, Inc. 5f9f848faSopenharmony_ci * All rights reserved. 6f9f848faSopenharmony_ci * 7f9f848faSopenharmony_ci * This code is derived from software contributed to The NetBSD Foundation 8f9f848faSopenharmony_ci * by Christos Zoulas. 9f9f848faSopenharmony_ci * 10f9f848faSopenharmony_ci * Redistribution and use in source and binary forms, with or without 11f9f848faSopenharmony_ci * modification, are permitted provided that the following conditions 12f9f848faSopenharmony_ci * are met: 13f9f848faSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 14f9f848faSopenharmony_ci * notice, this list of conditions and the following disclaimer. 15f9f848faSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 16f9f848faSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 17f9f848faSopenharmony_ci * documentation and/or other materials provided with the distribution. 18f9f848faSopenharmony_ci * 19f9f848faSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20f9f848faSopenharmony_ci * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21f9f848faSopenharmony_ci * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22f9f848faSopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23f9f848faSopenharmony_ci * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24f9f848faSopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25f9f848faSopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26f9f848faSopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27f9f848faSopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28f9f848faSopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29f9f848faSopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 30f9f848faSopenharmony_ci */ 31f9f848faSopenharmony_ci#include <sys/cdefs.h> 32f9f848faSopenharmony_ci#include <sys/types.h> 33f9f848faSopenharmony_ci#include <stdio.h> 34f9f848faSopenharmony_ci 35f9f848faSopenharmony_ci#include "execinfo.h" 36f9f848faSopenharmony_ci 37f9f848faSopenharmony_cistruct tracer_context { 38f9f848faSopenharmony_ci void **arr; 39f9f848faSopenharmony_ci size_t len; 40f9f848faSopenharmony_ci size_t n; 41f9f848faSopenharmony_ci}; 42f9f848faSopenharmony_ci 43f9f848faSopenharmony_citypedef enum { 44f9f848faSopenharmony_ci _URC_NO_REASON = 0, 45f9f848faSopenharmony_ci#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ 46f9f848faSopenharmony_ci !defined(__ARM_DWARF_EH__) && !defined(__SEH__) 47f9f848faSopenharmony_ci _URC_OK = 0, /* used by ARM EHABI */ 48f9f848faSopenharmony_ci#endif 49f9f848faSopenharmony_ci _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 50f9f848faSopenharmony_ci 51f9f848faSopenharmony_ci _URC_FATAL_PHASE2_ERROR = 2, 52f9f848faSopenharmony_ci _URC_FATAL_PHASE1_ERROR = 3, 53f9f848faSopenharmony_ci _URC_NORMAL_STOP = 4, 54f9f848faSopenharmony_ci 55f9f848faSopenharmony_ci _URC_END_OF_STACK = 5, 56f9f848faSopenharmony_ci _URC_HANDLER_FOUND = 6, 57f9f848faSopenharmony_ci _URC_INSTALL_CONTEXT = 7, 58f9f848faSopenharmony_ci _URC_CONTINUE_UNWIND = 8, 59f9f848faSopenharmony_ci#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ 60f9f848faSopenharmony_ci !defined(__ARM_DWARF_EH__) && !defined(__SEH__) 61f9f848faSopenharmony_ci _URC_FAILURE = 9 /* used by ARM EHABI */ 62f9f848faSopenharmony_ci#endif 63f9f848faSopenharmony_ci} _Unwind_Reason_Code; 64f9f848faSopenharmony_ci 65f9f848faSopenharmony_cistruct _Unwind_Context; 66f9f848faSopenharmony_citypedef unsigned int _Unwind_Word __attribute__((__mode__(__unwind_word__))); 67f9f848faSopenharmony_ci 68f9f848faSopenharmony_ci_Unwind_Word _Unwind_GetGR(struct _Unwind_Context *, int); 69f9f848faSopenharmony_ci_Unwind_Word _Unwind_GetIP(struct _Unwind_Context *); 70f9f848faSopenharmony_citypedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, 71f9f848faSopenharmony_ci void *); 72f9f848faSopenharmony_ciextern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); 73f9f848faSopenharmony_cistatic _Unwind_Reason_Code 74f9f848faSopenharmony_citracer(struct _Unwind_Context *ctx, void *arg) 75f9f848faSopenharmony_ci{ 76f9f848faSopenharmony_ci struct tracer_context *t = arg; 77f9f848faSopenharmony_ci if (t->n == (size_t)~0) { 78f9f848faSopenharmony_ci /* Skip backtrace frame */ 79f9f848faSopenharmony_ci t->n = 0; 80f9f848faSopenharmony_ci return 0; 81f9f848faSopenharmony_ci } 82f9f848faSopenharmony_ci if (t->n < t->len) 83f9f848faSopenharmony_ci t->arr[t->n++] = (void *)_Unwind_GetIP(ctx); 84f9f848faSopenharmony_ci else 85f9f848faSopenharmony_ci return _URC_END_OF_STACK; 86f9f848faSopenharmony_ci return _URC_NO_REASON; 87f9f848faSopenharmony_ci} 88f9f848faSopenharmony_ci 89f9f848faSopenharmony_cisize_t 90f9f848faSopenharmony_cibacktrace(void **arr, size_t len) 91f9f848faSopenharmony_ci{ 92f9f848faSopenharmony_ci struct tracer_context ctx; 93f9f848faSopenharmony_ci 94f9f848faSopenharmony_ci ctx.arr = arr; 95f9f848faSopenharmony_ci ctx.len = len; 96f9f848faSopenharmony_ci ctx.n = (size_t)~0; 97f9f848faSopenharmony_ci 98f9f848faSopenharmony_ci _Unwind_Backtrace(tracer, &ctx); 99f9f848faSopenharmony_ci if (ctx.n == (size_t)~0) 100f9f848faSopenharmony_ci ctx.n = 0; 101f9f848faSopenharmony_ci 102f9f848faSopenharmony_ci return ctx.n; 103f9f848faSopenharmony_ci} 104