1 /**
2  *
3  * Copyright: Copyright Digital Mars 2000 - 2012.
4  * License: Distributed under the
5  *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
6  *    (See accompanying file LICENSE)
7  * Authors:   Walter Bright, Sean Kelly, Martin Nowak
8  * Source: $(DRUNTIMESRC rt/_sections.d)
9  */
10 
11 module rt.sections;
12 
13 version (OSX)
14     version = Darwin;
15 else version (iOS)
16     version = Darwin;
17 else version (TVOS)
18     version = Darwin;
19 else version (WatchOS)
20     version = Darwin;
21 
22 version (CRuntime_Glibc)
23     public import rt.sections_elf_shared;
24 else version (CRuntime_Musl)
25     public import rt.sections_elf_shared;
26 else version (FreeBSD)
27     public import rt.sections_elf_shared;
28 else version (NetBSD)
29     public import rt.sections_elf_shared;
30 else version (OpenBSD)
31 {
32     /**
33      * OpenBSD is missing support needed for elf_shared.
34      * See the top of sections_solaris.d for more info.
35      */
36 
37     public import rt.sections_solaris;
38 }
39 else version (DragonFlyBSD)
40     public import rt.sections_elf_shared;
41 else version (Solaris)
42     public import rt.sections_solaris;
43 else version (Darwin)
44 {
45     version (X86_64)
46         public import rt.sections_osx_x86_64;
47     else version (X86)
48         public import rt.sections_osx_x86;
49     else
50         static assert(0, "unimplemented");
51 }
52 else version (CRuntime_DigitalMars)
53     public import rt.sections_win32;
54 else version (CRuntime_Microsoft)
55     public import rt.sections_win64;
56 else version (CRuntime_Bionic)
57     public import rt.sections_android;
58 else version (CRuntime_UClibc)
59     public import rt.sections_elf_shared;
60 else
61     static assert(0, "unimplemented");
62 
63 import rt.deh, rt.minfo;
64 
65 template isSectionGroup(T)
66 {
67     enum isSectionGroup =
68         is(typeof(T.init.modules) == immutable(ModuleInfo*)[]) &&
69         is(typeof(T.init.moduleGroup) == ModuleGroup) &&
70         (!is(typeof(T.init.ehTables)) || is(typeof(T.init.ehTables) == immutable(FuncTable)[])) &&
71         is(typeof(T.init.gcRanges) == void[][]) &&
72         is(typeof({ foreach (ref T; T) {}})) &&
73         is(typeof({ foreach_reverse (ref T; T) {}}));
74 }
75 static assert(isSectionGroup!(SectionGroup));
76 static assert(is(typeof(&initSections) == void function() nothrow @nogc));
77 static assert(is(typeof(&finiSections) == void function() nothrow @nogc));
78 static assert(is(typeof(&initTLSRanges) RT == return) &&
79               is(typeof(&initTLSRanges) == RT function() nothrow @nogc) &&
80               is(typeof(&finiTLSRanges) == void function(RT) nothrow @nogc) &&
81               is(typeof(&scanTLSRanges) == void function(RT, scope void delegate(void*, void*) nothrow) nothrow));
82 
83 version (Shared)
84 {
85     static assert(is(typeof(&pinLoadedLibraries) == void* function() nothrow @nogc));
86     static assert(is(typeof(&unpinLoadedLibraries) == void function(void*) nothrow @nogc));
87     static assert(is(typeof(&inheritLoadedLibraries) == void function(void*) nothrow @nogc));
88     static assert(is(typeof(&cleanupLoadedLibraries) == void function() nothrow @nogc));
89 }
90 
91 bool scanDataSegPrecisely() nothrow @nogc
92 {
93     import rt.config;
94     string opt = rt_configOption("scanDataSeg");
95     switch (opt)
96     {
97         case "":
98         case "conservative":
99             return false;
100         case "precise":
101             return true;
102         default:
103             __gshared err = new Error("DRT invalid scanDataSeg option, must be 'precise' or 'conservative'");
104             throw err;
105     }
106 }