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#include <arch/x86/feature.h> 8#include <assert.h> 9#include <lib/code_patching.h> 10#include <stddef.h> 11 12extern "C" { 13 14extern void* memcpy(void*, const void*, size_t); 15extern void* memcpy_erms(void*, const void*, size_t); 16extern void* memcpy_quad(void*, const void*, size_t); 17 18extern void* memset(void*, int, size_t); 19extern void* memset_erms(void*, int, size_t); 20extern void* memset_quad(void*, int, size_t); 21 22void x86_memcpy_select(const CodePatchInfo* patch) { 23 // We are patching a jmp rel8 instruction, which is two bytes. The rel8 24 // value is a signed 8-bit value specifying an offset relative to the 25 // address of the next instruction in memory after the jmp instruction. 26 const size_t kSize = 2; 27 const intptr_t jmp_from_address = reinterpret_cast<intptr_t>(memcpy) + kSize; 28 29 DEBUG_ASSERT(patch->dest_size == kSize); 30 DEBUG_ASSERT(reinterpret_cast<uintptr_t>(patch->dest_addr) == 31 reinterpret_cast<uintptr_t>(memcpy)); 32 33 intptr_t offset; 34 if (x86_feature_test(X86_FEATURE_ERMS)) { 35 offset = reinterpret_cast<intptr_t>(memcpy_erms) - jmp_from_address; 36 } else { 37 offset = reinterpret_cast<intptr_t>(memcpy_quad) - jmp_from_address; 38 } 39 DEBUG_ASSERT(offset >= -128 && offset <= 127); 40 patch->dest_addr[0] = 0xeb; /* jmp rel8 */ 41 patch->dest_addr[1] = static_cast<uint8_t>(offset); 42} 43 44void x86_memset_select(const CodePatchInfo* patch) { 45 // We are patching a jmp rel8 instruction, which is two bytes. The rel8 46 // value is a signed 8-bit value specifying an offset relative to the 47 // address of the next instruction in memory after the jmp instruction. 48 const size_t kSize = 2; 49 const intptr_t jmp_from_address = reinterpret_cast<intptr_t>(memset) + kSize; 50 51 DEBUG_ASSERT(patch->dest_size == kSize); 52 DEBUG_ASSERT(reinterpret_cast<uintptr_t>(patch->dest_addr) == 53 reinterpret_cast<uintptr_t>(memset)); 54 55 intptr_t offset; 56 if (x86_feature_test(X86_FEATURE_ERMS)) { 57 offset = reinterpret_cast<intptr_t>(memset_erms) - jmp_from_address; 58 } else { 59 offset = reinterpret_cast<intptr_t>(memset_quad) - jmp_from_address; 60 } 61 DEBUG_ASSERT(offset >= -128 && offset <= 127); 62 patch->dest_addr[0] = 0xeb; /* jmp rel8 */ 63 patch->dest_addr[1] = static_cast<uint8_t>(offset); 64} 65 66} 67