1 //===- ehframe_registration.cpp -------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains code required to load the rest of the MachO runtime. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "adt.h" 14 #include "c_api.h" 15 #include "common.h" 16 #include "executor_address.h" 17 #include "wrapper_function_utils.h" 18 19 using namespace __orc_rt; 20 21 // eh-frame registration functions. 22 // We expect these to be available for all processes. 23 extern "C" void __register_frame(const void *); 24 extern "C" void __deregister_frame(const void *); 25 26 namespace { 27 28 template <typename HandleFDEFn> 29 void walkEHFrameSection(span<const char> EHFrameSection, 30 HandleFDEFn HandleFDE) { 31 const char *CurCFIRecord = EHFrameSection.data(); 32 uint64_t Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord); 33 34 while (CurCFIRecord != EHFrameSection.end() && Size != 0) { 35 const char *OffsetField = CurCFIRecord + (Size == 0xffffffff ? 12 : 4); 36 if (Size == 0xffffffff) 37 Size = *reinterpret_cast<const uint64_t *>(CurCFIRecord + 4) + 12; 38 else 39 Size += 4; 40 uint32_t Offset = *reinterpret_cast<const uint32_t *>(OffsetField); 41 42 if (Offset != 0) 43 HandleFDE(CurCFIRecord); 44 45 CurCFIRecord += Size; 46 Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord); 47 } 48 } 49 50 } // end anonymous namespace 51 52 ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult 53 __orc_rt_macho_register_ehframe_section(char *ArgData, size_t ArgSize) { 54 return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( 55 ArgData, ArgSize, 56 [](ExecutorAddrRange FrameSection) -> Error { 57 walkEHFrameSection(FrameSection.toSpan<const char>(), 58 __register_frame); 59 return Error::success(); 60 }) 61 .release(); 62 } 63 64 ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult 65 __orc_rt_macho_deregister_ehframe_section(char *ArgData, size_t ArgSize) { 66 return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( 67 ArgData, ArgSize, 68 [](ExecutorAddrRange FrameSection) -> Error { 69 walkEHFrameSection(FrameSection.toSpan<const char>(), 70 __deregister_frame); 71 return Error::success(); 72 }) 73 .release(); 74 } 75