1 /** 2 * Written in the D programming language. 3 * This module provides OS X x86-64 specific support for sections. 4 * 5 * Copyright: Copyright Digital Mars 2016. 6 * License: Distributed under the 7 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 8 * (See accompanying file LICENSE) 9 * Authors: Walter Bright, Sean Kelly, Martin Nowak, Jacob Carlborg 10 * Source: $(DRUNTIMESRC rt/_sections_osx_x86_64.d) 11 */ 12 module rt.sections_osx_x86_64; 13 14 version (OSX) 15 version = Darwin; 16 else version (iOS) 17 version = Darwin; 18 else version (TVOS) 19 version = Darwin; 20 else version (WatchOS) 21 version = Darwin; 22 23 version (Darwin): 24 version (X86_64): 25 26 // debug = PRINTF; 27 import core.stdc.stdio; 28 import core.stdc.string, core.stdc.stdlib; 29 import core.sys.posix.pthread; 30 import core.sys.darwin.mach.dyld; 31 import core.sys.darwin.mach.getsect; 32 33 import rt.deh; 34 import rt.minfo; 35 import rt.sections_darwin_64; 36 import core.internal.container.array; 37 import rt.util.utility : safeAssert; 38 39 struct SectionGroup 40 { 41 static int opApply(scope int delegate(ref SectionGroup) dg) 42 { 43 return dg(_sections); 44 } 45 46 static int opApplyReverse(scope int delegate(ref SectionGroup) dg) 47 { 48 return dg(_sections); 49 } 50 51 @property immutable(ModuleInfo*)[] modules() const nothrow @nogc 52 { 53 return _moduleGroup.modules; 54 } 55 56 @property ref inout(ModuleGroup) moduleGroup() inout return nothrow @nogc 57 { 58 return _moduleGroup; 59 } 60 61 @property inout(void[])[] gcRanges() inout nothrow @nogc 62 { 63 return _gcRanges[]; 64 } 65 66 @property immutable(FuncTable)[] ehTables() const nothrow @nogc 67 { 68 return _ehTables[]; 69 } 70 71 private: 72 immutable(FuncTable)[] _ehTables; 73 ModuleGroup _moduleGroup; 74 Array!(void[]) _gcRanges; 75 } 76 77 /**** 78 * Boolean flag set to true while the runtime is initialized. 79 */ 80 __gshared bool _isRuntimeInitialized; 81 82 /**** 83 * Gets called on program startup just before GC is initialized. 84 */ 85 void initSections() nothrow @nogc 86 { 87 _dyld_register_func_for_add_image(§ions_osx_onAddImage); 88 _isRuntimeInitialized = true; 89 } 90 91 /*** 92 * Gets called on program shutdown just after GC is terminated. 93 */ 94 void finiSections() nothrow @nogc 95 { 96 _sections._gcRanges.reset(); 97 _isRuntimeInitialized = false; 98 } 99 100 void[] initTLSRanges() nothrow @nogc 101 { 102 static ubyte tlsAnchor; 103 104 auto range = getTLSRange(&tlsAnchor); 105 safeAssert(range !is null, "Could not determine TLS range."); 106 return range; 107 } 108 109 void finiTLSRanges(void[] rng) nothrow @nogc 110 { 111 112 } 113 114 void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow 115 { 116 dg(rng.ptr, rng.ptr + rng.length); 117 } 118 119 private: 120 121 __gshared SectionGroup _sections; 122 123 extern (C) void sections_osx_onAddImage(const scope mach_header* h, intptr_t slide) 124 { 125 foreachDataSection(h, slide, (sectionData) { _sections._gcRanges.insertBack(sectionData); }); 126 127 auto minfosect = getSection(h, slide, "__DATA", "__minfodata"); 128 if (minfosect != null) 129 { 130 // no support for multiple images yet 131 // take the sections from the last static image which is the executable 132 if (_isRuntimeInitialized) 133 { 134 fprintf(stderr, "Loading shared libraries isn't yet supported on OSX.\n"); 135 return; 136 } 137 else if (_sections.modules.ptr !is null) 138 { 139 fprintf(stderr, "Shared libraries are not yet supported on OSX.\n"); 140 } 141 142 debug(PRINTF) printf(" minfodata\n"); 143 auto p = cast(immutable(ModuleInfo*)*)minfosect.ptr; 144 immutable len = minfosect.length / (*p).sizeof; 145 146 _sections._moduleGroup = ModuleGroup(p[0 .. len]); 147 } 148 149 auto ehsect = getSection(h, slide, "__DATA", "__deh_eh"); 150 if (ehsect != null) 151 { 152 debug(PRINTF) printf(" deh_eh\n"); 153 auto p = cast(immutable(FuncTable)*)ehsect.ptr; 154 immutable len = ehsect.length / (*p).sizeof; 155 156 _sections._ehTables = p[0 .. len]; 157 } 158 }