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

Commit

Permalink
Merge pull request #590 from dawgfoto/autoInit
Browse files Browse the repository at this point in the history
perform runtime and module initialization when loading DSOs
  • Loading branch information
WalterBright committed Sep 1, 2013
2 parents fa39a32 + 68eee29 commit 99496ed
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 10 deletions.
15 changes: 13 additions & 2 deletions src/rt/dmain2.d
Expand Up @@ -548,7 +548,15 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
// the user's main function. If main terminates with an exception,
// the exception is handled and then cleanup begins. An exception
// thrown during cleanup, however, will abort the cleanup process.
void runAll()
void runMain()
{
if (runModuleUnitTests())
tryExec({ result = mainFunc(args); });
else
result = EXIT_FAILURE;
}

void runMainWithInit()
{
if (rt_init() && runModuleUnitTests())
tryExec({ result = mainFunc(args); });
Expand All @@ -559,7 +567,10 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
result = (result == EXIT_SUCCESS) ? EXIT_FAILURE : result;
}

tryExec(&runAll);
version (linux) // initialization is done in rt.sections_linux
tryExec(&runMain);
else
tryExec(&runMainWithInit);

// Issue 10344: flush stdout and return nonzero on failure
if (.fflush(.stdout) != 0)
Expand Down
77 changes: 69 additions & 8 deletions src/rt/sections_linux.d
Expand Up @@ -13,13 +13,15 @@ module rt.sections_linux;
version (linux):

// debug = PRINTF;
import core.memory;
import core.stdc.stdio;
import core.stdc.stdlib : calloc, malloc, free;
import core.stdc.stdlib : calloc, exit, free, malloc, EXIT_FAILURE;
import core.stdc.string : strlen;
import core.sys.linux.elf;
import core.sys.linux.link;
import rt.minfo;
import rt.deh;
import rt.dmain2;
import rt.util.container;

alias DSO SectionGroup;
Expand Down Expand Up @@ -100,9 +102,6 @@ void finiSections()
*/
Array!(void[])* initTLSRanges()
{
_tlsRanges.length = _static_dsos.length;
foreach (i, ref dso; _static_dsos)
_tlsRanges[i] = getTLSRange(dso._tlsMod, dso._tlsSize);
return &_tlsRanges;
}

Expand Down Expand Up @@ -174,22 +173,84 @@ extern(C) void _d_dso_registry(CompilerDSOData* data)

checkModuleCollisions(info, pdso._moduleGroup.modules);

// initialize the runtime when loading the first DSO
if (_static_dsos.empty) initRuntime();

_static_dsos.insertBack(pdso);
_tlsRanges.insertBack(getTLSRange(pdso._tlsMod, pdso._tlsSize));
registerGCRanges(pdso);
runModuleConstructors(pdso);
}
// has backlink => unregister
else
{
DSO* pdso = cast(DSO*)*data._slot;
assert(pdso == _static_dsos.back); // DSOs are unloaded in reverse order
*data._slot = null;

runModuleDestructors(pdso);
unregisterGCRanges(pdso);
assert(pdso._tlsSize == _tlsRanges.back.length);
_tlsRanges.popBack();
assert(pdso == _static_dsos.back); // static DSOs are unloaded in reverse order
_static_dsos.popBack();

*data._slot = null;
freeDSO(pdso);

pdso._gcRanges.reset();
.free(pdso);
// terminate the runtime when unloading the last DSO
if (_static_dsos.empty) termRuntime();
}
}

///////////////////////////////////////////////////////////////////////////////
// helper functions
///////////////////////////////////////////////////////////////////////////////

void initRuntime()
{
if (!rt_init())
{
rt_term();
exit(EXIT_FAILURE);
}
}

void termRuntime()
{
if (!rt_term())
exit(EXIT_FAILURE);
}

void runModuleConstructors(DSO* pdso)
{
pdso._moduleGroup.sortCtors();
pdso._moduleGroup.runCtors();
pdso._moduleGroup.runTlsCtors();
}

void runModuleDestructors(DSO* pdso)
{
pdso._moduleGroup.runTlsDtors();
pdso._moduleGroup.runDtors();
}

void registerGCRanges(DSO* pdso)
{
foreach (rng; pdso._gcRanges)
GC.addRange(rng.ptr, rng.length);
}

void unregisterGCRanges(DSO* pdso)
{
foreach (rng; pdso._gcRanges)
GC.removeRange(rng.ptr);
}

void freeDSO(DSO* pdso)
{
pdso._gcRanges.reset();
.free(pdso);
}

///////////////////////////////////////////////////////////////////////////////
// Elf program header iteration
///////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 99496ed

Please sign in to comment.