xref: /aosp_15_r20/external/pcre/src/pcre2_jit_misc.c (revision 22dc650d8ae982c6770746019a6f94af92b0f024)
1*22dc650dSSadaf Ebrahimi /*************************************************
2*22dc650dSSadaf Ebrahimi *      Perl-Compatible Regular Expressions       *
3*22dc650dSSadaf Ebrahimi *************************************************/
4*22dc650dSSadaf Ebrahimi 
5*22dc650dSSadaf Ebrahimi /* PCRE is a library of functions to support regular expressions whose syntax
6*22dc650dSSadaf Ebrahimi and semantics are as close as possible to those of the Perl 5 language.
7*22dc650dSSadaf Ebrahimi 
8*22dc650dSSadaf Ebrahimi                        Written by Philip Hazel
9*22dc650dSSadaf Ebrahimi      Original API code Copyright (c) 1997-2012 University of Cambridge
10*22dc650dSSadaf Ebrahimi          New API code Copyright (c) 2016 University of Cambridge
11*22dc650dSSadaf Ebrahimi 
12*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
13*22dc650dSSadaf Ebrahimi Redistribution and use in source and binary forms, with or without
14*22dc650dSSadaf Ebrahimi modification, are permitted provided that the following conditions are met:
15*22dc650dSSadaf Ebrahimi 
16*22dc650dSSadaf Ebrahimi     * Redistributions of source code must retain the above copyright notice,
17*22dc650dSSadaf Ebrahimi       this list of conditions and the following disclaimer.
18*22dc650dSSadaf Ebrahimi 
19*22dc650dSSadaf Ebrahimi     * Redistributions in binary form must reproduce the above copyright
20*22dc650dSSadaf Ebrahimi       notice, this list of conditions and the following disclaimer in the
21*22dc650dSSadaf Ebrahimi       documentation and/or other materials provided with the distribution.
22*22dc650dSSadaf Ebrahimi 
23*22dc650dSSadaf Ebrahimi     * Neither the name of the University of Cambridge nor the names of its
24*22dc650dSSadaf Ebrahimi       contributors may be used to endorse or promote products derived from
25*22dc650dSSadaf Ebrahimi       this software without specific prior written permission.
26*22dc650dSSadaf Ebrahimi 
27*22dc650dSSadaf Ebrahimi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*22dc650dSSadaf Ebrahimi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*22dc650dSSadaf Ebrahimi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*22dc650dSSadaf Ebrahimi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*22dc650dSSadaf Ebrahimi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*22dc650dSSadaf Ebrahimi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*22dc650dSSadaf Ebrahimi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*22dc650dSSadaf Ebrahimi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*22dc650dSSadaf Ebrahimi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*22dc650dSSadaf Ebrahimi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*22dc650dSSadaf Ebrahimi POSSIBILITY OF SUCH DAMAGE.
38*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
39*22dc650dSSadaf Ebrahimi */
40*22dc650dSSadaf Ebrahimi 
41*22dc650dSSadaf Ebrahimi 
42*22dc650dSSadaf Ebrahimi #ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
43*22dc650dSSadaf Ebrahimi #error This file must be included from pcre2_jit_compile.c.
44*22dc650dSSadaf Ebrahimi #endif
45*22dc650dSSadaf Ebrahimi 
46*22dc650dSSadaf Ebrahimi 
47*22dc650dSSadaf Ebrahimi 
48*22dc650dSSadaf Ebrahimi /*************************************************
49*22dc650dSSadaf Ebrahimi *           Free JIT read-only data              *
50*22dc650dSSadaf Ebrahimi *************************************************/
51*22dc650dSSadaf Ebrahimi 
52*22dc650dSSadaf Ebrahimi void
PRIV(jit_free_rodata)53*22dc650dSSadaf Ebrahimi PRIV(jit_free_rodata)(void *current, void *allocator_data)
54*22dc650dSSadaf Ebrahimi {
55*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
56*22dc650dSSadaf Ebrahimi (void)current;
57*22dc650dSSadaf Ebrahimi (void)allocator_data;
58*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
59*22dc650dSSadaf Ebrahimi void *next;
60*22dc650dSSadaf Ebrahimi 
61*22dc650dSSadaf Ebrahimi SLJIT_UNUSED_ARG(allocator_data);
62*22dc650dSSadaf Ebrahimi 
63*22dc650dSSadaf Ebrahimi while (current != NULL)
64*22dc650dSSadaf Ebrahimi   {
65*22dc650dSSadaf Ebrahimi   next = *(void**)current;
66*22dc650dSSadaf Ebrahimi   SLJIT_FREE(current, allocator_data);
67*22dc650dSSadaf Ebrahimi   current = next;
68*22dc650dSSadaf Ebrahimi   }
69*22dc650dSSadaf Ebrahimi 
70*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_JIT */
71*22dc650dSSadaf Ebrahimi }
72*22dc650dSSadaf Ebrahimi 
73*22dc650dSSadaf Ebrahimi /*************************************************
74*22dc650dSSadaf Ebrahimi *           Free JIT compiled code               *
75*22dc650dSSadaf Ebrahimi *************************************************/
76*22dc650dSSadaf Ebrahimi 
77*22dc650dSSadaf Ebrahimi void
PRIV(jit_free)78*22dc650dSSadaf Ebrahimi PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl)
79*22dc650dSSadaf Ebrahimi {
80*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
81*22dc650dSSadaf Ebrahimi (void)executable_jit;
82*22dc650dSSadaf Ebrahimi (void)memctl;
83*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
84*22dc650dSSadaf Ebrahimi 
85*22dc650dSSadaf Ebrahimi executable_functions *functions = (executable_functions *)executable_jit;
86*22dc650dSSadaf Ebrahimi void *allocator_data = memctl;
87*22dc650dSSadaf Ebrahimi int i;
88*22dc650dSSadaf Ebrahimi 
89*22dc650dSSadaf Ebrahimi for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
90*22dc650dSSadaf Ebrahimi   {
91*22dc650dSSadaf Ebrahimi   if (functions->executable_funcs[i] != NULL)
92*22dc650dSSadaf Ebrahimi     sljit_free_code(functions->executable_funcs[i], NULL);
93*22dc650dSSadaf Ebrahimi   PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);
94*22dc650dSSadaf Ebrahimi   }
95*22dc650dSSadaf Ebrahimi 
96*22dc650dSSadaf Ebrahimi SLJIT_FREE(functions, allocator_data);
97*22dc650dSSadaf Ebrahimi 
98*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_JIT */
99*22dc650dSSadaf Ebrahimi }
100*22dc650dSSadaf Ebrahimi 
101*22dc650dSSadaf Ebrahimi 
102*22dc650dSSadaf Ebrahimi /*************************************************
103*22dc650dSSadaf Ebrahimi *            Free unused JIT memory              *
104*22dc650dSSadaf Ebrahimi *************************************************/
105*22dc650dSSadaf Ebrahimi 
106*22dc650dSSadaf Ebrahimi PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
pcre2_jit_free_unused_memory(pcre2_general_context * gcontext)107*22dc650dSSadaf Ebrahimi pcre2_jit_free_unused_memory(pcre2_general_context *gcontext)
108*22dc650dSSadaf Ebrahimi {
109*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
110*22dc650dSSadaf Ebrahimi (void)gcontext;     /* Suppress warning */
111*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
112*22dc650dSSadaf Ebrahimi SLJIT_UNUSED_ARG(gcontext);
113*22dc650dSSadaf Ebrahimi #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
114*22dc650dSSadaf Ebrahimi sljit_free_unused_memory_exec();
115*22dc650dSSadaf Ebrahimi #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
116*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_JIT */
117*22dc650dSSadaf Ebrahimi }
118*22dc650dSSadaf Ebrahimi 
119*22dc650dSSadaf Ebrahimi 
120*22dc650dSSadaf Ebrahimi 
121*22dc650dSSadaf Ebrahimi /*************************************************
122*22dc650dSSadaf Ebrahimi *            Allocate a JIT stack                *
123*22dc650dSSadaf Ebrahimi *************************************************/
124*22dc650dSSadaf Ebrahimi 
125*22dc650dSSadaf Ebrahimi PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION
pcre2_jit_stack_create(size_t startsize,size_t maxsize,pcre2_general_context * gcontext)126*22dc650dSSadaf Ebrahimi pcre2_jit_stack_create(size_t startsize, size_t maxsize,
127*22dc650dSSadaf Ebrahimi   pcre2_general_context *gcontext)
128*22dc650dSSadaf Ebrahimi {
129*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
130*22dc650dSSadaf Ebrahimi 
131*22dc650dSSadaf Ebrahimi (void)gcontext;
132*22dc650dSSadaf Ebrahimi (void)startsize;
133*22dc650dSSadaf Ebrahimi (void)maxsize;
134*22dc650dSSadaf Ebrahimi return NULL;
135*22dc650dSSadaf Ebrahimi 
136*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
137*22dc650dSSadaf Ebrahimi 
138*22dc650dSSadaf Ebrahimi pcre2_jit_stack *jit_stack;
139*22dc650dSSadaf Ebrahimi 
140*22dc650dSSadaf Ebrahimi if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE)
141*22dc650dSSadaf Ebrahimi   return NULL;
142*22dc650dSSadaf Ebrahimi if (startsize > maxsize)
143*22dc650dSSadaf Ebrahimi   startsize = maxsize;
144*22dc650dSSadaf Ebrahimi startsize = (startsize + STACK_GROWTH_RATE - 1) & (size_t)(~(STACK_GROWTH_RATE - 1));
145*22dc650dSSadaf Ebrahimi maxsize = (maxsize + STACK_GROWTH_RATE - 1) & (size_t)(~(STACK_GROWTH_RATE - 1));
146*22dc650dSSadaf Ebrahimi 
147*22dc650dSSadaf Ebrahimi jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
148*22dc650dSSadaf Ebrahimi if (jit_stack == NULL) return NULL;
149*22dc650dSSadaf Ebrahimi jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);
150*22dc650dSSadaf Ebrahimi if (jit_stack->stack == NULL)
151*22dc650dSSadaf Ebrahimi   {
152*22dc650dSSadaf Ebrahimi   jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
153*22dc650dSSadaf Ebrahimi   return NULL;
154*22dc650dSSadaf Ebrahimi   }
155*22dc650dSSadaf Ebrahimi return jit_stack;
156*22dc650dSSadaf Ebrahimi 
157*22dc650dSSadaf Ebrahimi #endif
158*22dc650dSSadaf Ebrahimi }
159*22dc650dSSadaf Ebrahimi 
160*22dc650dSSadaf Ebrahimi 
161*22dc650dSSadaf Ebrahimi /*************************************************
162*22dc650dSSadaf Ebrahimi *         Assign a JIT stack to a pattern        *
163*22dc650dSSadaf Ebrahimi *************************************************/
164*22dc650dSSadaf Ebrahimi 
165*22dc650dSSadaf Ebrahimi PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
pcre2_jit_stack_assign(pcre2_match_context * mcontext,pcre2_jit_callback callback,void * callback_data)166*22dc650dSSadaf Ebrahimi pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback,
167*22dc650dSSadaf Ebrahimi   void *callback_data)
168*22dc650dSSadaf Ebrahimi {
169*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
170*22dc650dSSadaf Ebrahimi (void)mcontext;
171*22dc650dSSadaf Ebrahimi (void)callback;
172*22dc650dSSadaf Ebrahimi (void)callback_data;
173*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
174*22dc650dSSadaf Ebrahimi 
175*22dc650dSSadaf Ebrahimi if (mcontext == NULL) return;
176*22dc650dSSadaf Ebrahimi mcontext->jit_callback = callback;
177*22dc650dSSadaf Ebrahimi mcontext->jit_callback_data = callback_data;
178*22dc650dSSadaf Ebrahimi 
179*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_JIT */
180*22dc650dSSadaf Ebrahimi }
181*22dc650dSSadaf Ebrahimi 
182*22dc650dSSadaf Ebrahimi 
183*22dc650dSSadaf Ebrahimi /*************************************************
184*22dc650dSSadaf Ebrahimi *               Free a JIT stack                 *
185*22dc650dSSadaf Ebrahimi *************************************************/
186*22dc650dSSadaf Ebrahimi 
187*22dc650dSSadaf Ebrahimi PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
pcre2_jit_stack_free(pcre2_jit_stack * jit_stack)188*22dc650dSSadaf Ebrahimi pcre2_jit_stack_free(pcre2_jit_stack *jit_stack)
189*22dc650dSSadaf Ebrahimi {
190*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
191*22dc650dSSadaf Ebrahimi (void)jit_stack;
192*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
193*22dc650dSSadaf Ebrahimi if (jit_stack != NULL)
194*22dc650dSSadaf Ebrahimi   {
195*22dc650dSSadaf Ebrahimi   sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl);
196*22dc650dSSadaf Ebrahimi   jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
197*22dc650dSSadaf Ebrahimi   }
198*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_JIT */
199*22dc650dSSadaf Ebrahimi }
200*22dc650dSSadaf Ebrahimi 
201*22dc650dSSadaf Ebrahimi 
202*22dc650dSSadaf Ebrahimi /*************************************************
203*22dc650dSSadaf Ebrahimi *               Get target CPU type              *
204*22dc650dSSadaf Ebrahimi *************************************************/
205*22dc650dSSadaf Ebrahimi 
206*22dc650dSSadaf Ebrahimi const char*
PRIV(jit_get_target)207*22dc650dSSadaf Ebrahimi PRIV(jit_get_target)(void)
208*22dc650dSSadaf Ebrahimi {
209*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
210*22dc650dSSadaf Ebrahimi return "JIT is not supported";
211*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
212*22dc650dSSadaf Ebrahimi return sljit_get_platform_name();
213*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_JIT */
214*22dc650dSSadaf Ebrahimi }
215*22dc650dSSadaf Ebrahimi 
216*22dc650dSSadaf Ebrahimi 
217*22dc650dSSadaf Ebrahimi /*************************************************
218*22dc650dSSadaf Ebrahimi *              Get size of JIT code              *
219*22dc650dSSadaf Ebrahimi *************************************************/
220*22dc650dSSadaf Ebrahimi 
221*22dc650dSSadaf Ebrahimi size_t
PRIV(jit_get_size)222*22dc650dSSadaf Ebrahimi PRIV(jit_get_size)(void *executable_jit)
223*22dc650dSSadaf Ebrahimi {
224*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
225*22dc650dSSadaf Ebrahimi (void)executable_jit;
226*22dc650dSSadaf Ebrahimi return 0;
227*22dc650dSSadaf Ebrahimi #else  /* SUPPORT_JIT */
228*22dc650dSSadaf Ebrahimi sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes;
229*22dc650dSSadaf Ebrahimi SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed);
230*22dc650dSSadaf Ebrahimi return executable_sizes[0] + executable_sizes[1] + executable_sizes[2];
231*22dc650dSSadaf Ebrahimi #endif
232*22dc650dSSadaf Ebrahimi }
233*22dc650dSSadaf Ebrahimi 
234*22dc650dSSadaf Ebrahimi /* End of pcre2_jit_misc.c */
235