public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2020-12-09 9:50 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2020-12-09 9:50 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:f796c9539cca35b7445bea4ef131a64288cda6cc
commit f796c9539cca35b7445bea4ef131a64288cda6cc
Author: Iain Buclaw <ibuclaw@gdcproject.org>
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
+// <http://www.gnu.org/licenses/>.
+
+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 @@
# <http://www.gnu.org/licenses/>.
# 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 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-09-17 14:33 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-09-17 14:33 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0f2f68c1be64b0b5fa2e26345effe8337a94c17c
commit 0f2f68c1be64b0b5fa2e26345effe8337a94c17c
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/testsuite/lib/libphobos.exp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libphobos/testsuite/lib/libphobos.exp b/libphobos/testsuite/lib/libphobos.exp
index 3be2092b12e..ad323d761b9 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
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-04-19 18:05 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-04-19 18:05 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:69e0e9381323209a3dbda01527a90e71786ed31c
commit 69e0e9381323209a3dbda01527a90e71786ed31c
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/testsuite/lib/libphobos.exp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libphobos/testsuite/lib/libphobos.exp b/libphobos/testsuite/lib/libphobos.exp
index 3be2092b12e..ad323d761b9 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
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-04-10 17:00 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-04-10 17:00 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:c4a997f78b409eed36eb6ca476b5c3ceaefacf21
commit c4a997f78b409eed36eb6ca476b5c3ceaefacf21
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 22 ++++++++++++++++++----
libphobos/libdruntime/config/x86/switchcontext.S | 8 ++++++++
libphobos/libdruntime/gcc/deh.d | 5 -----
libphobos/libdruntime/gcc/sections/common.d | 2 +-
libphobos/m4/druntime/os.m4 | 22 ++++++++++++++++++----
libphobos/testsuite/lib/libphobos.exp | 4 ++++
6 files changed, 49 insertions(+), 14 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index fe7cd9c11ff..bbdcb409562 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14422,6 +14422,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'
@@ -14430,17 +14432,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/config/x86/switchcontext.S b/libphobos/libdruntime/config/x86/switchcontext.S
index 82420c6159c..8af3f5488ba 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 2e679320c38..8df5ac63d81 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/common.d b/libphobos/libdruntime/gcc/sections/common.d
index 85fdc0efd48..411f58ac548 100644
--- a/libphobos/libdruntime/gcc/sections/common.d
+++ b/libphobos/libdruntime/gcc/sections/common.d
@@ -1,5 +1,5 @@
// Contains various utility functions used by the runtime implementation.
-// Copyright (C) 2019-2021 Free Software Foundation, Inc.
+// Copyright (C) 2021 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
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 3be2092b12e..ad323d761b9 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
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-04-10 15:04 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-04-10 15:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:fb65d306947685b2492f7ba6622936575d638842
commit fb65d306947685b2492f7ba6622936575d638842
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 22 ++++++++++++++++++----
libphobos/libdruntime/config/x86/switchcontext.S | 8 ++++++++
libphobos/libdruntime/gcc/deh.d | 5 -----
libphobos/libdruntime/gcc/sections/common.d | 2 +-
libphobos/m4/druntime/os.m4 | 22 ++++++++++++++++++----
libphobos/testsuite/lib/libphobos.exp | 4 ++++
6 files changed, 49 insertions(+), 14 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index fe7cd9c11ff..bbdcb409562 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14422,6 +14422,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'
@@ -14430,17 +14432,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/config/x86/switchcontext.S b/libphobos/libdruntime/config/x86/switchcontext.S
index 82420c6159c..8af3f5488ba 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 2e679320c38..8df5ac63d81 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/common.d b/libphobos/libdruntime/gcc/sections/common.d
index 85fdc0efd48..411f58ac548 100644
--- a/libphobos/libdruntime/gcc/sections/common.d
+++ b/libphobos/libdruntime/gcc/sections/common.d
@@ -1,5 +1,5 @@
// Contains various utility functions used by the runtime implementation.
-// Copyright (C) 2019-2021 Free Software Foundation, Inc.
+// Copyright (C) 2021 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
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 3be2092b12e..ad323d761b9 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
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-03-14 22:00 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-03-14 22:00 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:266258f38e3ac2af31c739e195239e91deaa9a84
commit 266258f38e3ac2af31c739e195239e91deaa9a84
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 22 +-
libphobos/libdruntime/Makefile.am | 16 +-
libphobos/libdruntime/Makefile.in | 24 +-
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, 262 insertions(+), 196 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..5c243430ec1 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14373,6 +14373,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'
@@ -14381,17 +14383,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 945271e028f..c332d1787df 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -186,14 +186,14 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/gcinterface.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 \
+ gcc/sections/android.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/util/array.d rt/util/container/array.d \
rt/util/container/common.d rt/util/container/hashtab.d \
rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 06c02961c86..23c161f96d0 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -211,9 +211,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 \
@@ -812,14 +813,14 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/gcinterface.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 \
+ gcc/sections/android.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/util/array.d rt/util/container/array.d \
rt/util/container/common.d rt/util/container/hashtab.d \
rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
@@ -1210,6 +1211,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 82420c6159c..8af3f5488ba 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 c747b5132d1..7b44f2288dc 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 4af26b42ffc..56dff4ec861 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
+// <http://www.gnu.org/licenses/>.
+
+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 5b0fad9543b..d73708dc6d3 100644
--- a/libphobos/libdruntime/gcc/sections/elf_shared.d
+++ b/libphobos/libdruntime/gcc/sections/elf_shared.d
@@ -134,11 +134,6 @@ struct DSO
return _moduleGroup;
}
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- return null;
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
@@ -403,12 +398,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 3e3db70e4b8..2f807bb98e0 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 357940ba821..512693c071d 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 3be2092b12e..ad323d761b9 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 2f3a36f73cf..df01fcc8a23 100644
--- a/libphobos/testsuite/libphobos.druntime/druntime.exp
+++ b/libphobos/testsuite/libphobos.druntime/druntime.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# 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 0975ab1f801..770e5769e3c 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-03-07 17:01 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-03-07 17:01 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0ddfb769aaf3ac23950f43950da6739f290b65cd
commit 0ddfb769aaf3ac23950f43950da6739f290b65cd
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 22 +-
libphobos/libdruntime/Makefile.am | 16 +-
libphobos/libdruntime/Makefile.in | 24 +-
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, 262 insertions(+), 196 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..5c243430ec1 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14373,6 +14373,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'
@@ -14381,17 +14383,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 945271e028f..c332d1787df 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -186,14 +186,14 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/gcinterface.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 \
+ gcc/sections/android.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/util/array.d rt/util/container/array.d \
rt/util/container/common.d rt/util/container/hashtab.d \
rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 06c02961c86..23c161f96d0 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -211,9 +211,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 \
@@ -812,14 +813,14 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/gcinterface.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 \
+ gcc/sections/android.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/util/array.d rt/util/container/array.d \
rt/util/container/common.d rt/util/container/hashtab.d \
rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
@@ -1210,6 +1211,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 82420c6159c..8af3f5488ba 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 c747b5132d1..7b44f2288dc 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 4af26b42ffc..56dff4ec861 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
+// <http://www.gnu.org/licenses/>.
+
+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 5b0fad9543b..d73708dc6d3 100644
--- a/libphobos/libdruntime/gcc/sections/elf_shared.d
+++ b/libphobos/libdruntime/gcc/sections/elf_shared.d
@@ -134,11 +134,6 @@ struct DSO
return _moduleGroup;
}
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- return null;
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
@@ -403,12 +398,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 3e3db70e4b8..2f807bb98e0 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 357940ba821..512693c071d 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 3be2092b12e..ad323d761b9 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 2f3a36f73cf..df01fcc8a23 100644
--- a/libphobos/testsuite/libphobos.druntime/druntime.exp
+++ b/libphobos/testsuite/libphobos.druntime/druntime.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# 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 0975ab1f801..770e5769e3c 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-01-30 19:08 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-01-30 19:08 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:3e7f1342edfaf64a0aecfa50b7fad999b0810d54
commit 3e7f1342edfaf64a0aecfa50b7fad999b0810d54
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 22 +-
libphobos/libdruntime/Makefile.am | 23 +-
libphobos/libdruntime/Makefile.in | 31 +--
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, 270 insertions(+), 202 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..5c243430ec1 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14373,6 +14373,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'
@@ -14381,17 +14383,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 57de872862b..6402f26b1b8 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -185,17 +185,18 @@ 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/util/array.d rt/util/container/array.d rt/util/container/common.d \
- rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
- rt/util/typeinfo.d rt/util/utf.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/util/array.d rt/util/container/array.d \
+ rt/util/container/common.d rt/util/container/hashtab.d \
+ rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
+ rt/util/utf.d
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index e1b0a851b67..c82a6e75060 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -210,9 +210,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 \
@@ -803,17 +804,18 @@ 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/util/array.d rt/util/container/array.d rt/util/container/common.d \
- rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
- rt/util/typeinfo.d rt/util/utf.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/util/array.d rt/util/container/array.d \
+ rt/util/container/common.d rt/util/container/hashtab.d \
+ rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
+ rt/util/utf.d
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d
@@ -1192,6 +1194,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 82420c6159c..8af3f5488ba 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 c747b5132d1..7b44f2288dc 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 4af26b42ffc..56dff4ec861 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
+// <http://www.gnu.org/licenses/>.
+
+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 5b0fad9543b..d73708dc6d3 100644
--- a/libphobos/libdruntime/gcc/sections/elf_shared.d
+++ b/libphobos/libdruntime/gcc/sections/elf_shared.d
@@ -134,11 +134,6 @@ struct DSO
return _moduleGroup;
}
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- return null;
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
@@ -403,12 +398,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 3e3db70e4b8..2f807bb98e0 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 357940ba821..512693c071d 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 3be2092b12e..ad323d761b9 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 2f3a36f73cf..df01fcc8a23 100644
--- a/libphobos/testsuite/libphobos.druntime/druntime.exp
+++ b/libphobos/testsuite/libphobos.druntime/druntime.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# 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 0975ab1f801..770e5769e3c 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-01-28 17:31 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-01-28 17:31 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:4864fdba0a990a9e8052b3111f23531e2958487f
commit 4864fdba0a990a9e8052b3111f23531e2958487f
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 22 +-
libphobos/libdruntime/Makefile.am | 23 +-
libphobos/libdruntime/Makefile.in | 31 +--
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, 270 insertions(+), 202 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..5c243430ec1 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14373,6 +14373,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'
@@ -14381,17 +14383,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 57de872862b..6402f26b1b8 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -185,17 +185,18 @@ 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/util/array.d rt/util/container/array.d rt/util/container/common.d \
- rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
- rt/util/typeinfo.d rt/util/utf.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/util/array.d rt/util/container/array.d \
+ rt/util/container/common.d rt/util/container/hashtab.d \
+ rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
+ rt/util/utf.d
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index e1b0a851b67..c82a6e75060 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -210,9 +210,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 \
@@ -803,17 +804,18 @@ 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/util/array.d rt/util/container/array.d rt/util/container/common.d \
- rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
- rt/util/typeinfo.d rt/util/utf.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/util/array.d rt/util/container/array.d \
+ rt/util/container/common.d rt/util/container/hashtab.d \
+ rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \
+ rt/util/utf.d
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d
@@ -1192,6 +1194,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 82420c6159c..8af3f5488ba 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 c747b5132d1..7b44f2288dc 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 4af26b42ffc..56dff4ec861 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
+// <http://www.gnu.org/licenses/>.
+
+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 5b0fad9543b..d73708dc6d3 100644
--- a/libphobos/libdruntime/gcc/sections/elf_shared.d
+++ b/libphobos/libdruntime/gcc/sections/elf_shared.d
@@ -134,11 +134,6 @@ struct DSO
return _moduleGroup;
}
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- return null;
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
@@ -403,12 +398,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 3e3db70e4b8..2f807bb98e0 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 357940ba821..512693c071d 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 3be2092b12e..ad323d761b9 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 2f3a36f73cf..df01fcc8a23 100644
--- a/libphobos/testsuite/libphobos.druntime/druntime.exp
+++ b/libphobos/testsuite/libphobos.druntime/druntime.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# 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 0975ab1f801..770e5769e3c 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2021-01-11 11:39 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2021-01-11 11:39 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:3f44ca25722ed778aad91204b1b10a3ae0706119
commit 3f44ca25722ed778aad91204b1b10a3ae0706119
Author: Iain Buclaw <ibuclaw@gdcproject.org>
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 1c32a552d40..476303dec04 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14373,6 +14373,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'
@@ -14381,17 +14383,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 34d3b41df82..81774d92528 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 82420c6159c..8af3f5488ba 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 c747b5132d1..7b44f2288dc 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 4af26b42ffc..56dff4ec861 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
+// <http://www.gnu.org/licenses/>.
+
+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 9050413b261..9643d36d337 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 3e3db70e4b8..2f807bb98e0 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 357940ba821..512693c071d 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 3be2092b12e..ad323d761b9 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 2f3a36f73cf..df01fcc8a23 100644
--- a/libphobos/testsuite/libphobos.druntime/druntime.exp
+++ b/libphobos/testsuite/libphobos.druntime/druntime.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# 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 46dea2bfad0..3c63a42c642 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2020-12-22 13:40 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2020-12-22 13:40 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:ffd300cc0a8f5b31c0d41eb74dbc26a377d522fd
commit ffd300cc0a8f5b31c0d41eb74dbc26a377d522fd
Author: Iain Buclaw <ibuclaw@gdcproject.org>
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
+// <http://www.gnu.org/licenses/>.
+
+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 @@
# <http://www.gnu.org/licenses/>.
# 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 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2020-12-05 23:47 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:47 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:64d5fb2102128e39c50e6b80ba20aa3b3513e990
commit 64d5fb2102128e39c50e6b80ba20aa3b3513e990
Author: Iain Buclaw <ibuclaw@gdcproject.org>
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
+// <http://www.gnu.org/licenses/>.
+
+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 @@
# <http://www.gnu.org/licenses/>.
# 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 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2020-12-03 22:57 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2020-12-03 22:57 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:c2e08f8a620525ceb38a64ef3bc62e33686fc0ef
commit c2e08f8a620525ceb38a64ef3bc62e33686fc0ef
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 30 ++-
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, 280 insertions(+), 214 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index 77a3125cbd6..e86e129fd72 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -10038,7 +10038,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10050,7 +10050,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13485,7 +13485,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_D='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_D='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_D='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13497,7 +13497,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds_D='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_D='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_D='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -14381,6 +14381,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'
@@ -14389,17 +14391,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
+// <http://www.gnu.org/licenses/>.
+
+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 @@
# <http://www.gnu.org/licenses/>.
# 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 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2020-11-30 14:38 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2020-11-30 14:38 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:53e719ddf791ff35d243df556ae3162404cf95c0
commit 53e719ddf791ff35d243df556ae3162404cf95c0
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
libphobos/configure | 30 ++-
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, 280 insertions(+), 214 deletions(-)
diff --git a/libphobos/configure b/libphobos/configure
index 77a3125cbd6..e86e129fd72 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -10038,7 +10038,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10050,7 +10050,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13485,7 +13485,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_D='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_D='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_D='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13497,7 +13497,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds_D='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_D='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_D='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -14381,6 +14381,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'
@@ -14389,17 +14391,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
+// <http://www.gnu.org/licenses/>.
+
+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 @@
# <http://www.gnu.org/licenses/>.
# 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 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support
@ 2020-11-29 13:45 Iain Buclaw
0 siblings, 0 replies; 15+ messages in thread
From: Iain Buclaw @ 2020-11-29 13:45 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9eec2ee9893b784d419926147ccdbfcd36bcbb07
commit 9eec2ee9893b784d419926147ccdbfcd36bcbb07
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Nov 29 14:44:28 2020 +0100
libphobos: Checkpoint in darwin runtime support
Diff:
---
gcc/d/modules.cc | 1 +
libphobos/configure | 22 +-
libphobos/libdruntime/Makefile.in | 1 +
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, 243 insertions(+), 177 deletions(-)
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 742a24ff0bb..4e3fda53e7e 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -173,6 +173,7 @@ build_internal_fn (tree ident, tree expr)
TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
+ DECL_WEAK (decl) = 0;
return decl;
}
diff --git a/libphobos/configure b/libphobos/configure
index 77a3125cbd6..fb624b6f8e5 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14381,6 +14381,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'
@@ -14389,17 +14391,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.in b/libphobos/libdruntime/Makefile.in
index 99ee8b92afa..b14b3c159cf 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -1195,6 +1195,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
+// <http://www.gnu.org/licenses/>.
+
+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..7f90374dbd5 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 @@
# <http://www.gnu.org/licenses/>.
# 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 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2021-09-17 14:33 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-09 9:50 [gcc(refs/users/ibuclaw/heads/darwin)] libphobos: Checkpoint in darwin runtime support Iain Buclaw
-- strict thread matches above, loose matches on Subject: below --
2021-09-17 14:33 Iain Buclaw
2021-04-19 18:05 Iain Buclaw
2021-04-10 17:00 Iain Buclaw
2021-04-10 15:04 Iain Buclaw
2021-03-14 22:00 Iain Buclaw
2021-03-07 17:01 Iain Buclaw
2021-01-30 19:08 Iain Buclaw
2021-01-28 17:31 Iain Buclaw
2021-01-11 11:39 Iain Buclaw
2020-12-22 13:40 Iain Buclaw
2020-12-05 23:47 Iain Buclaw
2020-12-03 22:57 Iain Buclaw
2020-11-30 14:38 Iain Buclaw
2020-11-29 13:45 Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).