github.com/bytedance/mockey@v1.2.10/internal/monkey/fn/copy_darwin.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package fn 18 19 import ( 20 "reflect" 21 "runtime" 22 23 "github.com/bytedance/mockey/internal/monkey/common" 24 "github.com/bytedance/mockey/internal/tool" 25 ) 26 27 // Copy copies the original function code to a new page, injecting the code to the target function. 28 func Copy(targetPtr, oriFn interface{}) { 29 targetVal := reflect.ValueOf(targetPtr) 30 tool.Assert(targetVal.Type().Kind() == reflect.Ptr, "'%v' is not a pointer", targetPtr) 31 targetType := targetVal.Type().Elem() 32 tool.Assert(targetType.Kind() == reflect.Func, "'%v' is not a function pointer", targetPtr) 33 oriVal := reflect.ValueOf(oriFn) 34 tool.Assert(tool.CheckFuncArgs(targetType, oriVal.Type(), 0, 0), "target and ori not match") 35 36 oriAddr := oriVal.Pointer() 37 tool.DebugPrintf("Copy: copy start for %v\n", runtime.FuncForPC(oriAddr).Name()) 38 // allocate a new page to store copied fn 39 targetCode := common.AllocatePage() 40 oriCode := common.BytesOf(oriAddr, common.PageSize()) 41 tool.DebugPrintf("Copy: target addr: 0x%x, ori addr: 0x%x\n", common.PtrOf(targetCode), oriAddr) 42 // copy ori fn code to target code 43 copyCode(targetCode, oriCode) 44 // inject target code into the target function 45 InjectInto(targetVal, targetCode) 46 tool.DebugPrintf("Copy: copy end for %v\n", runtime.FuncForPC(oriAddr).Name()) 47 }