1 #ifndef __ARM_BUG_H__
2 #define __ARM_BUG_H__
3 
4 #include <asm/processor.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_DISP_WIDTH    24
15 #define BUG_LINE_LO_WIDTH (31 - BUG_DISP_WIDTH)
16 #define BUG_LINE_HI_WIDTH (31 - BUG_DISP_WIDTH)
17 
18 struct bug_frame {
19     signed int loc_disp;    /* Relative address to the bug address */
20     signed int file_disp;   /* Relative address to the filename */
21     signed int msg_disp;    /* Relative address to the predicate (for ASSERT) */
22     uint16_t line;          /* Line number */
23     uint32_t pad0:16;       /* Padding for 8-bytes align */
24 };
25 
26 #define bug_loc(b) ((const void *)(b) + (b)->loc_disp)
27 #define bug_file(b) ((const void *)(b) + (b)->file_disp);
28 #define bug_line(b) ((b)->line)
29 #define bug_msg(b) ((const char *)(b) + (b)->msg_disp)
30 
31 #define BUGFRAME_warn   0
32 #define BUGFRAME_bug    1
33 #define BUGFRAME_assert 2
34 
35 #define BUGFRAME_NR     3
36 
37 /* Many versions of GCC doesn't support the asm %c parameter which would
38  * be preferable to this unpleasantness. We use mergeable string
39  * sections to avoid multiple copies of the string appearing in the
40  * Xen image.
41  */
42 #define BUG_FRAME(type, line, file, has_msg, msg) do {                      \
43     BUILD_BUG_ON((line) >> 16);                                             \
44     BUILD_BUG_ON((type) >= BUGFRAME_NR);                                    \
45     asm ("1:"BUG_INSTR"\n"                                                  \
46          ".pushsection .rodata.str, \"aMS\", %progbits, 1\n"                \
47          "2:\t.asciz " __stringify(file) "\n"                               \
48          "3:\n"                                                             \
49          ".if " #has_msg "\n"                                               \
50          "\t.asciz " #msg "\n"                                              \
51          ".endif\n"                                                         \
52          ".popsection\n"                                                    \
53          ".pushsection .bug_frames." __stringify(type) ", \"a\", %progbits\n"\
54          "4:\n"                                                             \
55          ".p2align 2\n"                                                     \
56          ".long (1b - 4b)\n"                                                \
57          ".long (2b - 4b)\n"                                                \
58          ".long (3b - 4b)\n"                                                \
59          ".hword " __stringify(line) ", 0\n"                                \
60          ".popsection");                                                    \
61 } while (0)
62 
63 #define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, "")
64 
65 #define BUG() do {                                              \
66     BUG_FRAME(BUGFRAME_bug,  __LINE__, __FILE__, 0, "");        \
67     unreachable();                                              \
68 } while (0)
69 
70 #define assert_failed(msg) do {                                 \
71     BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg);     \
72     unreachable();                                              \
73 } while (0)
74 
75 extern const struct bug_frame __start_bug_frames[],
76                               __stop_bug_frames_0[],
77                               __stop_bug_frames_1[],
78                               __stop_bug_frames_2[];
79 
80 int do_bug_frame(struct cpu_user_regs *regs, vaddr_t pc);
81 
82 #endif /* __ARM_BUG_H__ */
83 /*
84  * Local variables:
85  * mode: C
86  * c-file-style: "BSD"
87  * c-basic-offset: 4
88  * indent-tabs-mode: nil
89  * End:
90  */
91