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 17 using namespace __orc_rt; 18 19 // eh-frame registration functions. 20 // We expect these to be available for all processes. 21 extern "C" void __register_frame(const void *); 22 extern "C" void __deregister_frame(const void *); 23 24 namespace { 25 26 template <typename HandleFDEFn> 27 void walkEHFrameSection(span<const char> EHFrameSection, 28 HandleFDEFn HandleFDE) { 29 const char *CurCFIRecord = EHFrameSection.data(); 30 uint64_t Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord); 31 32 while (CurCFIRecord != EHFrameSection.end() && Size != 0) { 33 const char *OffsetField = CurCFIRecord + (Size == 0xffffffff ? 12 : 4); 34 if (Size == 0xffffffff) 35 Size = *reinterpret_cast<const uint64_t *>(CurCFIRecord + 4) + 12; 36 else 37 Size += 4; 38 uint32_t Offset = *reinterpret_cast<const uint32_t *>(OffsetField); 39 40 if (Offset != 0) 41 HandleFDE(CurCFIRecord); 42 43 CurCFIRecord += Size; 44 Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord); 45 } 46 } 47 48 } // end anonymous namespace 49 50 ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult 51 __orc_rt_macho_register_ehframe_section(char *ArgData, size_t ArgSize) { 52 // NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer 53 // is taken to be the range of the eh-frame section. 54 bool HasError = false; 55 walkEHFrameSection(span<const char>(ArgData, ArgSize), __register_frame); 56 return __orc_rt_CreateCWrapperFunctionResultFromRange((char*)&HasError, 57 sizeof(HasError)); 58 } 59 60 ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult 61 __orc_rt_macho_deregister_ehframe_section(char *ArgData, size_t ArgSize) { 62 // NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer 63 // is taken to be the range of the eh-frame section. 64 bool HasError = false; 65 walkEHFrameSection(span<const char>(ArgData, ArgSize), __deregister_frame); 66 return __orc_rt_CreateCWrapperFunctionResultFromRange((char*)&HasError, 67 sizeof(HasError)); 68 } 69