1 #ifndef __ARM_BUG_H__ 2 #define __ARM_BUG_H__ 3 4 #include <xen/types.h> 5 6 #if defined(CONFIG_ARM_32) 7 # include <asm/arm32/bug.h> 8 #elif defined(CONFIG_ARM_64) 9 # include <asm/arm64/bug.h> 10 #else 11 # error "unknown ARM variant" 12 #endif 13 14 #define BUG_FRAME_STRUCT 15 16 struct bug_frame { 17 signed int loc_disp; /* Relative address to the bug address */ 18 signed int file_disp; /* Relative address to the filename */ 19 signed int msg_disp; /* Relative address to the predicate (for ASSERT) */ 20 uint16_t line; /* Line number */ 21 uint32_t pad0:16; /* Padding for 8-bytes align */ 22 }; 23 24 #define bug_loc(b) ((const void *)(b) + (b)->loc_disp) 25 #define bug_file(b) ((const void *)(b) + (b)->file_disp); 26 #define bug_line(b) ((b)->line) 27 #define bug_msg(b) ((const char *)(b) + (b)->msg_disp) 28 29 /* Many versions of GCC doesn't support the asm %c parameter which would 30 * be preferable to this unpleasantness. We use mergeable string 31 * sections to avoid multiple copies of the string appearing in the 32 * Xen image. BUGFRAME_run_fn needs to be handled separately. 33 */ 34 #define BUG_FRAME(type, line, file, has_msg, msg) do { \ 35 BUILD_BUG_ON((line) >> 16); \ 36 BUILD_BUG_ON((type) >= BUGFRAME_NR); \ 37 asm_inline ( \ 38 "1:"BUG_INSTR"\n" \ 39 ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ 40 "2:\t.asciz " __stringify(file) "\n" \ 41 "3:\n" \ 42 ".if " #has_msg "\n" \ 43 "\t.asciz " #msg "\n" \ 44 ".endif\n" \ 45 ".popsection\n" \ 46 ".pushsection .bug_frames." __stringify(type) ", \"a\", %progbits\n"\ 47 "4:\n" \ 48 ".p2align 2\n" \ 49 ".long (1b - 4b)\n" \ 50 ".long (2b - 4b)\n" \ 51 ".long (3b - 4b)\n" \ 52 ".hword " __stringify(line) ", 0\n" \ 53 ".popsection"); \ 54 } while (0) 55 56 /* 57 * GCC will not allow to use "i" when PIE is enabled (Xen doesn't set the 58 * flag but instead rely on the default value from the compiler). So the 59 * easiest way to implement run_in_exception_handler() is to pass the to 60 * be called function in a fixed register. 61 */ 62 #define run_in_exception_handler(fn) do { \ 63 register unsigned long _fn asm (STR(BUG_FN_REG)) = (unsigned long)(fn); \ 64 asm_inline ( \ 65 "1:"BUG_INSTR"\n" \ 66 ".pushsection .bug_frames." __stringify(BUGFRAME_run_fn) "," \ 67 " \"a\", %%progbits\n" \ 68 "2:\n" \ 69 ".p2align 2\n" \ 70 ".long (1b - 2b)\n" \ 71 ".long 0, 0, 0\n" \ 72 ".popsection" :: "r" (_fn) ); \ 73 } while (0) 74 75 #define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, "") 76 77 #define BUG() do { \ 78 BUG_FRAME(BUGFRAME_bug, __LINE__, __FILE__, 0, ""); \ 79 unreachable(); \ 80 } while (0) 81 82 #define assert_failed(msg) do { \ 83 BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg); \ 84 unreachable(); \ 85 } while (0) 86 87 #endif /* __ARM_BUG_H__ */ 88 /* 89 * Local variables: 90 * mode: C 91 * c-file-style: "BSD" 92 * c-basic-offset: 4 93 * indent-tabs-mode: nil 94 * End: 95 */ 96