Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
add SectionGroup
Browse files Browse the repository at this point in the history
- unify interface to platform specific section handling
- static executables have a single SectionGroup
- each shared library adds another SectionGroup
- use new DSO code for ModuleInfos
  • Loading branch information
MartinNowak committed Feb 28, 2013
1 parent 37f9bd2 commit 0e10e7e
Show file tree
Hide file tree
Showing 12 changed files with 567 additions and 189 deletions.
8 changes: 7 additions & 1 deletion mak/MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ MANIFEST=\
src\rt\deh.d \
src\rt\deh2.d \
src\rt\dmain2.d \
src\rt\dso.d \
src\rt\dylib_fixes.c \
src\rt\image.d \
src\rt\invariant.d \
Expand All @@ -182,6 +181,13 @@ MANIFEST=\
src\rt\obj.d \
src\rt\qsort.d \
src\rt\qsort2.d \
src\rt\sections.d \
src\rt\sections_freebsd.d \
src\rt\sections_linux.d \
src\rt\sections_osx.d \
src\rt\sections_solaris.d \
src\rt\sections_win32.d \
src\rt\sections_win64.d \
src\rt\switch_.d \
src\rt\tls.S \
src\rt\tlsgc.d \
Expand Down
8 changes: 7 additions & 1 deletion mak/SRCS
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ SRCS=\
src\rt\deh.d \
src\rt\deh2.d \
src\rt\dmain2.d \
src\rt\dso.d \
src\rt\invariant.d \
src\rt\invariant_.d \
src\rt\lifetime.d \
Expand All @@ -95,6 +94,13 @@ SRCS=\
src\rt\monitor_.d \
src\rt\obj.d \
src\rt\qsort.d \
src\rt\sections.d \
src\rt\sections_freebsd.d \
src\rt\sections_linux.d \
src\rt\sections_osx.d \
src\rt\sections_solaris.d \
src\rt\sections_win32.d \
src\rt\sections_win64.d \
src\rt\switch_.d \
src\rt\tlsgc.d \
src\rt\trace.d \
Expand Down
11 changes: 5 additions & 6 deletions src/rt/dmain2.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module rt.dmain2;
private
{
import rt.memory;
import rt.sections;
import rt.util.console;
import rt.util.string;
import core.stdc.stddef;
Expand Down Expand Up @@ -281,18 +282,13 @@ alias void delegate(Throwable) ExceptionHandler;

extern (C) bool rt_init(ExceptionHandler dg = null)
{
// reference _d_dso_registry in every executable/shared
// library for weak linkage support
import rt.dso;
static if (USE_DSO)
__gshared dummy_ref = &_d_dso_registry;

version (OSX)
_d_osx_image_init2();
_d_criticalInit();

try
{
initSections();
gc_init();
initStaticDataGC();
rt_moduleCtor();
Expand Down Expand Up @@ -325,6 +321,7 @@ extern (C) bool rt_term(ExceptionHandler dg = null)
thread_joinAll();
rt_moduleDtor();
gc_term();
finiSections();
return true;
}
catch (Throwable e)
Expand Down Expand Up @@ -603,6 +600,7 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)

void runAll()
{
initSections();
gc_init();
initStaticDataGC();
rt_moduleCtor();
Expand All @@ -615,6 +613,7 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
thread_joinAll();
rt_moduleDtor();
gc_term();
finiSections();
}

tryExec(&runAll);
Expand Down
10 changes: 0 additions & 10 deletions src/rt/memory_osx.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ version(OSX):
import src.core.sys.osx.mach.dyld;
import src.core.sys.osx.mach.getsect;

extern (C) extern __gshared ModuleInfo*[] _moduleinfo_array;
extern (C) extern __gshared ubyte[] _deh_eh_array;
extern (C) extern __gshared ubyte[][2] _tls_data_array;

Expand Down Expand Up @@ -88,15 +87,6 @@ extern (C) void onAddImage(in mach_header* h, intptr_t slide)
gc_addRange(sect.ptr, sect.length);
}

if (auto sect = getSection(h, slide, "__DATA", "__minfodata"))
{
//printf(" minfodata\n");
/* BUG: this will fail if there are multiple images with __minfodata
* sections. Not set up to handle that.
*/
_moduleinfo_array = (cast(ModuleInfo**)sect.ptr)[0 .. sect.length / _moduleinfo_array[0].sizeof];
}

if (auto sect = getSection(h, slide, "__DATA", "__deh_eh"))
{
//printf(" deh_eh\n");
Expand Down
163 changes: 26 additions & 137 deletions src/rt/minfo.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module rt.minfo;

import core.stdc.stdlib; // alloca
import core.stdc.string; // memcpy
import rt.sections;

enum
{
Expand Down Expand Up @@ -89,7 +90,7 @@ struct ModuleGroup
_ctors = null;
.free(_tlsctors.ptr);
_tlsctors = null;
_modules = null;
// _modules = null; // let the owner free it
}

private:
Expand All @@ -108,14 +109,17 @@ int moduleinfos_apply(scope int delegate(ref ModuleInfo*) dg)
{
int ret = 0;

foreach (m; _moduleGroup._modules)
foreach (ref sg; SectionGroup)
{
// TODO: Should null ModuleInfo be allowed?
if (m !is null)
foreach (m; sg.modules)
{
ret = dg(m);
if (ret)
break;
// TODO: Should null ModuleInfo be allowed?
if (m !is null)
{
ret = dg(m);
if (ret)
break;
}
}
}
return ret;
Expand All @@ -127,153 +131,38 @@ int moduleinfos_apply(scope int delegate(ref ModuleInfo*) dg)

extern (C) void rt_moduleCtor()
{
_moduleGroup = ModuleGroup(getModuleInfos());
_moduleGroup.sortCtors();
_moduleGroup.runCtors();
foreach (ref sg; SectionGroup)
{
sg.moduleGroup.sortCtors();
sg.moduleGroup.runCtors();
}
}

extern (C) void rt_moduleTlsCtor()
{
_moduleGroup.runTlsCtors();
}

extern (C) void rt_moduleTlsDtor()
{
_moduleGroup.runTlsDtors();
}

extern (C) void rt_moduleDtor()
{
_moduleGroup.runDtors();
version (Win32) {} else
.free(_moduleGroup._modules.ptr);
_moduleGroup.free();
}

/********************************************
* Access compiler generated list of modules.
*/

version (Win32)
{
// Windows: this gets initialized by minit.asm
// Posix: this gets initialized in _moduleCtor()
extern(C) __gshared ModuleInfo*[] _moduleinfo_array;
extern(C) void _minit();
}
else version (Win64)
{
extern (C)
foreach (ref sg; SectionGroup)
{
extern __gshared void* _minfo_beg;
extern __gshared void* _minfo_end;

// Dummy so Win32 code can still call it
extern(C) void _minit() { }
sg.moduleGroup.runTlsCtors();
}
}
else version (OSX)
{
extern (C) __gshared ModuleInfo*[] _moduleinfo_array;
}
else version (Posix)

extern (C) void rt_moduleTlsDtor()
{
// This linked list is created by a compiler generated function inserted
// into the .ctor list by the compiler.
struct ModuleReference
foreach_reverse (ref sg; SectionGroup)
{
ModuleReference* next;
ModuleInfo* mod;
sg.moduleGroup.runTlsDtors();
}

extern (C) __gshared ModuleReference* _Dmodule_ref; // start of linked list
}
else
{
static assert(0);
}

ModuleInfo*[] getModuleInfos()
out (result)
{
foreach(m; result)
assert(m !is null);
}
body
extern (C) void rt_moduleDtor()
{
typeof(return) result = void;

version (OSX)
{
// _moduleinfo_array is set by src.rt.memory_osx.onAddImage()
// but we need to throw out any null pointers
auto p = _moduleinfo_array.ptr;
auto pend = _moduleinfo_array.ptr + _moduleinfo_array.length;

// count non-null pointers
size_t cnt;
for (; p < pend; ++p)
if (*p !is null) ++cnt;

result = (cast(ModuleInfo**).malloc(cnt * size_t.sizeof))[0 .. cnt];

p = _moduleinfo_array.ptr;
cnt = 0;
for (; p < pend; ++p)
if (*p !is null) result[cnt++] = *p;
}
// all other Posix variants (FreeBSD, Solaris, Linux)
else version (Posix)
{
size_t len;
ModuleReference *mr;

for (mr = _Dmodule_ref; mr; mr = mr.next)
len++;
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++;
}
}
else version (Win32)
{
// _minit directly alters the global _moduleinfo_array
_minit();
result = _moduleinfo_array;
}
else version (Win64)
{
auto m = (cast(ModuleInfo**)&_minfo_beg)[1 .. &_minfo_end - &_minfo_beg];
/* Because of alignment inserted by the linker, various null pointers
* are there. We need to filter them out.
*/
auto p = m.ptr;
auto pend = m.ptr + m.length;

// count non-null pointers
size_t cnt;
for (; p < pend; ++p)
{
if (*p !is null) ++cnt;
}

result = (cast(ModuleInfo**).malloc(cnt * size_t.sizeof))[0 .. cnt];

p = m.ptr;
cnt = 0;
for (; p < pend; ++p)
if (*p !is null) result[cnt++] = *p;
}
else
foreach_reverse (ref sg; SectionGroup)
{
static assert(0);
sg.moduleGroup.runDtors();
sg.moduleGroup.free();
}
return result;
}


/********************************************
*/

Expand Down
38 changes: 38 additions & 0 deletions src/rt/sections.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
*
* Copyright: Copyright Digital Mars 2000 - 2012.
* License: Distributed under the
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
* (See accompanying file LICENSE)
* Authors: Walter Bright, Sean Kelly, Martin Nowak
* Source: $(DRUNTIMESRC src/rt/_sections.d)
*/

module rt.sections;

version (linux)
public import rt.sections_linux;
else version (FreeBSD)
public import rt.sections_freebsd;
else version (OSX)
public import rt.sections_osx;
else version (Win32)
public import rt.sections_win32;
else version (Win64)
public import rt.sections_win64;
else
static assert(0, "unimplemented");

import rt.minfo;

template isSectionGroup(T)
{
enum isSectionGroup =
is(typeof(T.init.modules) == ModuleInfo*[]) &&
is(typeof(T.init.moduleGroup) == ModuleGroup) &&
is(typeof({ foreach (ref T; T) {}})) &&
is(typeof({ foreach_reverse (ref T; T) {}}));
}
static assert(isSectionGroup!(SectionGroup));
static assert(is(typeof(&initSections) == void function()));
static assert(is(typeof(&finiSections) == void function()));
Loading

0 comments on commit 0e10e7e

Please sign in to comment.