1/*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7#define ASSEMBLER_ONLY
8#include "templates.h"
9#undef ASSEMBLER_ONLY
10
11        .global template_func
12        .global template_func_end
13template_func:
14#if defined(__i386__)
15        movl $MARKER_OLD, %eax
16        popl %ecx
17        and  $0xffffffe0,%ecx
18        jmp  *%ecx
19        call template_func
20#elif defined(__x86_64__)
21        disp = template_func_end - 4
22        xorl %r11d, %r11d
23        movq disp(%r15,%r11,1), %rax
24        popq %r11
25        andl $0xffffffe0,%r11d
26        addq %r15,%r11
27        jmpq *%r11
28        call template_func
29        test $0xffffffff,%r11d
30        movq $MARKER_OLD, %rax
31#else
32# error "Unsupported architecture"
33#endif
34template_func_end:
35
36
37        .global template_func_replacement
38        .global template_func_replacement_end
39        .p2align 5
40template_func_replacement:
41#if defined(__i386__)
42        movl $MARKER_NEW, %eax                       /* replaces constant */
43        popl %ecx
44        and  $0xffffffe0,%ecx
45        jmp  *%ecx
46        call (template_func_replacement - 32)  /* replaces a call target, the
47                                                * new target is bundle aligned
48                                                * and target address outside
49                                                * modified section */
50#elif defined(__x86_64__)
51        /*
52         * Tests all modifications that are currently allowed by
53         * service_runtime.
54         */
55        new_disp = template_func_replacement_end - 4
56        xorl %r11d, %r11d
57        movq new_disp(%r15,%r11,1), %rax       /* replaces displacement */
58        popq %r11
59        andl $0xffffffe0,%r11d
60        addq %r15,%r11
61        jmpq *%r11
62        call (template_func_replacement - 32)  /* replaces a call target, the
63                                                * new target is bundle aligned
64                                                * and target address outside
65                                                * modified section  */
66        test $0xffffffff,%r11d
67        movq $MARKER_NEW, %rax                       /* replaces constant */
68#else
69# error "Unsupported architecture"
70#endif
71template_func_replacement_end:
72
73
74#if defined(__i386__)
75        .global jump_into_super_inst_original
76        .global jump_into_super_inst_original_end
77        .p2align 5
78jump_into_super_inst_original:
79jump_is_ok:
80        and  $0xffffffe0,%ecx
81        jmp  *%ecx
82        call jump_is_ok
83jump_into_super_inst_original_end:
84
85
86/* This should not validate, so keep it as data. */
87        .data
88        .global jump_into_super_inst_modified
89        .global jump_into_super_inst_modified_end
90        .p2align 5
91jump_into_super_inst_modified:
92        and  $0xffffffe0,%ecx
93jump_is_awful:
94        jmp  *%ecx
95        call jump_is_awful
96jump_into_super_inst_modified_end:
97        .text
98#endif
99
100
101#if defined(__x86_64__)
102        .global jump_into_super_inst_original
103        .global jump_into_super_inst_original_end
104        .p2align 5
105jump_into_super_inst_original:
106jump_is_ok:
107        andl $0xffffffe0,%r11d
108        addq %r15,%r11
109        jmpq *%r11
110        call jump_is_ok
111jump_into_super_inst_original_end:
112
113
114/* This should not validate, so keep it as data. */
115        .data
116        .global jump_into_super_inst_modified
117        .global jump_into_super_inst_modified_end
118        .p2align 5
119jump_into_super_inst_modified:
120        andl $0xffffffe0,%r11d
121        addq %r15,%r11
122jump_is_awful:
123        jmpq *%r11
124        call jump_is_awful
125jump_into_super_inst_modified_end:
126        .text
127#endif
128
129
130        .global template_func_nonreplacement
131        .global template_func_nonreplacement_end
132        .global template_func_misaligned_replacement
133        .global template_func_misaligned_replacement_end
134        .p2align 5
135template_func_nonreplacement:
136template_func_misaligned_replacement:
137#if defined(__i386__)
138        nop                                    /* nop creates misalignment in
139                                                * replacing section which makes
140                                                * it illegal */
141        movl $MARKER_OLD, %eax
142        popl %ecx
143        and  $0xffffffe0,%ecx
144        jmp  *%ecx
145        call template_func_misaligned_replacement
146#elif defined(__x86_64__)
147        nop                                    /* nop creates misalignment in
148                                                * replacing section which makes
149                                                * it illegal */
150        xorl %r11d, %r11d
151        movq disp(%r15,%r11,1), %rax
152        popq %r11
153        andl $0xffffffe0,%r11d
154        addq %r15,%r11
155        jmpq *%r11
156        call template_func_misaligned_replacement
157        test $0xffffffff,%r11d
158        movq $MARKER_OLD, %rax
159#else
160# error "Unsupported architecture"
161#endif
162template_func_misaligned_replacement_end:
163template_func_nonreplacement_end:
164
165
166        .global hlts
167        .global hlts_end
168        .p2align 5
169hlts:
170        .fill 32, 1, 0xf4
171hlts_end:
172
173
174        .global branch_forwards
175        .global branch_forwards_end
176        .global branch_backwards
177        .global branch_backwards_end
178        .p2align 5
179branch_forwards:
180        jmp branch_backwards
181        /*
182         * The assembler generates a bad jmp if I use ".p2align 5"
183         * instead of padding manually.  TODO(mseaborn): Investigate.
184         */
185        .fill 32 - 5, 1, 0x90
186branch_forwards_end:
187branch_backwards:
188        jmp branch_forwards
189        /*
190         * The assembler generates a bad jmp if I use ".p2align 5"
191         * instead of padding manually.
192         */
193        .fill 32 - 5, 1, 0x90
194branch_backwards_end:
195
196
197        /*
198         * We include disallowed code below, so this must go into the
199         * data segment.
200         */
201        .data
202
203
204        .global invalid_code
205        .global invalid_code_end
206        .p2align 5
207invalid_code:
208        int $0x80
209        ret
210invalid_code_end:
211
212
213        .global template_func_illegal_register_replacement
214        .global template_func_illegal_register_replacement_end
215        .p2align 5
216template_func_illegal_register_replacement:
217#if defined(__i386__)
218        movl $MARKER_OLD, %eax
219        popl %ecx
220        and  $0xffffffe0,%ecx
221        jmp  *%edx                             /* replaces register here, jmp
222                                                * becomes illegal */
223        call template_func_illegal_register_replacement
224#elif defined(__x86_64__)
225        xorl %r11d, %r11d
226        movq disp(%r15,%r11,1), %rax
227        popq %r11
228        andl $0xffffffe0,%r11d
229        addq %r15,%r11
230        jmpq *%r11
231        call template_func_illegal_register_replacement
232        test $0xffffffff,%r11d
233        movq $MARKER_OLD, %rbx                       /* replaces register
234                                                * which is not allowed */
235#else
236# error "Unsupported architecture"
237#endif
238template_func_illegal_register_replacement_end:
239
240
241        .global template_func_illegal_guard_replacement
242        .global template_func_illegal_guard_replacement_end
243        .p2align 5
244template_func_illegal_guard_replacement:
245#if defined(__i386__)
246        movl $MARKER_OLD, %eax
247        popl %ecx
248        and  $0xffffffff,%ecx                  /* modifies mask */
249        jmp  *%ecx
250        call template_func_illegal_guard_replacement
251#elif defined(__x86_64__)
252        xorl %r14d, %r14d                      /* modifies memory guard */
253        movq disp(%r15,%r11,1), %rax
254        popq %r11
255        andl $0xffffffe0,%r11d
256        addq %r15,%r11
257        jmpq *%r11
258        call template_func_illegal_guard_replacement
259        test $0xffffffff,%r11d
260        movq $1234, %rax
261#else
262# error "Unsupported architecture"
263#endif
264template_func_illegal_guard_replacement_end:
265
266
267        .global template_func_illegal_call_target
268        .global template_func_illegal_call_target_end
269        .p2align 5
270template_func_illegal_call_target:
271#if defined(__i386__)
272        movl $1234, %eax
273        popl %ecx
274        and  $0xffffffe0,%ecx
275        jmp  *%ecx
276        call (template_func_illegal_call_target - 31)  /* target of a call
277                                                * instruction is beyond
278                                                * replaced section, and it is
279                                                * not bundle_aligned */
280#elif defined(__x86_64__)
281        xorl %r11d, %r11d
282        movq disp(%r15,%r11,1), %rax
283        popq %r11
284        andl $0xffffffe0,%r11d
285        addq %r15,%r11
286        jmpq *%r11
287        call (template_func_illegal_call_target - 31)  /* target of a call
288                                                * instruction is beyond
289                                                * replaced section, and it is
290                                                * not bundle_aligned */
291        test $0xffffffff,%r11d
292        movq $1234, %rax
293#else
294# error "Unsupported architecture"
295#endif
296template_func_illegal_call_target_end:
297
298
299        .global template_func_illegal_constant_replacement
300        .global template_func_illegal_constant_replacement_end
301        .p2align 5
302template_func_illegal_constant_replacement:
303#if defined(__i386__)
304        hlt  /* not applicable */
305#elif defined(__x86_64__)
306        xorl %r11d, %r11d
307        movq disp(%r15,%r11,1), %rax
308        popq %r11
309        andl $0xffffffe0,%r11d
310        addq %r15,%r11
311        jmpq *%r11
312        call (template_func_illegal_constant_replacement)
313        test $0xf0f0f0f0,%r11d             /* can't change constant in test */
314        movq $MARKER_OLD, %rax
315#else
316# error "Unsupported architecture"
317#endif
318template_func_illegal_constant_replacement_end:
319
320        .global template_func_external_jump_target
321        .global template_func_external_jump_target_end
322        .p2align 5
323template_func_external_jump_target:
324#if defined(__i386__)
325        movl $MARKER_OLD, %eax
326        jmp external_jump_return
327        call template_func_external_jump_target
328        movl $MARKER_STABLE, %eax
329external_jump_return:
330        popl %ecx
331        and  $0xffffffe0,%ecx
332        jmp  *%ecx
333#elif defined(__x86_64__)
334        movq $MARKER_OLD, %rax
335        jmp external_jump_return
336        call template_func_external_jump_target
337        movq $MARKER_STABLE, %rax
338external_jump_return:
339        popq %r11
340        andl $0xffffffe0,%r11d
341        addq %r15,%r11
342        jmpq *%r11
343#else
344# error "Unsupported architecture"
345#endif
346template_func_external_jump_target_end:
347
348        .global template_func_external_jump_target_replace
349        .global template_func_external_jump_target_replace_end
350        .p2align 5
351template_func_external_jump_target_replace:
352#if defined(__i386__)
353        movl $MARKER_NEW, %eax
354        jmp external_jump_replace_return
355        call template_func_external_jump_target_replace
356        movl $MARKER_STABLE, %eax
357external_jump_replace_return:
358        popl %ecx
359        and  $0xffffffe0,%ecx
360        jmp  *%ecx
361#elif defined(__x86_64__)
362        movq $MARKER_NEW, %rax
363        jmp external_jump_replace_return
364        call template_func_external_jump_target_replace
365        movq $MARKER_STABLE, %rax
366external_jump_replace_return:
367        popq %r11
368        andl $0xffffffe0,%r11d
369        addq %r15,%r11
370        jmpq *%r11
371#else
372# error "Unsupported architecture"
373#endif
374template_func_external_jump_target_replace_end:
375.global template_instr
376.global template_instr_end
377.global template_instr_replace
378.global template_instr_replace_end
379template_instr:
380        mov $0,%eax
381template_instr_end:
382template_instr_replace:
383        mov $0x11111111,%eax
384template_instr_replace_end:
385
386#if defined(__i386__)
387        .global delete_superinstruction
388        .global delete_superinstruction_end
389        .global delete_superinstruction_replace
390        .global delete_superinstruction_replace_end
391        .p2align 5
392delete_superinstruction:
393        and  $0xffffffe0,%ecx
394        jmp  *%ecx
395delete_superinstruction_end:
396delete_superinstruction_replace:
397        mov    $0x12345678,%ecx
398delete_superinstruction_replace_end:
399        .global delete_superinstruction_split
400        .global delete_superinstruction_split_end
401        .global delete_superinstruction_split_replace
402        .global delete_superinstruction_split_replace_end
403        .p2align 5
404delete_superinstruction_split:
405        and  $0xffffffe0,%ecx
406        jmp  *%ecx
407delete_superinstruction_split_end:
408delete_superinstruction_split_replace:
409        and  $0xffffffe0,%ecx
410        mov  %ecx,%ecx
411delete_superinstruction_split_replace_end:
412        .global create_superinstruction
413        .global create_superinstruction_end
414        .global create_superinstruction_replace
415        .global create_superinstruction_replace_end
416        .p2align 5
417create_superinstruction:
418        mov    $0x12345678,%ecx
419create_superinstruction_end:
420create_superinstruction_replace:
421        and  $0xffffffe0,%ecx
422        jmp  *%ecx
423create_superinstruction_replace_end:
424        .global create_superinstruction_split
425        .global create_superinstruction_split_end
426        .global create_superinstruction_split_replace
427        .global create_superinstruction_split_replace_end
428        .p2align 5
429create_superinstruction_split:
430        and  $0xffffffe0,%ecx
431        mov  %ecx,%ecx
432create_superinstruction_split_end:
433create_superinstruction_split_replace:
434        and  $0xffffffe0,%ecx
435        jmp  *%ecx
436create_superinstruction_split_replace_end:
437        .global change_boundaries_first_instructions
438        .global change_boundaries_first_instructions_end
439        .global change_boundaries_first_instructions_replace
440        .global change_boundaries_first_instructions_replace_end
441        .p2align 5
442change_boundaries_first_instructions:
443        mov %eax,%eax
444        lea (%eax,%eax),%eax
445change_boundaries_first_instructions_end:
446change_boundaries_first_instructions_replace:
447        lea (%eax,%eax),%eax
448        mov %eax,%eax
449change_boundaries_first_instructions_replace_end:
450        .global change_boundaries_last_instructions
451        .global change_boundaries_last_instructions_end
452        .global change_boundaries_last_instructions_replace
453        .global change_boundaries_last_instructions_replace_end
454        .p2align 5
455change_boundaries_last_instructions:
456        .fill 32 - 5, 1, 0x90
457        mov %eax,%eax
458        lea (%eax,%eax),%eax
459change_boundaries_last_instructions_end:
460change_boundaries_last_instructions_replace:
461        .fill 32 - 5, 1, 0x90
462        lea (%eax,%eax),%eax
463        mov %eax,%eax
464change_boundaries_last_instructions_replace_end:
465#elif defined(__x86_64__)
466#else
467# error "Unsupported architecture"
468#endif
469