1// Copyright 2016 The Fuchsia Authors 2// Copyright (c) 2008-2015 Travis Geiselbrecht 3// 4// Use of this source code is governed by a MIT-style 5// license that can be found in the LICENSE file or at 6// https://opensource.org/licenses/MIT 7 8#include <arch/ops.h> 9#include <ctype.h> 10#include <debug.h> 11#include <dev/hw_rng.h> 12#include <kernel/spinlock.h> 13#include <list.h> 14#include <platform.h> 15#include <platform/debug.h> 16#include <printf.h> 17#include <stdio.h> 18#include <stdlib.h> 19#include <zircon/types.h> 20#include <zircon/time.h> 21 22void spin(uint32_t usecs) { 23 zx_time_t start = current_time(); 24 25 zx_duration_t nsecs = ZX_USEC(usecs); 26 while (zx_time_sub_time(current_time(), start) < nsecs) 27 ; 28} 29 30void _panic(void* caller, void* frame, const char* fmt, ...) { 31 platform_panic_start(); 32 33 printf("panic (caller %p frame %p): ", caller, frame); 34 35 va_list ap; 36 va_start(ap, fmt); 37 vprintf(fmt, ap); 38 va_end(ap); 39 40 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC); 41} 42 43static void puts_for_panic(const char *msg, size_t len) 44{ 45 __printf_output_func(msg, len, NULL); 46} 47 48void _panic_no_format(const char *msg, size_t len) { 49 platform_panic_start(); 50 puts_for_panic(msg, len); 51 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC); 52} 53 54void __stack_chk_fail(void) { 55 panic_no_format("stack canary corrupted!\n"); 56} 57 58uintptr_t choose_stack_guard(void) { 59 uintptr_t guard; 60 if (hw_rng_get_entropy(&guard, sizeof(guard), true) != sizeof(guard)) { 61 // We can't get a random value, so use a randomish value. 62 guard = 0xdeadbeef00ff00ffUL ^ (uintptr_t)&guard; 63 } 64 return guard; 65} 66 67#if !DISABLE_DEBUG_OUTPUT 68 69void hexdump_very_ex(const void* ptr, size_t len, uint64_t disp_addr, hexdump_print_fn_t* pfn) { 70 addr_t address = (addr_t)ptr; 71 size_t count; 72 73 for (count = 0; count < len; count += 16) { 74 union { 75 uint32_t buf[4]; 76 uint8_t cbuf[16]; 77 } u; 78 size_t s = ROUNDUP(MIN(len - count, 16), 4); 79 size_t i; 80 81 pfn(((disp_addr + len) > 0xFFFFFFFF) 82 ? "0x%016llx: " 83 : "0x%08llx: ", 84 disp_addr + count); 85 86 for (i = 0; i < s / 4; i++) { 87 u.buf[i] = ((const uint32_t*)address)[i]; 88 pfn("%08x ", u.buf[i]); 89 } 90 for (; i < 4; i++) { 91 pfn(" "); 92 } 93 pfn("|"); 94 95 for (i = 0; i < 16; i++) { 96 char c = u.cbuf[i]; 97 if (i < s && isprint(c)) { 98 pfn("%c", c); 99 } else { 100 pfn("."); 101 } 102 } 103 pfn("|\n"); 104 address += 16; 105 } 106} 107 108void hexdump8_very_ex(const void* ptr, size_t len, uint64_t disp_addr, hexdump_print_fn_t* pfn) { 109 addr_t address = (addr_t)ptr; 110 size_t count; 111 size_t i; 112 113 for (count = 0; count < len; count += 16) { 114 pfn(((disp_addr + len) > 0xFFFFFFFF) 115 ? "0x%016llx: " 116 : "0x%08llx: ", 117 disp_addr + count); 118 119 for (i = 0; i < MIN(len - count, 16); i++) { 120 pfn("%02hhx ", *(const uint8_t*)(address + i)); 121 } 122 123 for (; i < 16; i++) { 124 pfn(" "); 125 } 126 127 pfn("|"); 128 129 for (i = 0; i < MIN(len - count, 16); i++) { 130 char c = ((const char*)address)[i]; 131 pfn("%c", isprint(c) ? c : '.'); 132 } 133 134 pfn("\n"); 135 address += 16; 136 } 137} 138 139#endif // !DISABLE_DEBUG_OUTPUT 140