1 // Copyright 2017 The Fuchsia Authors 2 // 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file or at 5 // https://opensource.org/licenses/MIT 6 7 #pragma once 8 9 #if defined(__ASSEMBLER__) 10 11 // This is used in assembly code to specify a code fragment that will get 12 // filled in by the given function, patch_func() when the kernel starts up. 13 // |loc| specifies which code will be patched up, so that a functioning 14 // version of the code may be used before patching takes place. This is 15 // needed, for example, for memcpy and memset. 16 #define APPLY_CODE_PATCH_FUNC_WITH_DEFAULT(patch_func, loc, size_in_bytes) \ 17 /* Add "struct CodePatchInfo" entry to the code_patch_table array. */ \ 18 .pushsection code_patch_table,"a",%progbits; \ 19 .balign 8; \ 20 .quad patch_func; /* apply_func field */ \ 21 .quad loc; /* dest_addr field */ \ 22 .quad size_in_bytes; /* dest_size field */ \ 23 .popsection 24 25 // This is used in assembly code to specify a code fragment that will get 26 // filled in by the given function, patch_func(), when the kernel starts 27 // up. This is used for selecting instructions based on which instructions 28 // the CPU supports. 29 #define APPLY_CODE_PATCH_FUNC(patch_func, size_in_bytes) \ 30 0: \ 31 /* Allocate placeholder code. We fill this with the 1-byte int3 */ \ 32 /* instruction (0xcc), which will fault if we accidentally execute */ \ 33 /* it before applying the patch. */ \ 34 .fill size_in_bytes, 1, 0xcc; \ 35 APPLY_CODE_PATCH_FUNC_WITH_DEFAULT(patch_func, 0b, size_in_bytes) 36 37 #else 38 39 #include <stdint.h> 40 41 struct CodePatchInfo { 42 void (*apply_func)(const CodePatchInfo* patch); 43 uint8_t* dest_addr; // Destination code address to patch. 44 uint64_t dest_size; // Size of placeholder code. 45 }; 46 47 // CODE_TEMPLATE(kVar, "asm...") assembles the given assembly code and 48 // makes the resulting bytes available in a global variable, kVar. kVarEnd 49 // specifies the end address of kVar, allowing the size of the code 50 // fragment to be calculated. 51 #define CODE_TEMPLATE(name, asm_code) \ 52 extern const uint8_t name[]; \ 53 extern const uint8_t name##End[]; \ 54 __asm__(".pushsection .rodata.code_template,\"a\",%progbits\n" \ 55 ".global " #name "\n" \ 56 ".global " #name "End\n" \ 57 #name ":\n" \ 58 asm_code "\n" \ 59 #name "End:\n" \ 60 ".popsection"); 61 62 #endif 63