111
|
1 /****************************************************************************
|
|
2 * *
|
|
3 * GNAT COMPILER COMPONENTS *
|
|
4 * *
|
|
5 * S I G T R A M P *
|
|
6 * *
|
|
7 * Asm Implementation File *
|
|
8 * *
|
131
|
9 * Copyright (C) 2015-2018, Free Software Foundation, Inc. *
|
111
|
10 * *
|
|
11 * GNAT is free software; you can redistribute it and/or modify it under *
|
|
12 * terms of the GNU General Public License as published by the Free Soft- *
|
|
13 * ware Foundation; either version 3, or (at your option) any later ver- *
|
|
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
|
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
|
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
17 * *
|
|
18 * As a special exception under Section 7 of GPL version 3, you are granted *
|
|
19 * additional permissions described in the GCC Runtime Library Exception, *
|
|
20 * version 3.1, as published by the Free Software Foundation. *
|
|
21 * *
|
|
22 * In particular, you can freely distribute your programs built with the *
|
|
23 * GNAT Pro compiler, including any required library run-time units, using *
|
|
24 * any licensing terms of your choosing. See the AdaCore Software License *
|
|
25 * for full details. *
|
|
26 * *
|
|
27 * GNAT was originally developed by the GNAT team at New York University. *
|
|
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
|
|
29 * *
|
|
30 ****************************************************************************/
|
|
31
|
|
32 /******************************************************
|
|
33 * ARM-Android version of the __gnat_sigtramp service *
|
|
34 ******************************************************/
|
|
35
|
|
36 #include <sys/ucontext.h>
|
|
37
|
|
38 #include "sigtramp.h"
|
|
39 /* See sigtramp.h for a general explanation of functionality. */
|
|
40
|
|
41 /* ----------------------
|
|
42 -- General comments --
|
|
43 ----------------------
|
|
44
|
|
45 Stubs are generated from toplevel asms,
|
|
46 The general idea is to establish CFA as the sigcontext
|
|
47 and state where to find the registers as offsets from there.
|
|
48
|
|
49 We support stubs for VxWorks and Android, providing unwind info for
|
|
50 common registers. We might need variants with support for floating
|
|
51 point or altivec registers as well at some point.
|
|
52
|
|
53 For Android it would be simpler to write this in Asm since there's only
|
|
54 one variant, but to keep it looking like the VxWorks stubs,
|
|
55 C is the choice for our toplevel interface.
|
|
56
|
|
57 Note that the registers we "restore" here are those to which we have
|
|
58 direct access through the system sigcontext structure, which includes
|
|
59 only a partial set of the non-volatiles ABI-wise. */
|
|
60
|
|
61 /* -----------------------------------------
|
|
62 -- Protypes for our internal asm stubs --
|
|
63 -----------------------------------------
|
|
64
|
|
65 The registers are expected to be at SIGCONTEXT + 12 (reference the
|
|
66 sicontext structure in asm/sigcontext.h which describes the first
|
|
67 3 * 4byte fields.) Even though our symbols will remain local, the
|
|
68 prototype claims "extern" and not "static" to prevent compiler complaints
|
|
69 about a symbol used but never defined. */
|
|
70
|
|
71 /* sigtramp stub providing unwind info for common registers. */
|
|
72
|
|
73 extern void __gnat_sigtramp_common
|
|
74 (int signo, void *siginfo, void *sigcontext,
|
|
75 __sigtramphandler_t * handler);
|
|
76
|
|
77 void __gnat_sigtramp (int signo, void *si, void *sc,
|
|
78 __sigtramphandler_t * handler)
|
|
79 __attribute__((optimize(2)));
|
|
80
|
|
81 void __gnat_sigtramp (int signo, void *si, void *ucontext,
|
|
82 __sigtramphandler_t * handler)
|
|
83 {
|
|
84 struct sigcontext *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
|
|
85
|
|
86 __gnat_sigtramp_common (signo, si, mcontext, handler);
|
|
87 }
|
|
88
|
|
89 /* asm string construction helpers. */
|
|
90
|
|
91 #define STR(TEXT) #TEXT
|
|
92 /* stringify expanded TEXT, surrounding it with double quotes. */
|
|
93
|
|
94 #define S(E) STR(E)
|
|
95 /* stringify E, which will resolve as text but may contain macros
|
|
96 still to be expanded. */
|
|
97
|
|
98 /* asm (TEXT) outputs <tab>TEXT. These facilitate the output of
|
|
99 multiline contents: */
|
|
100 #define TAB(S) "\t" S
|
|
101 #define CR(S) S "\n"
|
|
102
|
|
103 #undef TCR
|
|
104 #define TCR(S) TAB(CR(S))
|
|
105
|
|
106 /* Trampoline body block
|
|
107 --------------------- */
|
|
108
|
|
109 #define SIGTRAMP_BODY \
|
|
110 CR("") \
|
|
111 TCR("# Allocate frame and also save r2 which is the argument register") \
|
|
112 TCR("# containing the sigcontext, so that we can restore it during") \
|
|
113 TCR("# unwinding and thereby load the rest of the desired context.") \
|
|
114 TCR("stmfd sp!, {r2, r3, lr}") \
|
|
115 TCR("# The unwinder undo's these operations in reverse order so starting") \
|
|
116 TCR("# from bottom, restore r2 from the current vsp location, move r2 into") \
|
|
117 TCR("# the vsp, add 12 bytes to get the start of the register save area") \
|
|
118 TCR("# then restore the 15 general purpose registers of the frame which") \
|
|
119 TCR("# raised the signal.") \
|
|
120 TCR(".save {r0-r15}") \
|
|
121 TCR(".pad #12") \
|
|
122 TCR(".movsp r2") \
|
|
123 TCR(".save {r2}") \
|
|
124 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
|
|
125 TCR("# arguments are the same as those we received in r0, r1 and r2.") \
|
|
126 TCR("blx r3") \
|
|
127 TCR("# Restore our callee-saved items, release our frame and return") \
|
|
128 TCR("# (should never get here!).") \
|
|
129 TCR("ldmfd sp, {r2, r3, pc}")
|
|
130
|
|
131 /* Symbol definition block
|
|
132 ----------------------- */
|
|
133
|
|
134 #define SIGTRAMP_START(SYM) \
|
|
135 CR("# " S(SYM) " unwind trampoline") \
|
|
136 TCR(".type " S(SYM) ", %function") \
|
|
137 CR("") \
|
|
138 CR(S(SYM) ":") \
|
|
139 TCR(".fnstart")
|
|
140
|
|
141 /* Symbol termination block
|
|
142 ------------------------ */
|
|
143
|
|
144 #define SIGTRAMP_END(SYM) \
|
|
145 CR(".fnend") \
|
|
146 TCR(".size " S(SYM) ", .-" S(SYM))
|
|
147
|
|
148 /*----------------------------
|
|
149 -- And now, the real code --
|
|
150 ---------------------------- */
|
|
151
|
|
152 /* Text section start. The compiler isn't aware of that switch. */
|
|
153
|
|
154 asm (".text\n"
|
|
155 TCR(".align 2"));
|
|
156
|
|
157 /* sigtramp stub for common registers. */
|
|
158
|
|
159 #define TRAMP_COMMON __gnat_sigtramp_common
|
|
160
|
|
161 asm (SIGTRAMP_START(TRAMP_COMMON));
|
|
162 asm (SIGTRAMP_BODY);
|
|
163 asm (SIGTRAMP_END(TRAMP_COMMON));
|