diff --git a/src/core/runtime.d b/src/core/runtime.d index b9b3573293..df4a9333f3 100644 --- a/src/core/runtime.d +++ b/src/core/runtime.d @@ -588,6 +588,8 @@ extern (C) UnitTestResult runModuleUnitTests() import core.sys.freebsd.execinfo; else version( NetBSD ) import core.sys.netbsd.execinfo; + else version( DragonFlyBSD ) + import core.sys.dragonflybsd.execinfo; else version( Windows ) import core.sys.windows.stacktrace; else version( Solaris ) @@ -705,6 +707,8 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) import core.sys.freebsd.execinfo; else version( NetBSD ) import core.sys.netbsd.execinfo; + else version( DragonFlyBSD ) + import core.sys.dragonflybsd.execinfo; else version( Windows ) import core.sys.windows.stacktrace; else version( Solaris ) @@ -791,6 +795,7 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) version(linux) enum enableDwarf = true; else version(FreeBSD) enum enableDwarf = true; + else version(DragonFlyBSD) enum enableDwarf = true; else enum enableDwarf = false; static if (enableDwarf) @@ -914,6 +919,18 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) symEnd = eptr - buf.ptr; } } + else version( DragonFlyBSD ) + { + // format is: 0x00000000 <_D6module4funcAFZv+0x78> at module + auto bptr = cast(char*) memchr( buf.ptr, '<', buf.length ); + auto eptr = cast(char*) memchr( buf.ptr, '+', buf.length ); + + if( bptr++ && eptr ) + { + symBeg = bptr - buf.ptr; + symEnd = eptr - buf.ptr; + } + } else version( Solaris ) { // format is object'symbol+offset [pc] diff --git a/src/core/stdc/assert_.d b/src/core/stdc/assert_.d index 6785a8094e..919cdce7cd 100644 --- a/src/core/stdc/assert_.d +++ b/src/core/stdc/assert_.d @@ -53,6 +53,13 @@ else version (FreeBSD) */ void __assert(const(char)* exp, const(char)* file, uint line); } +else version (DragonFlyBSD) +{ + /*** + * Assert failure function in the DragonFlyBSD C library. + */ + void __assert(const(char)* exp, const(char)* file, uint line); +} else version (CRuntime_Glibc) { /*** diff --git a/src/core/stdc/config.d b/src/core/stdc/config.d index de25b7bf62..c968575a1a 100644 --- a/src/core/stdc/config.d +++ b/src/core/stdc/config.d @@ -129,6 +129,8 @@ else version( DigitalMars ) alias real c_long_double; else version( NetBSD ) alias real c_long_double; + else version( DragonFlyBSD ) + alias real c_long_double; else version( Solaris ) alias real c_long_double; else version( Darwin ) diff --git a/src/core/stdc/errno.d b/src/core/stdc/errno.d index b33219d98a..7f12479060 100644 --- a/src/core/stdc/errno.d +++ b/src/core/stdc/errno.d @@ -67,6 +67,11 @@ else version (FreeBSD) alias errno = __error; } } +else version (DragonFlyBSD) +{ + pragma(mangle, "errno") extern int __errno; + ref int errno() { return __errno;} +} else version (CRuntime_Bionic) { extern (C) @@ -1830,6 +1835,109 @@ else version( OpenBSD ) enum ENOTSUP = 91; /// Not supported enum ELAST = 91; /// Must be equal largest errno } +else version( DragonFlyBSD ) +{ + enum EPERM = 1; + enum ENOENT = 2; + enum ESRCH = 3; + enum EINTR = 4; + enum EIO = 5; + enum ENXIO = 6; + enum E2BIG = 7; + enum ENOEXEC = 8; + enum EBADF = 9; + enum ECHILD = 10; + enum EDEADLK = 11; + enum ENOMEM = 12; + enum EACCES = 13; + enum EFAULT = 14; + enum ENOTBLK = 15; + enum EBUSY = 16; + enum EEXIST = 17; + enum EXDEV = 18; + enum ENODEV = 19; + enum ENOTDIR = 20; + enum EISDIR = 21; + enum EINVAL = 22; + enum ENFILE = 23; + enum EMFILE = 24; + enum ENOTTY = 25; + enum ETXTBSY = 26; + enum EFBIG = 27; + enum ENOSPC = 28; + enum ESPIPE = 29; + enum EROFS = 30; + enum EMLINK = 31; + enum EPIPE = 32; + enum EDOM = 33; + enum ERANGE = 34; + enum EAGAIN = 35; + enum EWOULDBLOCK = EAGAIN; + enum EINPROGRESS = 36; + enum EALREADY = 37; + enum ENOTSOCK = 38; + enum EDESTADDRREQ = 39; + enum EMSGSIZE = 40; + enum EPROTOTYPE = 41; + enum ENOPROTOOPT = 42; + enum EPROTONOSUPPORT = 43; + enum ENOTSUP = 45; + enum EOPNOTSUPP = ENOTSUP; + enum EPFNOSUPPORT = 46; + enum EAFNOSUPPORT = 47; + enum EADDRINUSE = 48; + enum EADDRNOTAVAIL = 49; + enum ENETDOWN = 50; + enum ENETUNREACH = 51; + enum ENETRESET = 52; + enum ECONNABORTED = 53; + enum ECONNRESET = 54; + enum ENOBUFS = 55; + enum EISCONN = 56; + enum ENOTCONN = 57; + enum ESHUTDOWN = 58; + enum ETOOMANYREFS = 59; + enum ETIMEDOUT = 60; + enum ECONNREFUSED = 61; + enum ELOOP = 62; + enum ENAMETOOLONG = 63; + enum EHOSTUNREACH = 65; + enum ENOTEMPTY = 66; + enum EPROCLIM = 67; + enum EUSERS = 68; + enum EDQUOT = 69; + enum ESTALE = 70; + enum EREMOTE = 71; + enum EBADRPC = 72; + enum ERPCMISMATCH = 73; + enum EPROGUNAVAIL = 74; + enum EPROGMISMATCH = 75; + enum EPROCUNAVAIL = 76; + enum ENOLCK = 77; + enum ENOSYS = 78; + enum EFTYPE = 79; + enum EAUTH = 80; + enum ENEEDAUTH = 81; + enum EIDRM = 82; + enum ENOMSG = 83; + enum EOVERFLOW = 84; + enum ECANCELED = 85; + enum EILSEQ = 86; + enum ENOATTR = 87; + enum EDOOFUS = 88; + enum EBADMSG = 89; + enum EMULTIHOP = 90; + enum ENOLINK = 91; + enum EPROTO = 92; + enum ENOMEDIUM = 93; + enum EUNUSED94 = 94; + enum EUNUSED95 = 95; + enum EUNUSED96 = 96; + enum EUNUSED97 = 97; + enum EUNUSED98 = 98; + enum EASYNC = 99; + enum ELAST = 99; +} else version (Solaris) { enum EPERM = 1 /** Not super-user */; diff --git a/src/core/stdc/fenv.d b/src/core/stdc/fenv.d index 94e1818f89..5118b12fce 100644 --- a/src/core/stdc/fenv.d +++ b/src/core/stdc/fenv.d @@ -263,6 +263,24 @@ else version ( OpenBSD ) alias fexcept_t = uint; } +else version ( DragonFlyBSD ) +{ + struct fenv_t + { + struct _x87 + { + uint control; + uint status; + uint tag; + uint[4] others; + }; + _x87 x87; + + uint mxcsr; + } + + alias uint fexcept_t; +} else version( CRuntime_Bionic ) { version(X86) @@ -649,6 +667,12 @@ else version( OpenBSD ) /// enum FE_DFL_ENV = &__fe_dfl_env; } +else version( DragonFlyBSD ) +{ + private extern const fenv_t __fe_dfl_env; + /// + enum FE_DFL_ENV = &__fe_dfl_env; +} else version( CRuntime_Bionic ) { private extern const fenv_t __fe_dfl_env; diff --git a/src/core/stdc/locale.d b/src/core/stdc/locale.d index c1bbd55c28..68823faf4f 100644 --- a/src/core/stdc/locale.d +++ b/src/core/stdc/locale.d @@ -169,6 +169,23 @@ else version(OpenBSD) /// enum LC_MESSAGES = 6; } +else version(DragonFlyBSD) +{ + /// + enum LC_ALL = 0; + /// + enum LC_COLLATE = 1; + /// + enum LC_CTYPE = 2; + /// + enum LC_MONETARY = 3; + /// + enum LC_NUMERIC = 4; + /// + enum LC_TIME = 5; + /// + enum LC_MESSAGES = 6; +} else version(CRuntime_Bionic) { enum diff --git a/src/core/stdc/math.d b/src/core/stdc/math.d index 7405b58919..80a8a82468 100644 --- a/src/core/stdc/math.d +++ b/src/core/stdc/math.d @@ -67,6 +67,13 @@ else version (OpenBSD) /// enum int FP_ILOGBNAN = int.max; } +else version (DragonFlyBSD) +{ + /// + enum int FP_ILOGB0 = -int.max; + /// + enum int FP_ILOGBNAN = int.max; +} else version (CRuntime_Bionic) { /// @@ -1223,6 +1230,70 @@ else version( NetBSD ) } } } +else version( DragonFlyBSD ) +{ + enum + { + FP_INFINITE = 0x01, + FP_NAN = 0x02, + FP_NORMAL = 0x04, + FP_SUBNORMAL = 0x08, + FP_ZERO = 0x10, + } + + /* + * /usr/include/math.h : martynas@openbsd believes only F version is true. + enum FP_FAST_FMA = 1; + enum FP_FAST_FMAL = 1; + */ + enum FP_FAST_FMAF = 1; + + pure int __fpclassifyd(double); + pure int __fpclassifyf(float); + pure int __fpclassifyl(real); + pure int __isfinitef(float); + pure int __isfinite(double); + pure int __isfinitel(real); + pure int __isinff(float); + pure int __isinf(double); + pure int __isinfl(real); + pure int __isnanf(float); + pure int __isnan(double); + pure int __isnanl(real); + pure int __isnormalf(float); + pure int __isnormal(double); + pure int __isnormall(real); + pure int __signbit(double); + pure int __signbitf(float); + pure int __signbitl(real); + + extern (D) + { + pure int fpclassify(float x) { return __fpclassifyf(x); } + pure int fpclassify(double x) { return __fpclassifyd(x); } + pure int fpclassify(real x) { return __fpclassifyl(x); } + + pure int isfinite(float x) { return __isfinitef(x); } + pure int isfinite(double x) { return __isfinite(x); } + pure int isfinite(real x) { return __isfinitel(x); } + + pure int isinf(float x) { return __isinff(x); } + pure int isinf(double x) { return __isinf(x); } + pure int isinf(real x) { return __isinfl(x); } + + pure int isnan(float x) { return __isnanf(x); } + pure int isnan(double x) { return __isnan(x); } + pure int isnan(real x) { return __isnanl(x); } + + pure int isnormal(float x) { return __isnormalf(x); } + pure int isnormal(double x) { return __isnormal(x); } + pure int isnormal(real x) { return __isnormall(x); } + + pure int signbit(float x) { return __signbitf(x); } + pure int signbit(double x) { return __signbit(x); } + pure int signbit(real x) { return __signbitl(x); } + } +} else version( Solaris ) { pure int __isnanf(float x); @@ -3110,6 +3181,250 @@ else version( OpenBSD ) /// pure float fmaf(float x, float y, float z); } +else version(DragonFlyBSD) +{ + /* double */ + double acos(double x); + double asin(double x); + double atan(double x); + double atan2(double, double); + double cos(double x); + double sin(double x); + double tan(double x); + + double cosh(double x); + double sinh(double x); + double tanh(double x); + + double exp(double x); + double frexp(double, int *exp); + double ldexp(double, int exp); + double log(double x); + double log10(double x); + double modf(double x, double *iptr); + + double pow(double x, double y); + double sqrt(double x); + + double ceil(double x); + double fabs(double x); + double floor(double x); + double fmod(double x, double); + + double acosh(double x); + double asinh(double x); + double atanh(double x); + + double exp2(double x); + double expm1(double x); + int ilogb(double x); + double log1p(double x); + double log2(double x); + double logb(double x); + double scalbn(double x, int n); + double scalbln(double x, c_long n); + + double cbrt(double x); + double hypot(double x, double y); + + double erf(double x); + double erfc(double x); + double lgamma(double x); + double tgamma(double x); + + double nearbyint(double x); + double rint(double x); + c_long lrint(double x); + long llrint(double x); + double round(double x); + c_long lround(double x); + long llround(double x); + double trunc(double x); + + double remainder(double x , double y); + double remquo(double x, double y, int * quo); + + double copysign(double x, double y); + double nan(const char *); + double nextafter(double x, double y); + double nexttoward(double x, real y); + + double fdim(double x, double y); + double fmax(double x, double y); + double fmin(double x, double y); + + double fma(double x, double y, double z); + + double j0(double x); + double j1(double x); + double jn(int, double); + double y0(double x); + double y1(double x); + double yn(int, double); + + double gamma(double x); + double scalb(double x, double y); + + double drem(double x, double y); + int finite(double x); + double gamma_r(double x, int *); + double lgamma_r(double x, int *); + + double significand(double x); + + /* float */ + float acosf(float x); + float asinf(float x); + float atanf(float x); + float atan2f(float x, float y); + float cosf(float x); + float sinf(float x); + float tanf(float x); + + float acoshf(float x); + float asinhf(float x); + float atanhf(float x); + float coshf(float x); + float sinhf(float x); + float tanhf(float x); + + float expf(float x); + float exp2f(float x); + float expm1f(float x); + float frexpf(float x, int *exp); + int ilogbf(float x); + float ldexpf(float x, int exp); + float logf(float x); + float log10f(float x); + float log1pf(float x); + float log2f(float x); + float logbf(float x); + float modff(float x, float *iptr); + float scalbnf(float x, int y); + float scalblnf(float x, c_long y); + + float cbrtf(float x); + float fabsf(float x); + float hypotf(float x, float y); + float powf(float x, float y); + float sqrtf(float x); + + float erff(float x); + float erfcf(float x); + float lgammaf(float x); + float tgammaf(float x); + + float ceilf(float x); + float floorf(float x); + float nearbyintf(float x); + float rintf(float x); + c_long lrintf(float x); + long llrintf(float x); + float roundf(float x); + c_long lroundf(float x); + long llroundf(float x); + float truncf(float x); + + float fmodf(float x, float y); + float remainderf(float x, float y); + float remquof(float x, float y, int *iptr); + + float copysignf(float x, float y); + float nanf(const char *); + float nextafterf(float x, float y); + float nexttowardf(float x, real y); + + float fdimf(float x, float y); + float fmaxf(float x, float y); + float fminf(float x, float y); + + float fmaf(float x, float y, float z); + + float j0f(float x); + float j1f(float x); + float jnf(int, float); + float scalbf(float x, float); + float y0f(float x); + float y1f(float x); + float ynf(int, float); + float gammaf(float x); + float dremf(float x, float); + int finitef(float x); + int isinff(float x); + int isnanf(float x); + + float gammaf_r(float x, int *); + float lgammaf_r(float x, int *); + float significandf(float x); + + /* real */ + real acosl(real x); + real asinl(real x); + real atanl(real x); + real atan2l(real x, real y); + real cosl(real x); + real sinl(real x); + real tanl(real x); + + real acoshl(real x); + real asinhl(real x); + real atanhl(real x); + real coshl(real x); + real sinhl(real x); + real tanhl(real x); + + real expl(real x); + real exp2l(real x); + real expm1l(real x); + real frexpl(real x, int *exp); + int ilogbl(real x); + real ldexpl(real x, int exp); + real logl(real x); + real log10l(real x); + real log1pl(real x); + real log2l(real x); + real logbl(real x); + real modfl(real x, real *iptr); + real scalbnl(real x, int y); + real scalblnl(real x, c_long y); + + real cbrtl(real x); + real fabsl(real x); + real hypotl(real x, real y); + real powl(real x, real y); + real sqrtl(real x); + + real erfl(real x); + real erfcl(real x); + real lgammal(real x); + real tgammal(real x); + + real ceill(real x); + real floorl(real x); + real nearbyintl(real x); + real rintl(real x); + c_long lrintl(real x); + long llrintl(real x); + real roundl(real x); + c_long lroundl(real x); + long llroundl(real x); + real truncl(real x); + + real fmodl(real x, real); + real remainderl(real x, real); + real remquol(real x, real y, int *iptr); + + real copysignl(real x, real y); + real nanl(const char *); + real nextafterl(real x, real y); + real nexttowardl(real x, real y); + + real fdiml(real x, real y); + real fmaxl(real x, real y); + real fminl(real x, real y); + + real fmal(real x, real, real); +} else version(CRuntime_Bionic) { // Bionic defines long double as 64 bits, same as double, so several long diff --git a/src/core/stdc/stdio.d b/src/core/stdc/stdio.d index 80bb2e5066..bf03dce482 100644 --- a/src/core/stdc/stdio.d +++ b/src/core/stdc/stdio.d @@ -42,6 +42,10 @@ private { import core.sys.posix.sys.types; } + version (DragonFlyBSD) + { + import core.sys.posix.sys.types; + } } extern (C): @@ -261,6 +265,45 @@ else version ( OpenBSD ) long __mbstateL; } } +else version ( DragonFlyBSD ) +{ + enum + { + BUFSIZ = 1024, + EOF = -1, + FOPEN_MAX = 20, + FILENAME_MAX = 1024, + TMP_MAX = 308915776, + L_tmpnam = 1024 + } + + struct __sbuf { // + byte* s_buf; // storage buffer + int function(void *, const char *, int) sbuf_drain_func; + void* s_drain_arg; // user-supplied drain argument + int s_error; // current error code + ssize_t s_size; // size of storage buffer + ssize_t s_len; // current length of string + int s_flags; // flags + ssize_t s_sect_len; // current length of section + }; + + enum { + SBUF_FIXEDLEN = 0x00000000, // fixed length buffer (default) + SBUF_AUTOEXTEND = 0x00000001, // automatically extend buffer + SBUF_USRFLAGMSK = 0x0000ffff, // mask of flags the user may specify + SBUF_DYNAMIC = 0x00010000, // s_buf must be freed + SBUF_FINISHED = 0x00020000, // set by sbuf_finish() + SBUF_DYNSTRUCT = 0x00080000, // sbuf must be freed + SBUF_INSECTION = 0x00100000, // set by sbuf_start_section() + } + + union __mbstate_t // + { + char[128] _mbstate8; + long _mbstateL; + } +} else version (Solaris) { enum @@ -583,6 +626,24 @@ else version( OpenBSD ) /// alias shared(__sFILE) FILE; } +else version( DragonFlyBSD ) +{ + alias off_t fpos_t; + + /// See /usr/include/stdio.h + struct __FILE_public + { + ubyte* *_p; /* current position in (some) buffer */ + int _flags; /* flags, below; this FILE is free if 0 */ + int _fileno; /* fileno, if Unix descriptor, else -1 */ + ssize_t _r; /* read space left for getc() */ + ssize_t _w; /* write space left for putc() */ + ssize_t _lbfsize; /* 0 or -_bf._size, for inline putc */ + } + + alias __FILE_public _iobuf; + alias shared(__FILE_public) FILE; +} else version (Solaris) { import core.stdc.wchar_ : __mbstate_t; @@ -895,6 +956,23 @@ else version( OpenBSD ) /// shared stderr = &__sF[2]; } +else version( DragonFlyBSD ) +{ + enum + { + _IOFBF = 0, + _IOLBF = 1, + _IONBF = 2, + } + + private extern shared FILE* __stdinp; + private extern shared FILE* __stdoutp; + private extern shared FILE* __stderrp; + + alias __stdinp stdin; + alias __stdoutp stdout; + alias __stderrp stderr; +} else version (Solaris) { enum @@ -1422,6 +1500,37 @@ else version( OpenBSD ) /// int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } +else version( DragonFlyBSD ) +{ + // No unsafe pointer manipulation. + @trusted + { + void rewind(FILE*); + pure void clearerr(FILE*); + pure int feof(FILE*); + pure int ferror(FILE*); + int fileno(FILE*); + } + enum __SLBF = 0x0001; + enum __SNBF = 0x0002; + enum __SRD = 0x0004; + enum __SWR = 0x0008; + enum __SRW = 0x0010; + enum __SEOF = 0x0020; + enum __SERR = 0x0040; + enum __SMBF = 0x0080; + enum __SAPP = 0x0100; + enum __SSTR = 0x0200; + enum __SOPT = 0x0400; + enum __SNPT = 0x0800; + enum __SOFF = 0x1000; + enum __SMOD = 0x2000; + enum __SALC = 0x4000; + enum __SIGN = 0x8000; + + int snprintf(scope char* s, size_t n, scope const char* format, ...); + int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); +} else version (Solaris) { // No unsafe pointer manipulation. diff --git a/src/core/stdc/stdlib.d b/src/core/stdc/stdlib.d index e98be23166..dffbf32427 100644 --- a/src/core/stdc/stdlib.d +++ b/src/core/stdc/stdlib.d @@ -77,6 +77,7 @@ else version(Darwin) enum RAND_MAX = 0x7fffffff; else version(FreeBSD) enum RAND_MAX = 0x7fffffff; else version(NetBSD) enum RAND_MAX = 0x7fffffff; else version(OpenBSD) enum RAND_MAX = 0x7fffffff; +else version(DragonFlyBSD) enum RAND_MAX = 0x7fffffff; else version(Solaris) enum RAND_MAX = 0x7fff; else version(CRuntime_Bionic) enum RAND_MAX = 0x7fffffff; else version(CRuntime_Musl) enum RAND_MAX = 0x7fffffff; diff --git a/src/core/stdc/string.d b/src/core/stdc/string.d index e3c6e2ebb5..56b18026b7 100644 --- a/src/core/stdc/string.d +++ b/src/core/stdc/string.d @@ -97,6 +97,10 @@ else version (OpenBSD) { int strerror_r(int errnum, scope char* buf, size_t buflen); } +else version (DragonFlyBSD) +{ + int strerror_r(int errnum, scope char* buf, size_t buflen); +} else version (Solaris) { int strerror_r(int errnum, scope char* buf, size_t buflen); diff --git a/src/core/stdc/time.d b/src/core/stdc/time.d index 294e6fadf7..28975d522e 100644 --- a/src/core/stdc/time.d +++ b/src/core/stdc/time.d @@ -103,6 +103,10 @@ else version( OpenBSD ) { enum clock_t CLOCKS_PER_SEC = 100; } +else version( DragonFlyBSD ) +{ + enum clock_t CLOCKS_PER_SEC = 128; +} else version (CRuntime_Glibc) { enum clock_t CLOCKS_PER_SEC = 1_000_000; @@ -184,6 +188,13 @@ else version( OpenBSD ) /// extern __gshared const(char)*[2] tzname; // non-standard } +else version( DragonFlyBSD ) +{ + /// + void tzset(); // non-standard + /// + extern __gshared const(char)*[2] tzname; // non-standard +} else version (Solaris) { /// diff --git a/src/core/sync/mutex.d b/src/core/sync/mutex.d index ca71794b8f..169846baf3 100644 --- a/src/core/sync/mutex.d +++ b/src/core/sync/mutex.d @@ -374,10 +374,10 @@ unittest // by checking that locking is not possible. This assumes // that the underlying implementation is well behaved // and makes the object non-lockable upon destruction. - // For example, Bionic doesn't appear to do so, so this test is - // not run on Android. + // The Bionic and Musl C runtimes and DragonFly don't appear to do so, so skip this test. version (CRuntime_Bionic) {} else version (CRuntime_Musl) {} else + version (DragonFlyBSD) {} else assert(!mtx.tryLock_nothrow()); free(cast(void*) mtx); diff --git a/src/core/sys/linux/elf.d b/src/core/sys/linux/elf.d index f467371ed5..19f7aa4204 100644 --- a/src/core/sys/linux/elf.d +++ b/src/core/sys/linux/elf.d @@ -121,6 +121,7 @@ enum ELFOSABI_OPENBSD = 12; enum ELFOSABI_ARM_AEABI = 64; enum ELFOSABI_ARM = 97; enum ELFOSABI_STANDALONE = 255; +enum ELFOSABI_DRAGONFLYBSD = ELFOSABI_NONE; enum EI_ABIVERSION = 8; diff --git a/src/core/sys/netbsd/sys/elf_common.d b/src/core/sys/netbsd/sys/elf_common.d index 3bfb48c44b..91d8933995 100644 --- a/src/core/sys/netbsd/sys/elf_common.d +++ b/src/core/sys/netbsd/sys/elf_common.d @@ -78,6 +78,7 @@ enum ELFOSABI_NSK = 14; enum ELFOSABI_AROS = 15; enum ELFOSABI_ARM = 97; enum ELFOSABI_STANDALONE = 255; +enum ELFOSABI_DRAGONFLYBSD = ELFOSABI_NONE; extern (D) { diff --git a/src/core/sys/osx/sys/mman.d b/src/core/sys/osx/sys/mman.d index 066ea93cc9..b5a8719a17 100644 --- a/src/core/sys/osx/sys/mman.d +++ b/src/core/sys/osx/sys/mman.d @@ -2,7 +2,7 @@ * $(RED Deprecated. Use $(D core.sys.darwin.sys.mman) instead. This module * will be removed in June 2018.) * - * D header file for FreeBSD + * D header file for OSX * * Authors: Martin Nowak */ diff --git a/src/core/sys/solaris/sys/elf.d b/src/core/sys/solaris/sys/elf.d index 5b59f22abd..c0312fc2b6 100644 --- a/src/core/sys/solaris/sys/elf.d +++ b/src/core/sys/solaris/sys/elf.d @@ -229,6 +229,7 @@ enum ELFOSABI_NSK = 14; enum ELFOSABI_AROS = 15; enum ELFOSABI_ARM = 97; enum ELFOSABI_STANDALONE = 255; +enum ELFOSABI_DRAGONFLYBSD= ELFOSABI_NONE; enum EAV_SUNW_NONE = 0; enum EAV_SUNW_CURRENT = 1; diff --git a/src/core/thread.d b/src/core/thread.d index 83a4a26b53..60ef223f0a 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -1189,7 +1189,7 @@ class Thread } else { - // NOTE: pthread_setschedprio is not implemented on Darwin or FreeBSD, so use + // NOTE: pthread_setschedprio is not implemented on Darwin, FreeBSD or DragonFlyBSD, so use // the more complicated get/set sequence below. int policy; sched_param param; @@ -3206,6 +3206,7 @@ extern (C) @nogc nothrow version (CRuntime_Glibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr); version (FreeBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); version (NetBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); + version (DragonFlyBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr); version (Solaris) int thr_stksegment(stack_t* stk); version (CRuntime_Bionic) int pthread_getattr_np(pthread_t thid, pthread_attr_t* attr); version (CRuntime_Musl) int pthread_getattr_np(pthread_t, pthread_attr_t*); @@ -3278,6 +3279,17 @@ private void* getStackBottom() nothrow @nogc pthread_attr_destroy(&attr); return addr + size; } + else version (DragonFlyBSD) + { + pthread_attr_t attr; + void* addr; size_t size; + + pthread_attr_init(&attr); + pthread_attr_get_np(pthread_self(), &attr); + pthread_attr_getstack(&attr, &addr, &size); + pthread_attr_destroy(&attr); + return addr + size; + } else version (Solaris) { stack_t stk; @@ -4521,6 +4533,7 @@ private: version (Posix) import core.sys.posix.sys.mman; // mmap version (FreeBSD) import core.sys.freebsd.sys.mman : MAP_ANON; version (NetBSD) import core.sys.netbsd.sys.mman : MAP_ANON; + version (DragonFlyBSD) import core.sys.dragonflybsd.sys.mman : MAP_ANON; version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON; version (Darwin) import core.sys.darwin.sys.mman : MAP_ANON; @@ -5524,6 +5537,27 @@ version (FreeBSD) unittest thr.join(); } +version (DragonFlyBSD) unittest +{ + static void loop() + { + pthread_attr_t attr; + pthread_attr_init(&attr); + auto thr = pthread_self(); + foreach (i; 0 .. 50) + pthread_attr_get_np(thr, &attr); + pthread_attr_destroy(&attr); + } + + auto thr = new Thread(&loop).start(); + foreach (i; 0 .. 50) + { + thread_suspendAll(); + thread_resumeAll(); + } + thr.join(); +} + unittest { // use >PAGESIZE to avoid stack overflow (e.g. in an syscall) diff --git a/src/core/threadasm.S b/src/core/threadasm.S index 9a1538115a..3e57b10758 100644 --- a/src/core/threadasm.S +++ b/src/core/threadasm.S @@ -13,7 +13,7 @@ * http://www.boost.org/LICENSE_1_0.txt) */ -#if (defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__ELF__) +#if (__linux__ || __FreeBSD__ || __NetBSD__ || __DragonFly__) && __ELF__ /* * Mark the resulting object file as not requiring execution permissions on * stack memory. The absence of this section would mark the whole resulting diff --git a/src/core/time.d b/src/core/time.d index 9e59f7c656..14050b6842 100644 --- a/src/core/time.d +++ b/src/core/time.d @@ -195,7 +195,7 @@ version(CoreDdoc) enum ClockType extremely frequently (e.g. hundreds of thousands of times a second) but don't care about high precision, the coarse clock might be appropriate. - Currently, only Linux and FreeBSD support a coarser clock, and on other + Currently, only Linux and FreeBSD/DragonFlyBSD support a coarser clock, and on other platforms, it's treated as $(D ClockType.normal). +/ coarse = 2, @@ -207,7 +207,7 @@ version(CoreDdoc) enum ClockType more precise clock than the normal one, it's treated as equivalent to $(D ClockType.normal). - Currently, only FreeBSD supports a more precise clock, where it uses + Currently, only FreeBSD/DragonFlyBSD supports a more precise clock, where it uses $(D CLOCK_MONOTONIC_PRECISE) for the monotonic time and $(D CLOCK_REALTIME_PRECISE) for the wall clock time. +/ @@ -231,7 +231,7 @@ version(CoreDdoc) enum ClockType Uses a clock that has a precision of one second (contrast to the coarse clock, which has sub-second precision like the normal clock does). - FreeBSD is the only system which specifically has a clock set up for + FreeBSD/DragonFlyBSD are the only systems which specifically have a clock set up for this (it has $(D CLOCK_SECOND) to use with $(D clock_gettime) which takes advantage of an in-kernel cached value), but on other systems, the fastest function available will be used, and the resulting $(D SysTime) @@ -320,6 +320,16 @@ else version(NetBSD) enum ClockType precise = 3, second = 6, } +else version(DragonFlyBSD) enum ClockType +{ + normal = 0, + coarse = 2, + precise = 3, + second = 6, + uptime = 8, + uptimeCoarse = 9, + uptimePrecise = 10, +} else version(Solaris) enum ClockType { normal = 0, @@ -386,6 +396,20 @@ version(Posix) case second: assert(0); } } + else version(DragonFlyBSD) + { + import core.sys.dragonflybsd.time; + with(ClockType) final switch(clockType) + { + case coarse: return CLOCK_MONOTONIC_FAST; + case normal: return CLOCK_MONOTONIC; + case precise: return CLOCK_MONOTONIC_PRECISE; + case uptime: return CLOCK_UPTIME; + case uptimeCoarse: return CLOCK_UPTIME_FAST; + case uptimePrecise: return CLOCK_UPTIME_PRECISE; + case second: assert(0); + } + } else version(Solaris) { import core.sys.solaris.time; diff --git a/src/gc/os.d b/src/gc/os.d index 39aac1ae1f..9e75dfd9b4 100644 --- a/src/gc/os.d +++ b/src/gc/os.d @@ -40,6 +40,7 @@ else version (Posix) import core.sys.posix.sys.mman; version (FreeBSD) import core.sys.freebsd.sys.mman : MAP_ANON; + version (DragonFlyBSD) import core.sys.dragonflybsd.sys.mman : MAP_ANON; version (NetBSD) import core.sys.netbsd.sys.mman : MAP_ANON; version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON; version (Darwin) import core.sys.darwin.sys.mman : MAP_ANON; diff --git a/src/rt/backtrace/dwarf.d b/src/rt/backtrace/dwarf.d index db93aa0ff2..79173fbf3d 100644 --- a/src/rt/backtrace/dwarf.d +++ b/src/rt/backtrace/dwarf.d @@ -12,10 +12,11 @@ module rt.backtrace.dwarf; -version(CRuntime_Glibc) version = linux_or_freebsd; -else version(FreeBSD) version = linux_or_freebsd; +version(CRuntime_Glibc) version = glibc_or_bsdlibc; +else version(FreeBSD) version = glibc_or_bsdlibc; +else version(DragonFlyBSD) version = glibc_or_bsdlibc; -version(linux_or_freebsd): +version(glibc_or_bsdlibc): import rt.util.container.array; import rt.backtrace.elf; @@ -36,6 +37,7 @@ int traceHandlerOpApplyImpl(const void*[] callstack, scope int delegate(ref size import core.stdc.stdio : snprintf; version(linux) import core.sys.linux.execinfo : backtrace_symbols; else version(FreeBSD) import core.sys.freebsd.execinfo : backtrace_symbols; + else version(DragonFlyBSD) import core.sys.dragonflybsd.execinfo : backtrace_symbols; import core.sys.posix.stdlib : free; const char** frameList = backtrace_symbols(callstack.ptr, cast(int) callstack.length); @@ -392,6 +394,13 @@ const(char)[] getDemangledSymbol(const(char)[] btSymbol, ref char[1024] buffer) auto eptr = cast(char*) memchr(btSymbol.ptr, '>', btSymbol.length); auto pptr = cast(char*) memchr(btSymbol.ptr, '+', btSymbol.length); } + else version(DragonFlyBSD) + { + // format is: 0x00000000 <_D6module4funcAFZv+0x78> at module + auto bptr = cast(char*) memchr(btSymbol.ptr, '<', btSymbol.length); + auto eptr = cast(char*) memchr(btSymbol.ptr, '>', btSymbol.length); + auto pptr = cast(char*) memchr(btSymbol.ptr, '+', btSymbol.length); + } if (pptr && pptr < eptr) eptr = pptr; diff --git a/src/rt/backtrace/elf.d b/src/rt/backtrace/elf.d index e2c37f1fef..d907f2b972 100644 --- a/src/rt/backtrace/elf.d +++ b/src/rt/backtrace/elf.d @@ -11,16 +11,18 @@ module rt.backtrace.elf; -version(linux) version = linux_or_freebsd; -else version(FreeBSD) version = linux_or_freebsd; +version(linux) version = linux_or_bsd; +else version(FreeBSD) version = linux_or_bsd; +else version(DragonFlyBSD) version = linux_or_bsd; -version(linux_or_freebsd): +version(linux_or_bsd): import core.sys.posix.fcntl; import core.sys.posix.unistd; version(linux) public import core.sys.linux.elf; version(FreeBSD) public import core.sys.freebsd.sys.elf; +version(DragonFlyBSD) public import core.sys.dragonflybsd.sys.elf; struct ElfFile { @@ -36,6 +38,10 @@ struct ElfFile auto selfPath = getFreeBSDExePath(selfPathBuffer[]); if (selfPath is null) return false; } + else version (DragonFlyBSD) + { + auto selfPath = "/proc/curproc/file".ptr; + } file.fd = open(selfPath, O_RDONLY); if (file.fd >= 0) diff --git a/src/rt/dmain2.d b/src/rt/dmain2.d index 5ab13b6d80..658df75891 100644 --- a/src/rt/dmain2.d +++ b/src/rt/dmain2.d @@ -39,6 +39,10 @@ version (NetBSD) { import core.stdc.fenv; } +version (DragonFlyBSD) +{ + import core.stdc.fenv; +} // not sure why we can't define this in one place, but this is to keep this // module from importing core.runtime. diff --git a/src/rt/qsort.d b/src/rt/qsort.d index 9e553b24d9..cc45c5706f 100644 --- a/src/rt/qsort.d +++ b/src/rt/qsort.d @@ -57,6 +57,21 @@ else version (FreeBSD) return a; } } +else version (DragonFlyBSD) +{ + alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp; + extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp); + + extern (C) void[] _adSort(return scope void[] a, TypeInfo ti) + { + extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2) + { + return (cast(TypeInfo)ti).compare(p1, p2); + } + qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp); + return a; + } +} else version (Darwin) { alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp; diff --git a/src/rt/sections.d b/src/rt/sections.d index c28a216a37..1737c92433 100644 --- a/src/rt/sections.d +++ b/src/rt/sections.d @@ -27,6 +27,8 @@ else version (FreeBSD) public import rt.sections_elf_shared; else version (NetBSD) public import rt.sections_elf_shared; +else version (DragonFlyBSD) + public import rt.sections_elf_shared; else version (Solaris) public import rt.sections_solaris; else version (Darwin) diff --git a/src/rt/sections_elf_shared.d b/src/rt/sections_elf_shared.d index 6bead38421..8b4af7afae 100644 --- a/src/rt/sections_elf_shared.d +++ b/src/rt/sections_elf_shared.d @@ -14,6 +14,7 @@ version (CRuntime_Glibc) enum SharedELF = true; else version (CRuntime_Musl) enum SharedELF = true; else version (FreeBSD) enum SharedELF = true; else version (NetBSD) enum SharedELF = true; +else version (DragonFlyBSD) enum SharedELF = true; else enum SharedELF = false; static if (SharedELF): @@ -40,6 +41,12 @@ else version (NetBSD) import core.sys.netbsd.sys.elf; import core.sys.netbsd.sys.link_elf; } +else version (DragonFlyBSD) +{ + import core.sys.dragonflybsd.dlfcn; + import core.sys.dragonflybsd.sys.elf; + import core.sys.dragonflybsd.sys.link_elf; +} else { static assert(0, "unimplemented"); @@ -122,6 +129,7 @@ __gshared bool _isRuntimeInitialized; version (FreeBSD) private __gshared void* dummy_ref; +version (DragonFlyBSD) private __gshared void* dummy_ref; version (NetBSD) private __gshared void* dummy_ref; /**** @@ -132,6 +140,7 @@ void initSections() nothrow @nogc _isRuntimeInitialized = true; // reference symbol to support weak linkage version (FreeBSD) dummy_ref = &_d_dso_registry; + version (DragonFlyBSD) dummy_ref = &_d_dso_registry; version (NetBSD) dummy_ref = &_d_dso_registry; } @@ -262,6 +271,7 @@ private: // start of linked list for ModuleInfo references version (FreeBSD) deprecated extern (C) __gshared void* _Dmodule_ref; +version (DragonFlyBSD) deprecated extern (C) __gshared void* _Dmodule_ref; version (NetBSD) deprecated extern (C) __gshared void* _Dmodule_ref; version (Shared) @@ -679,6 +689,8 @@ version (Shared) strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate else version (NetBSD) strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (DragonFlyBSD) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate else static assert(0, "unimplemented"); break; @@ -801,6 +813,10 @@ else version (NetBSD) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* resul auto dg = DG(addr, result); return dl_iterate_phdr(&callback, &dg) != 0; } +else version (DragonFlyBSD) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc +{ + return !!_rtld_addr_phdr(addr, result); +} /********************************* * Determine if 'addr' lies within shared object 'info'. @@ -826,12 +842,14 @@ bool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!"Phdr"* re version (linux) import core.sys.linux.errno : program_invocation_name; // should be in core.sys.freebsd.stdlib version (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc; +version (DragonFlyBSD) extern(C) const(char)* getprogname() nothrow @nogc; version (NetBSD) extern(C) const(char)* getprogname() nothrow @nogc; @property const(char)* progname() nothrow @nogc { version (linux) return program_invocation_name; version (FreeBSD) return getprogname(); + version (DragonFlyBSD) return getprogname(); version (NetBSD) return getprogname(); } diff --git a/src/rt/util/typeinfo.d b/src/rt/util/typeinfo.d index 81b62c5b91..51c4632e93 100644 --- a/src/rt/util/typeinfo.d +++ b/src/rt/util/typeinfo.d @@ -247,7 +247,7 @@ unittest { assert(f1 == 0 + 0i); - assert(f1 == f2); + assert(f1 == f2); assert(f1 !is f2); ti = typeid(F); assert(ti.getHash(&f1) == ti.getHash(&f2)); diff --git a/test/exceptions/Makefile b/test/exceptions/Makefile index 6b9858db9e..8a674f37c0 100644 --- a/test/exceptions/Makefile +++ b/test/exceptions/Makefile @@ -8,6 +8,9 @@ endif ifeq ($(OS)-$(BUILD),freebsd-debug) TESTS:=$(TESTS) line_trace endif +ifeq ($(OS)-$(BUILD),dragonflybsd-debug) + TESTS:=$(TESTS) line_trace +endif DIFF:=diff SED:=sed diff --git a/test/shared/Makefile b/test/shared/Makefile index a4455682b5..ae997c5c8b 100644 --- a/test/shared/Makefile +++ b/test/shared/Makefile @@ -5,8 +5,8 @@ include ../common.mak TESTS:=link load linkD linkDR loadDR host finalize TESTS+=link_linkdep load_linkdep link_loaddep load_loaddep load_13414 -EXPORT_DYNAMIC=$(if $(findstring $(OS),linux freebsd),-L--export-dynamic,) -NO_AS_NEEDED=$(if $(findstring $(OS),linux freebsd),-L--no-as-needed,) +EXPORT_DYNAMIC=$(if $(findstring $(OS),linux freebsd dragonflybsd),-L--export-dynamic,) +NO_AS_NEEDED=$(if $(findstring $(OS),linux freebsd dragonflybsd),-L--no-as-needed,) .PHONY: all clean all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS))) diff --git a/test/shared/src/host.c b/test/shared/src/host.c index 81e896aa3d..395ad0c3f5 100644 --- a/test/shared/src/host.c +++ b/test/shared/src/host.c @@ -10,6 +10,11 @@ int main(int argc, char* argv[]) void *druntime = dlopen(argv[1], RTLD_LAZY); // load druntime assert(druntime); #endif +#if defined(__DragonFly__) + // workaround for Bugzilla 14824 + void *druntime = dlopen(argv[1], RTLD_LAZY); // load druntime + assert(druntime); +#endif const size_t pathlen = strrchr(argv[0], '/') - argv[0] + 1; char *name = malloc(pathlen + sizeof("plugin1.so")); @@ -55,6 +60,9 @@ int main(int argc, char* argv[]) #if defined(__FreeBSD__) dlclose(druntime); +#endif +#if defined(__DragonFly__) + dlclose(druntime); #endif return EXIT_SUCCESS; } diff --git a/test/shared/src/load.d b/test/shared/src/load.d index 8c13f51eac..4e0e3ab628 100644 --- a/test/shared/src/load.d +++ b/test/shared/src/load.d @@ -5,6 +5,7 @@ import core.thread; version (linux) import core.sys.linux.dlfcn; else version (FreeBSD) import core.sys.freebsd.dlfcn; +else version (DragonFlyBSD) import core.sys.dragonflybsd.dlfcn; else version (NetBSD) import core.sys.netbsd.dlfcn; else static assert(0, "unimplemented");