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(&sections_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 }