1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
/**
* Written in the D programming language.
* This module provides FreeBSD-specific support for sections.
*
* Copyright: Copyright Martin Nowak 2012-2013.
* License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
* Authors: Martin Nowak
* Source: $(DRUNTIMESRC src/rt/_sections_freebsd.d)
*/
module rt.sections_freebsd;
version (LDC) {} else
version (FreeBSD):
// debug = PRINTF;
debug(PRINTF) import core.stdc.stdio;
import core.stdc.stdlib : malloc, free;
import rt.deh, rt.minfo;
struct SectionGroup
{
static int opApply(scope int delegate(ref SectionGroup) dg)
{
return dg(_sections);
}
static int opApplyReverse(scope int delegate(ref SectionGroup) dg)
{
return dg(_sections);
}
@property inout(ModuleInfo*)[] modules() inout
{
return _moduleGroup.modules;
}
@property ref inout(ModuleGroup) moduleGroup() inout
{
return _moduleGroup;
}
@property immutable(FuncTable)[] ehTables() const
{
auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;
auto pend = cast(immutable(FuncTable)*)&_deh_end;
return pbeg[0 .. pend - pbeg];
}
@property inout(void[])[] gcRanges() inout
{
return _gcRanges[];
}
private:
ModuleGroup _moduleGroup;
version (X86_64)
void[][2] _gcRanges;
else
void[][1] _gcRanges;
}
void initSections()
{
_sections.moduleGroup = ModuleGroup(getModuleInfos());
version (X86_64)
{
auto pbeg = cast(void*)&etext;
auto pend = cast(void*)&_deh_end;
_sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
pbeg = cast(void*)&__progname;
pend = cast(void*)&_end;
_sections._gcRanges[1] = pbeg[0 .. pend - pbeg];
}
else
{
auto pbeg = cast(void*)&etext;
auto pend = cast(void*)&_end;
_sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
}
}
void finiSections()
{
.free(_sections.modules.ptr);
}
void[] initTLSRanges()
{
auto pbeg = cast(void*)&_tlsstart;
auto pend = cast(void*)&_tlsend;
return pbeg[0 .. pend - pbeg];
}
void finiTLSRanges(void[] rng)
{
}
void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) dg)
{
dg(rng.ptr, rng.ptr + rng.length);
}
private:
__gshared SectionGroup _sections;
// This linked list is created by a compiler generated function inserted
// into the .ctor list by the compiler.
struct ModuleReference
{
ModuleReference* next;
ModuleInfo* mod;
}
extern (C) __gshared ModuleReference* _Dmodule_ref; // start of linked list
ModuleInfo*[] getModuleInfos()
out (result)
{
foreach(m; result)
assert(m !is null);
}
body
{
size_t len;
ModuleReference *mr;
for (mr = _Dmodule_ref; mr; mr = mr.next)
len++;
auto result = (cast(ModuleInfo**).malloc(len * size_t.sizeof))[0 .. len];
len = 0;
for (mr = _Dmodule_ref; mr; mr = mr.next)
{ result[len] = mr.mod;
len++;
}
return result;
}
extern(C)
{
/* Symbols created by the compiler/linker and inserted into the
* object file that 'bracket' sections.
*/
extern __gshared
{
void* _deh_beg;
void* _deh_end;
size_t etext;
size_t _end;
version (X86_64)
size_t __progname;
}
extern
{
void* _tlsstart;
void* _tlsend;
}
}
|