From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 7FF723833002; Tue, 22 Dec 2020 13:40:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7FF723833002 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/users/ibuclaw/heads/darwin X-Git-Oldrev: a0f42eb291e98e74eefa9a204492af943427fe76 X-Git-Newrev: ffd300cc0a8f5b31c0d41eb74dbc26a377d522fd Message-Id: <20201222134027.7FF723833002@sourceware.org> Date: Tue, 22 Dec 2020 13:40:27 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Dec 2020 13:40:27 -0000 https://gcc.gnu.org/g:ffd300cc0a8f5b31c0d41eb74dbc26a377d522fd commit ffd300cc0a8f5b31c0d41eb74dbc26a377d522fd Author: Iain Buclaw Date: Sun Nov 29 14:44:28 2020 +0100 libphobos: Checkpoint in darwin runtime support Diff: --- libphobos/configure | 22 +- libphobos/libdruntime/Makefile.am | 30 +-- libphobos/libdruntime/Makefile.in | 38 +-- libphobos/libdruntime/config/x86/switchcontext.S | 8 + libphobos/libdruntime/gcc/deh.d | 5 - libphobos/libdruntime/gcc/sections/android.d | 7 - libphobos/libdruntime/gcc/sections/common.d | 48 ++++ libphobos/libdruntime/gcc/sections/elf_shared.d | 11 - libphobos/libdruntime/gcc/sections/osx.d | 279 +++++++++++---------- libphobos/libdruntime/gcc/sections/win64.d | 8 - libphobos/m4/druntime/os.m4 | 22 +- libphobos/testsuite/lib/libphobos.exp | 4 + .../testsuite/libphobos.druntime/druntime.exp | 2 +- libphobos/testsuite/libphobos.phobos/phobos.exp | 2 +- 14 files changed, 276 insertions(+), 210 deletions(-) diff --git a/libphobos/configure b/libphobos/configure index a7fb5edb90f..0ec729c9d96 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -14383,6 +14383,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -14391,17 +14393,29 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for minfo section bracketing" >&5 $as_echo_n "checking for minfo section bracketing... " >&6; } + case "$druntime_cv_target_os" in + darwin*) + section="__DATA,__minfodata" + start="section\$start\$__DATA\$__minfodata" + stop="section\$end\$__DATA\$__minfodata" + ;; + *) + section="minfo" + start="__start_minfo" + stop="__stop_minfo" + ;; + esac cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - void* module_info_ptr __attribute__((section ("minfo"))); - extern void* __start_minfo __attribute__((visibility ("hidden"))); - extern void* __stop_minfo __attribute__((visibility ("hidden"))); + void* module_info_ptr __attribute__((section ("$section"))); + extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden"))); + extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden"))); int main() { // Never run, just to prevent compiler from optimizing access - return &__start_minfo == &__stop_minfo; + return (int)(&stop_minfo - &start_minfo); } _ACEOF diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 4798bdf777d..1ebc97af39d 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -183,21 +183,21 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d gc/pooltable.d \ gc/proxy.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \ gcc/emutls.d gcc/gthread.d gcc/sections/android.d \ - gcc/sections/elf_shared.d gcc/sections/osx.d gcc/sections/package.d \ - gcc/sections/win32.d gcc/sections/win64.d gcc/unwind/arm.d \ - gcc/unwind/arm_common.d gcc/unwind/c6x.d gcc/unwind/generic.d \ - gcc/unwind/package.d gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d \ - rt/aaA.d rt/adi.d rt/arrayassign.d rt/arraycast.d rt/arraycat.d \ - rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \ - rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \ - rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \ - rt/typeinfo/ti_Acdouble.d rt/typeinfo/ti_Acfloat.d \ - rt/typeinfo/ti_Acreal.d rt/typeinfo/ti_Adouble.d \ - rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d rt/typeinfo/ti_Aint.d \ - rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d rt/typeinfo/ti_Ashort.d \ - rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d rt/typeinfo/ti_cdouble.d \ - rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d rt/typeinfo/ti_char.d \ - rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \ + gcc/sections/common.d gcc/sections/elf_shared.d gcc/sections/osx.d \ + gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \ + gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \ + gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \ + rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \ + rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \ + rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \ + rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \ + rt/switch_.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \ + rt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \ + rt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \ + rt/typeinfo/ti_Aint.d rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d \ + rt/typeinfo/ti_Ashort.d rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d \ + rt/typeinfo/ti_cdouble.d rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d \ + rt/typeinfo/ti_char.d rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \ rt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \ rt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \ rt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 99ee8b92afa..3bf08f52b31 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -207,9 +207,10 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \ gc/pooltable.lo gc/proxy.lo gcc/attribute.lo gcc/backtrace.lo \ gcc/builtins.lo gcc/deh.lo gcc/emutls.lo gcc/gthread.lo \ - gcc/sections/android.lo gcc/sections/elf_shared.lo \ - gcc/sections/osx.lo gcc/sections/package.lo \ - gcc/sections/win32.lo gcc/sections/win64.lo gcc/unwind/arm.lo \ + gcc/sections/android.lo gcc/sections/common.lo \ + gcc/sections/elf_shared.lo gcc/sections/osx.lo \ + gcc/sections/package.lo gcc/sections/win32.lo \ + gcc/sections/win64.lo gcc/unwind/arm.lo \ gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \ gcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \ object.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \ @@ -808,21 +809,21 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d gc/pooltable.d \ gc/proxy.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \ gcc/emutls.d gcc/gthread.d gcc/sections/android.d \ - gcc/sections/elf_shared.d gcc/sections/osx.d gcc/sections/package.d \ - gcc/sections/win32.d gcc/sections/win64.d gcc/unwind/arm.d \ - gcc/unwind/arm_common.d gcc/unwind/c6x.d gcc/unwind/generic.d \ - gcc/unwind/package.d gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d \ - rt/aaA.d rt/adi.d rt/arrayassign.d rt/arraycast.d rt/arraycat.d \ - rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \ - rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \ - rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \ - rt/typeinfo/ti_Acdouble.d rt/typeinfo/ti_Acfloat.d \ - rt/typeinfo/ti_Acreal.d rt/typeinfo/ti_Adouble.d \ - rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d rt/typeinfo/ti_Aint.d \ - rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d rt/typeinfo/ti_Ashort.d \ - rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d rt/typeinfo/ti_cdouble.d \ - rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d rt/typeinfo/ti_char.d \ - rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \ + gcc/sections/common.d gcc/sections/elf_shared.d gcc/sections/osx.d \ + gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \ + gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \ + gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \ + rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \ + rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \ + rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \ + rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \ + rt/switch_.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \ + rt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \ + rt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \ + rt/typeinfo/ti_Aint.d rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d \ + rt/typeinfo/ti_Ashort.d rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d \ + rt/typeinfo/ti_cdouble.d rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d \ + rt/typeinfo/ti_char.d rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \ rt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \ rt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \ rt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \ @@ -1195,6 +1196,7 @@ gcc/sections/$(am__dirstamp): @$(MKDIR_P) gcc/sections @: > gcc/sections/$(am__dirstamp) gcc/sections/android.lo: gcc/sections/$(am__dirstamp) +gcc/sections/common.lo: gcc/sections/$(am__dirstamp) gcc/sections/elf_shared.lo: gcc/sections/$(am__dirstamp) gcc/sections/osx.lo: gcc/sections/$(am__dirstamp) gcc/sections/package.lo: gcc/sections/$(am__dirstamp) diff --git a/libphobos/libdruntime/config/x86/switchcontext.S b/libphobos/libdruntime/config/x86/switchcontext.S index f2f8efa218e..66c81f8b37a 100644 --- a/libphobos/libdruntime/config/x86/switchcontext.S +++ b/libphobos/libdruntime/config/x86/switchcontext.S @@ -33,7 +33,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see .text .globl CSYM(fiber_switchContext) +#if defined(__ELF__) .type CSYM(fiber_switchContext), @function +#endif .align 16 CSYM(fiber_switchContext): .cfi_startproc @@ -61,13 +63,17 @@ CSYM(fiber_switchContext): // 'return' to complete switch ret .cfi_endproc +#if defined(__ELF__) .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) +#endif #elif defined(__x86_64__) && !defined(__ILP32__) && !defined(__CET__) .text .globl CSYM(fiber_switchContext) +#if defined(__ELF__) .type CSYM(fiber_switchContext), @function +#endif .align 16 CSYM(fiber_switchContext): .cfi_startproc @@ -96,6 +102,8 @@ CSYM(fiber_switchContext): // 'return' to complete switch ret .cfi_endproc +#if defined(__ELF__) .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) +#endif #endif diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index 3e78a6c9c0e..bb2035f5155 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -34,11 +34,6 @@ extern(C) { int _d_isbaseof(ClassInfo, ClassInfo); void _d_createTrace(Object, void*); - - // Not used in GDC but declaration required by rt/sections.d - struct FuncTable - { - } } /** diff --git a/libphobos/libdruntime/gcc/sections/android.d b/libphobos/libdruntime/gcc/sections/android.d index 2180a0b2514..51f5d24c2cb 100644 --- a/libphobos/libdruntime/gcc/sections/android.d +++ b/libphobos/libdruntime/gcc/sections/android.d @@ -54,13 +54,6 @@ struct SectionGroup return _moduleGroup; } - @property immutable(FuncTable)[] ehTables() const nothrow @nogc - { - auto pbeg = cast(immutable(FuncTable)*)&__start_deh; - auto pend = cast(immutable(FuncTable)*)&__stop_deh; - return pbeg[0 .. pend - pbeg]; - } - @property inout(void[])[] gcRanges() inout nothrow @nogc { return _gcRanges[]; diff --git a/libphobos/libdruntime/gcc/sections/common.d b/libphobos/libdruntime/gcc/sections/common.d new file mode 100644 index 00000000000..b2d2322347d --- /dev/null +++ b/libphobos/libdruntime/gcc/sections/common.d @@ -0,0 +1,48 @@ +// Common support routines for retrieving platform-specific sections. +// Copyright (C) 2019 Free Software Foundation, Inc. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +module gcc.sections.common; + +/**** + * Asserts the specified condition, independent from -release, by abort()ing. + * Regular assertions throw an AssertError and thus require an initialized + * GC, which isn't the case (yet or anymore) for the startup/shutdown code in + * this module (called by CRT ctors/dtors etc.). + */ +void safeAssert(bool condition, scope string msg, size_t line = __LINE__) @nogc nothrow @safe +{ + import core.internal.abort; + condition || abort(msg, __FILE__, line); +} + +/**** + * This data structure is generated by the compiler, and then passed to + * _d_dso_registry(). + */ +struct CompilerDSOData +{ + size_t _version; // currently 1 + void** _slot; // can be used to store runtime data + immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file +} + +T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; } diff --git a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d index 59e2dd60a1f..3fb1b491f88 100644 --- a/libphobos/libdruntime/gcc/sections/elf_shared.d +++ b/libphobos/libdruntime/gcc/sections/elf_shared.d @@ -132,11 +132,6 @@ struct DSO return _moduleGroup; } - @property immutable(FuncTable)[] ehTables() const nothrow @nogc - { - return null; - } - @property inout(void[])[] gcRanges() inout nothrow @nogc { return _gcRanges[]; @@ -383,12 +378,6 @@ version (Shared) */ __gshared pthread_mutex_t _handleToDSOMutex; @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow { __gshared HashTab!(void*, DSO*) x; return x; } - - /* - * Section in executable that contains copy relocations. - * Might be null when druntime is dynamically loaded by a C host. - */ - __gshared const(void)[] _copyRelocSection; } else { diff --git a/libphobos/libdruntime/gcc/sections/osx.d b/libphobos/libdruntime/gcc/sections/osx.d index cb02b452404..6ace2da4a8b 100644 --- a/libphobos/libdruntime/gcc/sections/osx.d +++ b/libphobos/libdruntime/gcc/sections/osx.d @@ -24,25 +24,38 @@ module gcc.sections.osx; version (OSX): -// debug = PRINTF; -import core.stdc.stdio; -import core.stdc.string, core.stdc.stdlib; -import core.sys.posix.pthread; +import gcc.sections.common; + +import core.stdc.stdlib; import core.sys.darwin.mach.dyld; import core.sys.darwin.mach.getsect; -import rt.deh, rt.minfo; +import rt.minfo; import rt.util.container.array; -struct SectionGroup +version (GNU_EMUTLS) + import gcc.emutls; + +alias DSO SectionGroup; +struct DSO { - static int opApply(scope int delegate(ref SectionGroup) dg) + static int opApply(scope int delegate(ref DSO) dg) { - return dg(_sections); + foreach (dso; _loadedDSOs) + { + if (auto res = dg(*dso)) + return res; + } + return 0; } - static int opApplyReverse(scope int delegate(ref SectionGroup) dg) + static int opApplyReverse(scope int delegate(ref DSO) dg) { - return dg(_sections); + foreach_reverse (dso; _loadedDSOs) + { + if (auto res = dg(*dso)) + return res; + } + return 0; } @property immutable(ModuleInfo*)[] modules() const nothrow @nogc @@ -60,16 +73,9 @@ struct SectionGroup return _gcRanges[]; } - @property immutable(FuncTable)[] ehTables() const nothrow @nogc - { - return _ehTables[]; - } - private: - immutable(FuncTable)[] _ehTables; ModuleGroup _moduleGroup; Array!(void[]) _gcRanges; - immutable(void)[][2] _tlsImage; } /**** @@ -82,8 +88,6 @@ __gshared bool _isRuntimeInitialized; */ void initSections() nothrow @nogc { - pthread_key_create(&_tlsKey, null); - _dyld_register_func_for_add_image(§ions_osx_onAddImage); _isRuntimeInitialized = true; } @@ -92,160 +96,161 @@ void initSections() nothrow @nogc */ void finiSections() nothrow @nogc { - _sections._gcRanges.reset(); - pthread_key_delete(_tlsKey); _isRuntimeInitialized = false; } void[]* initTLSRanges() nothrow @nogc { - return &getTLSBlock(); + return null; } void finiTLSRanges(void[]* rng) nothrow @nogc { - .free(rng.ptr); - .free(rng); } void scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow { - dg(rng.ptr, rng.ptr + rng.length); + version (GNU_EMUTLS) + _d_emutls_scan(dg); + else + static assert(0, "Native TLS unimplemented"); } -// NOTE: The Mach-O object file format does not allow for thread local -// storage declarations. So instead we roll our own by putting tls -// into the __tls_data and the __tlscoal_nt sections. -// -// This function is called by the code emitted by the compiler. It -// is expected to translate an address into the TLS static data to -// the corresponding address in the TLS dynamic per-thread data. - -// NB: the compiler mangles this function as '___tls_get_addr' even though it is extern(D) -extern(D) void* ___tls_get_addr( void* p ) +version (Shared) { - immutable off = tlsOffset(p); - auto tls = getTLSBlockAlloc(); - assert(off < tls.length); - return tls.ptr + off; -} - -private: + // interface for core.thread to inherit loaded libraries + void* pinLoadedLibraries() nothrow @nogc + { + return null; + } -__gshared pthread_key_t _tlsKey; + void unpinLoadedLibraries(void* p) nothrow @nogc + { + } -size_t tlsOffset(void* p) -in -{ - assert(_sections._tlsImage[0].ptr !is null || - _sections._tlsImage[1].ptr !is null); -} -body -{ - // NOTE: p is an address in the TLS static data emitted by the - // compiler. If it isn't, something is disastrously wrong. - immutable off0 = cast(size_t)(p - _sections._tlsImage[0].ptr); - if (off0 < _sections._tlsImage[0].length) + // Called before TLS ctors are ran, copy over the loaded libraries + // of the parent thread. + void inheritLoadedLibraries(void* p) nothrow @nogc { - return off0; } - immutable off1 = cast(size_t)(p - _sections._tlsImage[1].ptr); - if (off1 < _sections._tlsImage[1].length) + + // Called after all TLS dtors ran, decrements all remaining dlopen refs. + void cleanupLoadedLibraries() nothrow @nogc { - size_t sz = (_sections._tlsImage[0].length + 15) & ~cast(size_t)15; - return sz + off1; } - assert(0); } -ref void[] getTLSBlock() nothrow @nogc +private: + +/* + * Static DSOs loaded by the runtime linker. This includes the + * executable. These can't be unloaded. + */ +@property ref Array!(DSO*) _loadedDSOs() @nogc nothrow { - auto pary = cast(void[]*)pthread_getspecific(_tlsKey); - if (pary is null) - { - pary = cast(void[]*).calloc(1, (void[]).sizeof); - if (pthread_setspecific(_tlsKey, pary) != 0) - { - import core.stdc.stdio; - perror("pthread_setspecific failed with"); - assert(0); - } - } - return *pary; + __gshared Array!(DSO*) x; + return x; } -ref void[] getTLSBlockAlloc() +/* + * Set to true during rt_loadLibrary/rt_unloadLibrary calls. + */ +enum _rtLoading = false; + +struct MachHeader { - auto pary = &getTLSBlock(); - if (!pary.length) - { - auto imgs = _sections._tlsImage; - immutable sz0 = (imgs[0].length + 15) & ~cast(size_t)15; - immutable sz2 = sz0 + imgs[1].length; - auto p = .malloc(sz2); - memcpy(p, imgs[0].ptr, imgs[0].length); - memcpy(p + sz0, imgs[1].ptr, imgs[1].length); - *pary = p[0 .. sz2]; - } - return *pary; + const(mach_header)* header; // the mach header of the image + intptr_t slide; // virtural memory address slide amount } -__gshared SectionGroup _sections; +/////////////////////////////////////////////////////////////////////////////// +// Compiler to runtime interface. +/////////////////////////////////////////////////////////////////////////////// -extern (C) void sections_osx_onAddImage(in mach_header* h, intptr_t slide) +/* For each shared library and executable, the compiler generates code that + * sets up CompilerDSOData and calls _d_dso_registry(). + * A pointer to that code is inserted into both the .ctors and .dtors + * segment so it gets called by the loader on startup and shutdown. + */ +extern(C) void _d_dso_registry(CompilerDSOData* data) { - foreach (e; dataSegs) - { - auto sect = getSection(h, slide, e.seg.ptr, e.sect.ptr); - if (sect != null) - _sections._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]); - } + // only one supported currently + safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version."); - auto minfosect = getSection(h, slide, "__DATA", "__minfodata"); - if (minfosect != null) + // no backlink => register + if (*data._slot is null) { - // no support for multiple images yet - // take the sections from the last static image which is the executable - if (_isRuntimeInitialized) - { - fprintf(stderr, "Loading shared libraries isn't yet supported on OSX.\n"); - return; - } - else if (_sections.modules.ptr !is null) + DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof); + assert(typeid(DSO).initializer().ptr is null); + *data._slot = pdso; // store backlink in library record + + pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end)); + + MachHeader info = void; + const headerFound = findDSOHeaderForAddr(data._slot, &info); + safeAssert(headerFound, "Failed to find image header."); + + foreach (e; dataSegs) { - fprintf(stderr, "Shared libraries are not yet supported on OSX.\n"); + auto sect = getSection(info.header, info.slide, + e.seg.ptr, e.sect.ptr); + if (sect != null) + pdso._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]); } - debug(PRINTF) printf(" minfodata\n"); - auto p = cast(immutable(ModuleInfo*)*)minfosect.ptr; - immutable len = minfosect.length / (*p).sizeof; - - _sections._moduleGroup = ModuleGroup(p[0 .. len]); + foreach (p; _loadedDSOs) + safeAssert(p !is pdso, "DSO already registered."); + _loadedDSOs.insertBack(pdso); } - - auto ehsect = getSection(h, slide, "__DATA", "__deh_eh"); - if (ehsect != null) + // has backlink => unregister + else { - debug(PRINTF) printf(" deh_eh\n"); - auto p = cast(immutable(FuncTable)*)ehsect.ptr; - immutable len = ehsect.length / (*p).sizeof; + DSO* pdso = cast(DSO*)*data._slot; + *data._slot = null; - _sections._ehTables = p[0 .. len]; - } + // static DSOs are unloaded in reverse order + safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one."); + _loadedDSOs.popBack(); - auto tlssect = getSection(h, slide, "__DATA", "__tls_data"); - if (tlssect != null) - { - debug(PRINTF) printf(" tls_data %p %p\n", tlssect.ptr, tlssect.ptr + tlssect.length); - _sections._tlsImage[0] = (cast(immutable(void)*)tlssect.ptr)[0 .. tlssect.length]; + pdso._gcRanges.reset(); + .free(pdso); + + // last DSO being unloaded => shutdown registry + if (_loadedDSOs.empty) + { + version (GNU_EMUTLS) + _d_emutls_destroy(); + } } +} + +/************************** + * Input: + * result where the output is to be written + * Returns: + * true if found, and *result is filled in + */ - auto tlssect2 = getSection(h, slide, "__DATA", "__tlscoal_nt"); - if (tlssect2 != null) +bool findDSOHeaderForAddr(in void* addr, MachHeader* result) +{ + foreach (i; 0 .. _dyld_image_count()) { - debug(PRINTF) printf(" tlscoal_nt %p %p\n", tlssect2.ptr, tlssect2.ptr + tlssect2.length); - _sections._tlsImage[1] = (cast(immutable(void)*)tlssect2.ptr)[0 .. tlssect2.length]; + const header = _dyld_get_image_header(i); + const slide = _dyld_get_image_vmaddr_slide(i); + const section = getSection(header, slide, SEG_DATA, SECT_DATA); + + // less than base address of section means quick reject + if (!section.length || addr < section.ptr) + continue; + + if (addr < section.ptr + section.length) + { + result.header = header; + result.slide = slide; + return true; + } } + return false; } struct SegRef @@ -258,25 +263,27 @@ static immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA}, {SEG_DATA, SECT_BSS}, {SEG_DATA, SECT_COMMON}]; +/** + * Returns the section for the named section in the named segment + * for the mach_header pointer passed, or null if not found. + */ ubyte[] getSection(in mach_header* header, intptr_t slide, in char* segmentName, in char* sectionName) { - version (X86) + version (D_LP64) { - assert(header.magic == MH_MAGIC); - auto sect = getsectbynamefromheader(header, + assert(header.magic == MH_MAGIC_64); + auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header, segmentName, sectionName); } - else version (X86_64) + else { - assert(header.magic == MH_MAGIC_64); - auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header, + assert(header.magic == MH_MAGIC); + auto sect = getsectbynamefromheader(header, segmentName, sectionName); } - else - static assert(0, "unimplemented"); if (sect !is null && sect.size > 0) return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size]; diff --git a/libphobos/libdruntime/gcc/sections/win64.d b/libphobos/libdruntime/gcc/sections/win64.d index 1a4ee989cec..8362a6ffa23 100644 --- a/libphobos/libdruntime/gcc/sections/win64.d +++ b/libphobos/libdruntime/gcc/sections/win64.d @@ -51,14 +51,6 @@ struct SectionGroup return _moduleGroup; } - version (Win64) - @property immutable(FuncTable)[] ehTables() const nothrow @nogc - { - auto pbeg = cast(immutable(FuncTable)*)&_deh_beg; - auto pend = cast(immutable(FuncTable)*)&_deh_end; - return pbeg[0 .. pend - pbeg]; - } - @property inout(void[])[] gcRanges() inout nothrow @nogc { return _gcRanges[]; diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4 index ed93e30f1e9..351558dbcda 100644 --- a/libphobos/m4/druntime/os.m4 +++ b/libphobos/m4/druntime/os.m4 @@ -149,17 +149,31 @@ AC_DEFUN([DRUNTIME_OS_ARM_EABI_UNWINDER], # substitute DCFG_MINFO_BRACKETING. AC_DEFUN([DRUNTIME_OS_MINFO_BRACKETING], [ + AC_REQUIRE([DRUNTIME_OS_DETECT]) + AC_LANG_PUSH([C]) AC_MSG_CHECKING([for minfo section bracketing]) + case "$druntime_cv_target_os" in + darwin*) + section="__DATA,__minfodata" + start="section\$start\$__DATA\$__minfodata" + stop="section\$end\$__DATA\$__minfodata" + ;; + *) + section="minfo" + start="__start_minfo" + stop="__stop_minfo" + ;; + esac AC_LINK_IFELSE([AC_LANG_SOURCE([ - void* module_info_ptr __attribute__((section ("minfo"))); - extern void* __start_minfo __attribute__((visibility ("hidden"))); - extern void* __stop_minfo __attribute__((visibility ("hidden"))); + void* module_info_ptr __attribute__((section ("$section"))); + extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden"))); + extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden"))); int main() { // Never run, just to prevent compiler from optimizing access - return &__start_minfo == &__stop_minfo; + return (int)(&stop_minfo - &start_minfo); } ])], [AC_MSG_RESULT([yes]) diff --git a/libphobos/testsuite/lib/libphobos.exp b/libphobos/testsuite/lib/libphobos.exp index 790480bf95c..3b43f0182a7 100644 --- a/libphobos/testsuite/lib/libphobos.exp +++ b/libphobos/testsuite/lib/libphobos.exp @@ -90,6 +90,10 @@ proc libphobos-dg-test { prog do_what extra_tool_flags } { } proc libphobos-dg-prune { system text } { + + # Ignore warnings from cctools. + regsub -all "(^|\n)clang: warning: argument unused during compilation:\[^\n\]*" $text "" text + return $text } diff --git a/libphobos/testsuite/libphobos.druntime/druntime.exp b/libphobos/testsuite/libphobos.druntime/druntime.exp index 7072ebb1c9f..a157329c916 100644 --- a/libphobos/testsuite/libphobos.druntime/druntime.exp +++ b/libphobos/testsuite/libphobos.druntime/druntime.exp @@ -15,7 +15,7 @@ # . # Immediately exit if we can't run target executables. -if { ![isnative] || ![is-effective-target static] } { +if { ![isnative] } { return } diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp index aad877c24c2..45c48ce7324 100644 --- a/libphobos/testsuite/libphobos.phobos/phobos.exp +++ b/libphobos/testsuite/libphobos.phobos/phobos.exp @@ -15,7 +15,7 @@ # . # Immediately exit if we can't run target executables. -if { ![isnative] || ![is-effective-target static] } { +if { ![isnative] } { return }