Fix D compilation on Solaris

Message ID ydd1s871yng.fsf@CeBiTec.Uni-Bielefeld.DE
State New
Headers show
Series
  • Fix D compilation on Solaris
Related show

Commit Message

Rainer Orth Oct. 30, 2018, 11:06 a.m.
I just tried building D on Solaris 11/SPARC and x86 and ran into a
couple of issues.  The following patch is at least enough to have the
build finish on Solaris 11/x86, but on SPARC d21 runs into several BUS
errors (probably due to alignment issues).

One comment up front: I believe it would be good if libphobos had a
configure.tgt like several other target libraries so users won't run
into D related build failures with --enable-languages=all for targets
known not to work.

Here are the issues I ran into:

* On sparc, the build first aborted with

In file included from ./tm_d.h:7,
                 from /vol/gcc/src/hg/trunk/local/gcc/config/default-d.c:21:
/vol/gcc/src/hg/trunk/local/gcc/config/sparc/sparc-protos.h:45:47: error: use of enum 'memmodel' without previous declaration
   45 | extern void sparc_emit_membar_for_model (enum memmodel, int, int);
      |                                               ^~~~~~~~

  Unlike glibc-d.c, default-d.c fails to include memmodel.h.  The patch
  below fixes that.

* However, default-d.c isn't very useful for Solaris.  Instead, I've
  added sol2-d.c which implements a proper TARGET_D_OS_VERSIONS.

* Next, the sparc build ran into

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/stdc/fenv.d:700:9: error: static assert  "Unimplemented architecture"
  700 |         static assert(0, "Unimplemented architecture");
      |         ^

  and indeed the file lacked SPARC definitions.  However, even the x86
  ones are really Linux/x86, so I added apropriate definitions for
  Solaris/x86, too.

* Next, I ran into

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections.d:70:5: error: static assert  (is(typeof(&pinLoadedLibraries) == void* function() nothrow @nogc)) is false
   70 |     static assert(is(typeof(&pinLoadedLibraries) == void* function() nothrow @nogc));
      |     ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections.d:70:5: error: static assert  (is(typeof(&pinLoadedLibraries) == void* function() nothrow @nogc)) is false
   70 |     static assert(is(typeof(&pinLoadedLibraries) == void* function() nothrow @nogc));
      |     ^

  To get me further along, I added dummy definitions to
  sections_solaris.d.  However, I wonder if it wouldn't be better to
  adapt sections_elf_shared.d to Solaris instead?

* Next error on sparc:

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:951:26: error: undefined identifier '_NGREG'
  951 |     alias greg_t[_NGREG] gregset_t;
      |                          ^
d21: internal compiler error: Bus Error

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:1017:21: error: undefined identifier 'fpregset_t', did you mean alias 'gregset_t'?
 1017 |         fpregset_t  fpregs;
      |                     ^

  ucontext.d lacked several SPARC and SPARC64 definitions here.  While
  adding D version of system types manually in a few cases is workable
  if tedious, I wonder if there isn't an easier way to do this.  Imagine
  a new port when there are many more definitions to add...

* Next error:

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d:989:21: error: cannot modify immutable expression m_isRTClass
  989 |                     m_isRTClass = true;
      |                     ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d:997:21: error: cannot modify immutable expression m_isRTClass
  997 |                     m_isRTClass = false;
      |                     ^

  It seems weird to assign to an immutable variable, so I removed that
  attribute.

* Next:

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections_solaris.d:63:5: error: @nogc function 'rt.sections_solaris.initSections' cannot call non-@nogc function 'rt.sections_solaris.SectionGroup.moduleGroup'
   63 |     _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);
      |     ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections_solaris.d:63:5: error: function 'rt.sections_solaris.SectionGroup.moduleGroup' is not nothrow
   63 |     _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);
      |     ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections_solaris.d:59:6: error: nothrow function 'rt.sections_solaris.initSections' may throw
   59 | void initSections() nothrow @nogc
      |      ^

  Adding nothrow @nogc to moduleGroup definition fixed that.

* Next:

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/aio.d:127:5: error: static assert  "Unsupported platform"
  127 |     static assert(false, "Unsupported platform");
      |     ^

  The file needed a definition of the Solaris versions.  The one I added
  is enough to get the build to continue, but may well need an
  additional largefile version...

* Next and final build error:

/vol/gcc/src/hg/trunk/local/libphobos/src/std/datetime/systime.d:229:25: error:undefined identifier ‘clock_gettime’
  229 |                     if (clock_gettime(clockArg, &ts) != 0)
      |                         ^
/vol/gcc/src/hg/trunk/local/libphobos/src/std/datetime/systime.d:66:24: error: template instance std.datetime.systime.Clock.currStdTime!cast(ClockType)0 error instantiating
   66 |         return SysTime(currStdTime!clockType, tz);
      |                        ^
/vol/gcc/src/hg/trunk/local/libphobos/src/std/datetime/timezone.d:795:63: note:instantiated from here: currTime!cast(ClockType)0
  795 |                     auto currYear = (cast(Date) Clock.currTime()).year;
      |                                        

  The file needs to import clock_gettime on Solaris.

* Initially, I did the Solaris/x86 build with /bin/as.  However, that
  ran into

Input string too long, limit 10240
make[2]: *** [std/datetime/timezone.lo] Error 1

  I haven't yet checked which string exceeds that hard limit, but
  continued with gas instead.

* With the patches described above, the x86 build using gas finished,
  but every single link test FAILs with

FAIL: gdc.dg/gdc283.d   -O0  (test for excess errors)
Excess errors:
Undefined                       first referenced
 symbol                             in file
_tlsstart                           /var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
_tlsend                             /var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
__start_deh                         /var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
__stop_deh                          /var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
_d_dso_registry                     /var/tmp//ccVc7Kgd.o

  I've yet no idea what I'm supposed to do about those.  As I mentioned,
  it may be better to try and get sections_elf_shared.d to support
  Solaris instead?  It seems some of the Solaris support has
  bitrotted...

* On sparc, I didn't get that far, unfortunately: as I mentioned, many
  compilations die with SIGBUS:

libtool: compile:  /var/gcc/regression/trunk/11.5-gcc/build/./gcc/gdc -B/var/gcc/regression/trunk/11.5-gcc/build/./gcc/ -B/vol/gcc/sparc-sun-solaris2.11/bin/ -B/vol/gcc/sparc-sun-solaris2.11/lib/ -isystem /vol/gcc/sparc-sun-solaris2.11/include -isystem /vol/gcc/sparc-sun-solaris2.11/sys-include -fno-checking -fPIC -O2 -g -nostdinc -I /vol/gcc/src/hg/trunk/local/libphobos/libdruntime -I . -c /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d -fversion=Shared -o core/.libs/thread.o
d21: internal compiler error: Bus Error
0xbb5507 crash_signal
        /vol/gcc/src/hg/trunk/local/gcc/toplev.c:325
0x518700 IntegerExp::toInteger()
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.c:2943
0x4d05c3 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d1543 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
0x4d1543 interpret(Statement*, InterState*)
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
0x4d263b interpretFunction
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
0x4d263b interpretFunction
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
0x4d05c3 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d14df interpret(Expression*, InterState*, CtfeGoal)
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
0x4d05c3 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d14df interpret(Expression*, InterState*, CtfeGoal)
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
0x5243d7 DeclarationExp::accept(Visitor*)
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:661
0x4d05c3 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d1543 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
0x4d1543 interpret(Statement*, InterState*)
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
0x4d263b interpretFunction
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
0x4d263b interpretFunction
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
0x4d05c3 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d14df interpret(Expression*, InterState*, CtfeGoal)
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
0x4d05c3 interpret
        /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

  Will need to dig further here.

Anyway, please find attached the patch that got me to this point.
Honestly, I've no idea how the ChangeLog is supposed to be formatted for
D yet.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2018-10-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config/default-d.c: Include memmodel.h.

	* config/sol2-d.c: New file.
	* config/t-sol2 (sol2-d.o): New rule.
	* config.gcc <*-*-solaris2*>: Set d_target_objs,
	target_has_targetdm.

	libphobos:
	* libdruntime/core/stdc/fenv.d [SPARC, SPARC64]: Set SPARC_Any.
	[X86, X86_64]: Set X86_Any.
	[Solaris]: Provide FE_* constants.
	* libdruntime/core/sys/posix/aio.d [Solaris] (struct aio_result,
	struct aiocb): New types.
	* libdruntime/core/sys/posix/ucontext.d [SPARC64, SPARC] (_NGREG,
	greg_t): Define.
	[SPARC64, SPARC] (struct _fpq, struct fq, struct fpregset_t): New
	types.
	* libdruntime/core/thread.d (Class Thread) [Solaris]
	(m_isRTClass): Don't declare immutable.
	* libdruntime/rt/sections_solaris.d (SectionGroup.moduleGroup):
	Declare nothrow @nogc.
	(pinLoadedLibraries, unpinLoadedLibraries, inheritLoadedLibraries)
	(cleanupLoadedLibraries): New functions.
	* src/std/datetime/systime.d (class Clock) [Solaris]
	(clock_gettime): Import.

Comments

Rainer Orth Oct. 30, 2018, 1:12 p.m. | #1
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> * On sparc, I didn't get that far, unfortunately: as I mentioned, many

>   compilations die with SIGBUS:

>

> libtool: compile:  /var/gcc/regression/trunk/11.5-gcc/build/./gcc/gdc -B/var/gcc/regression/trunk/11.5-gcc/build/./gcc/ -B/vol/gcc/sparc-sun-solaris2.11/bin/ -B/vol/gcc/sparc-sun-solaris2.11/lib/ -isystem /vol/gcc/sparc-sun-solaris2.11/include -isystem /vol/gcc/sparc-sun-solaris2.11/sys-include -fno-checking -fPIC -O2 -g -nostdinc -I /vol/gcc/src/hg/trunk/local/libphobos/libdruntime -I . -c /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d -fversion=Shared -o core/.libs/thread.o

> d21: internal compiler error: Bus Error

> 0xbb5507 crash_signal

>         /vol/gcc/src/hg/trunk/local/gcc/toplev.c:325

> 0x518700 IntegerExp::toInteger()

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.c:2943

> 0x4d05c3 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> 0x4d1543 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017

> 0x4d1543 interpret(Statement*, InterState*)

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024

> 0x4d263b interpretFunction

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906

> 0x4d263b interpretFunction

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726

> 0x4d05c3 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> 0x4d14df interpret(Expression*, InterState*, CtfeGoal)

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994

> 0x4d05c3 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> 0x4d14df interpret(Expression*, InterState*, CtfeGoal)

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994

> 0x5243d7 DeclarationExp::accept(Visitor*)

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:661

> 0x4d05c3 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> 0x4d1543 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017

> 0x4d1543 interpret(Statement*, InterState*)

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024

> 0x4d263b interpretFunction

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906

> 0x4d263b interpretFunction

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726

> 0x4d05c3 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> 0x4d14df interpret(Expression*, InterState*, CtfeGoal)

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994

> 0x4d05c3 interpret

>         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

>

>   Will need to dig further here.


It's exactly as I suspected:

$ d21 /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d -mcpu=v9 -fversion=Shared -I /vol/gcc/src/hg/trunk/local/libphobos/libdruntime -o thread.s

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0x00518700 in IntegerExp::toInteger (this=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.c:2942
2942        return value;
(gdb) where
#0  0x00518700 in IntegerExp::toInteger (this=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.c:2942
#1  0x004d8f24 in Interpreter::visit(BinExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#2  0x005268ec in CmpExp::accept(Visitor*) ()
#3  0x004d05c4 in interpret (pue=0xffbfbbf4, e=0x22778f0, istate=0xffbfc144, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#4  0x004d6254 in Interpreter::visit(ForStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#5  0x005aec68 in ForStatement::accept(Visitor*) ()
#6  0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#7  0x005b5708 in CompoundStatement::accept(Visitor*) ()
#8  0x004d4810 in Interpreter::visit(ScopeStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#9  0x005aec08 in ScopeStatement::accept(Visitor*) ()
#10 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#11 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#12 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#13 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#14 0x004d1544 in interpret (istate=<optimized out>, s=<optimized out>, 
    pue=0xffbfc07c) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
#15 interpret (s=0x22ea0f8, istate=0xffbfc144)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
#16 0x004d263c in interpretFunction (thisarg=0x22f6198, 
    arguments=<optimized out>, istate=0xffbfcb5c, fd=0x2270cc0)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
#17 interpretFunction (fd=0x2270cc0, istate=0xffbfcb5c, 
    arguments=<optimized out>, thisarg=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
#18 0x004e22ac in Interpreter::visit(CallExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#19 0x00486cb8 in CallExp::accept (this=0x22ea380, v=0xffbfc2cc)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:878
#20 0x004d05c4 in interpret (pue=0xffbfc344, e=0x22ea380, istate=0xffbfcb5c, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#21 0x004d14e0 in interpret (e=0x22ea380, istate=0xffbfcb5c, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
#22 0x004e33dc in Interpreter::interpretAssignCommon(BinExp*, UnionExp (*)(Loc, Type*, Expression*, Expression*), int) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#23 0x00526d18 in ConstructExp::accept(Visitor*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:672
#24 0x004d05c4 in interpret (pue=0xffbfc5bc, e=0x22ea348, istate=0xffbfcb5c, 
    goal=ctfeNeedNothing)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#25 0x004d14e0 in interpret (e=0x22ea348, istate=0xffbfcb5c, 
    goal=ctfeNeedNothing)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
#26 0x004de01c in Interpreter::visit(DeclarationExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#27 0x005243d8 in DeclarationExp::accept (this=0x2270170, v=0xffbfc79c)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:661
#28 0x004d05c4 in interpret (pue=0xffbfca94, e=0x2270170, istate=0xffbfcb5c, 
    goal=ctfeNeedNothing)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#29 0x004d5ab8 in Interpreter::visit(ExpStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#30 0x005b56d8 in ExpStatement::accept(Visitor*) ()
#31 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#32 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#33 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#34 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#35 0x004d1544 in interpret (istate=<optimized out>, s=<optimized out>, 
    pue=0xffbfca94) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
#36 interpret (s=0x22eabb0, istate=0xffbfcb5c)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
#37 0x004d263c in interpretFunction (thisarg=0x22f6198, 
    arguments=<optimized out>, istate=0xffbfd964, fd=0x226fed8)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
#38 interpretFunction (fd=0x226fed8, istate=0xffbfd964, 
    arguments=<optimized out>, thisarg=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
#39 0x004e22ac in Interpreter::visit(CallExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#40 0x00486cb8 in CallExp::accept (this=0x22ef2b0, v=0xffbfcce4)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:878
#41 0x004d05c4 in interpret (pue=0xffbfcd5c, e=0x22ef2b0, istate=0xffbfd964, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#42 0x004d14e0 in interpret (e=0x22ef2b0, istate=0xffbfd964, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
#43 0x004e33dc in Interpreter::interpretAssignCommon(BinExp*, UnionExp (*)(Loc, Type*, Expression*, Expression*), int) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#44 0x00526d18 in ConstructExp::accept(Visitor*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:672
#45 0x004d05c4 in interpret (pue=0xffbfcfd4, e=0x22ef240, istate=0xffbfd964, 
    goal=ctfeNeedNothing)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#46 0x004d14e0 in interpret (e=0x22ef240, istate=0xffbfd964, 
    goal=ctfeNeedNothing)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
#47 0x004de01c in Interpreter::visit(DeclarationExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#48 0x005243d8 in DeclarationExp::accept (this=0x22eef08, v=0xffbfd1b4)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:661
#49 0x004d05c4 in interpret (pue=0xffbfd89c, e=0x22eef08, istate=0xffbfd964, 
    goal=ctfeNeedNothing)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#50 0x004d5ab8 in Interpreter::visit(ExpStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#51 0x005b56d8 in ExpStatement::accept(Visitor*) ()
#52 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#53 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#54 0x004d6140 in Interpreter::visit(ForStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#55 0x005aec68 in ForStatement::accept(Visitor*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/statement.h:230
#56 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#57 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#58 0x004d4810 in Interpreter::visit(ScopeStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#59 0x005aec08 in ScopeStatement::accept (this=0x22eefa8, v=0xffbfd6dc)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/statement.h:230
#60 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#61 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#62 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#63 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#64 0x004d1544 in interpret (istate=<optimized out>, s=<optimized out>, 
    pue=0xffbfd89c) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
#65 interpret (s=0x22f5f18, istate=0xffbfd964)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
#66 0x004d263c in interpretFunction (thisarg=0x0, arguments=<optimized out>, 
    istate=0xffbfde94, fd=0x226f700)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
#67 interpretFunction (fd=0x226f700, istate=0xffbfde94, 
    arguments=<optimized out>, thisarg=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
#68 0x004e22ac in Interpreter::visit(CallExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#69 0x00486cb8 in CallExp::accept (this=0x226d8e0, v=0xffbfdaec)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:878
#70 0x004d05c4 in interpret (pue=0xffbfddcc, e=0x226d8e0, istate=0xffbfde94, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#71 0x004d6768 in Interpreter::visit(ReturnStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#72 0x005b5abc in ReturnStatement::accept(Visitor*) ()
#73 0x004d475c in Interpreter::visit(CompoundStatement*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#74 0x005b5708 in CompoundStatement::accept(Visitor*) ()
#75 0x004d1544 in interpret (istate=<optimized out>, s=<optimized out>, 
    pue=0xffbfddcc) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
#76 interpret (s=0x22f6000, istate=0xffbfde94)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
#77 0x004d263c in interpretFunction (thisarg=0x0, arguments=<optimized out>, 
    istate=0x0, fd=0x226d458)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
#78 interpretFunction (fd=0x226d458, istate=0x0, arguments=<optimized out>, 
    thisarg=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
#79 0x004e22ac in Interpreter::visit(CallExp*) ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.h:292
#80 0x00486cb8 in CallExp::accept (this=0x2264840, v=0xffbfe01c)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:878
#81 0x004d05c4 in interpret (pue=0xffbfe094, e=0x2264840, istate=0x0, 
    goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
#82 0x004d14e0 in interpret (e=0x2264840, istate=0x0, goal=ctfeNeedRvalue)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
#83 0x004d19d8 in ctfeInterpret (e=0x2264840)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:657
#84 ctfeInterpret (e=0x2264840)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:641
#85 0x00490be8 in Expression::ctfeInterpret (this=<optimized out>)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:205
#86 PragmaDeclaration::semantic (this=0x22648f8, sc=0x2263200)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/attrib.c:1062
#87 0x00490414 in AttribDeclaration::semantic (this=0x22649c8, sc=0x2263200)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/attrib.c:186
#88 0x00502f40 in TemplateInstance::expandMembers (this=this@entry=0x1969bb0, 
    sc2=sc2@entry=0x2263200)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dtemplate.c:5923
#89 0x00502f90 in TemplateInstance::tryExpandMembers (this=0x1969bb0, 
    sc2=0x2263200) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dtemplate.c:5941
#90 0x00508d20 in TemplateInstance::semantic (fargs=0x0, sc=0x2262c48, 
    this=0x1969bb0) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dtemplate.c:6219
#91 TemplateInstance::semantic (this=0x1969bb0, sc=0x2262c48, fargs=0x0)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dtemplate.c:5962
#92 0x00587ab8 in TypeInstance::resolve (this=0x1969fb8, loc=..., 
    sc=0x2262c48, pe=0xffbfe4a0, pt=0xffbfe49c, ps=0xffbfe4a4, intypeid=false)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/mtype.c:7051
#93 0x0057470c in TypeInstance::toDsymbol (this=0x1969fb8, sc=0x2262c48)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/mtype.c:7101
#94 0x004c7a14 in AliasDeclaration::aliasSemantic (this=0x196a020, 
    sc=0x2262c48) at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/declaration.c:401
#95 0x00490414 in AttribDeclaration::semantic (this=0x196ae08, sc=0x193fe38)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/attrib.c:186
#96 0x004e8688 in Module::semantic (this=0x193f6a0)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dmodule.c:822
#97 Module::semantic (this=0x193f6a0)
    at /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dmodule.c:797
#98 0x00601f9c in d_parse_file ()
    at /vol/gcc/src/hg/trunk/local/gcc/d/d-lang.cc:1115
#99 0x00bb5580 in compile_file ()
    at /vol/gcc/src/hg/trunk/local/gcc/toplev.c:455
#100 0x00bb8604 in toplev::main(int, char**) ()
#101 0x0142da50 in main (argc=8, argv=0xffbfe8cc)
    at /vol/gcc/src/hg/trunk/local/gcc/main.c:39

1: x/i $pc
=> 0x518700 <IntegerExp::toInteger()+16>:       ldtw  [ %o0 + 0x20 ], %o0
(gdb) p/x $o0
$1 = 0xffbfba04

It's indeed an unaligned access: the ldtw insn requires 8-byte
alignment, but the source isn't.  gdb misreports the signal as SIGSEGV,
but truss shows SIGBUS with an alignment error:

    Incurred fault #5, FLTACCESS  %pc = 0x00518700
      siginfo: SIGBUS BUS_ADRALN addr=0xFFBFBB24
    Received signal #10, SIGBUS [caught]
      siginfo: SIGBUS BUS_ADRALN addr=0xFFBFBB24

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Iain Buclaw Oct. 30, 2018, 5:43 p.m. | #2
On Tue, 30 Oct 2018 at 14:13, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>

> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

>

> > * On sparc, I didn't get that far, unfortunately: as I mentioned, many

> >   compilations die with SIGBUS:

> >

> > libtool: compile:  /var/gcc/regression/trunk/11.5-gcc/build/./gcc/gdc -B/var/gcc/regression/trunk/11.5-gcc/build/./gcc/ -B/vol/gcc/sparc-sun-solaris2.11/bin/ -B/vol/gcc/sparc-sun-solaris2.11/lib/ -isystem /vol/gcc/sparc-sun-solaris2.11/include -isystem /vol/gcc/sparc-sun-solaris2.11/sys-include -fno-checking -fPIC -O2 -g -nostdinc -I /vol/gcc/src/hg/trunk/local/libphobos/libdruntime -I . -c /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d -fversion=Shared -o core/.libs/thread.o

> > d21: internal compiler error: Bus Error

> > 0xbb5507 crash_signal

> >         /vol/gcc/src/hg/trunk/local/gcc/toplev.c:325

> > 0x518700 IntegerExp::toInteger()

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.c:2943

> > 0x4d05c3 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> > 0x4d1543 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017

> > 0x4d1543 interpret(Statement*, InterState*)

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024

> > 0x4d263b interpretFunction

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906

> > 0x4d263b interpretFunction

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726

> > 0x4d05c3 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> > 0x4d14df interpret(Expression*, InterState*, CtfeGoal)

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994

> > 0x4d05c3 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> > 0x4d14df interpret(Expression*, InterState*, CtfeGoal)

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994

> > 0x5243d7 DeclarationExp::accept(Visitor*)

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:661

> > 0x4d05c3 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> > 0x4d1543 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017

> > 0x4d1543 interpret(Statement*, InterState*)

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024

> > 0x4d263b interpretFunction

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906

> > 0x4d263b interpretFunction

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726

> > 0x4d05c3 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> > 0x4d14df interpret(Expression*, InterState*, CtfeGoal)

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994

> > 0x4d05c3 interpret

> >         /vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984

> >

> >   Will need to dig further here.

>

> It's exactly as I suspected:

>

> $ d21 /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d -mcpu=v9 -fversion=Shared -I /vol/gcc/src/hg/trunk/local/libphobos/libdruntime -o thread.s

>


Hi Rainer,

Thanks for looking into this.

My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

Upstream dmd use a poor man's alignment, from what I recall to be
compatible with the dmc compiler.

        // Ensure that the union is suitably aligned.
        real_t for_alignment_only;

What happens if you were to replace that with marking the type as
__attribute__ ((aligned (8))) ?

-- 
Iain
Rainer Orth Oct. 31, 2018, 9:40 a.m. | #3
Hi Iain,

> My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

>

> Upstream dmd use a poor man's alignment, from what I recall to be

> compatible with the dmc compiler.

>

>         // Ensure that the union is suitably aligned.

>         real_t for_alignment_only;

>

> What happens if you were to replace that with marking the type as

> __attribute__ ((aligned (8))) ?


thanks for the suggestion: this worked just fine.  After a couple more
libphobos adjustments (described below), I was able to finish the build
on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

The link tests still all fail as before, but sparc and x86 are now on
par here :-)

Here are the new issues I saw while completing the sparc build:

* math.d has two problems on 32-bit sparc:

/vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5278:18: error: undefined identifier 'ControlState'
 5278 |     ControlState savedState;
      |                  ^
/vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5325:25: error: undefined identifier 'ControlState'
 5325 |     static ControlState getControlState() @trusted nothrow @nogc
      |                         ^
/vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5390:17: error: undefined identifier 'ControlState'
 5390 |     static void setControlState(ControlState newState) @trusted nothrow @nogc
      |                 ^

  Fixed by using the ControlState alias on both SPARC64 and SPARC.

/vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5211:9: error: static assert  "Not implemented for this architecture"
 5211 |         static assert(false, "Not implemented for this architecture");
      |         ^

  Similarly, ExceptionMask was only defined for SPARC64.  However,
  looking closer it seems that the current definition only matches Linux
  resp. Glibc fenv.h (FE_*).  The Solaris values are different on sparc.

  This seems to be a recurring theme, unfortunately: definitions guarded
  by version ($CPU) are really CRuntime_Glibc && $CPU.  I fear libphobos
  has to be way more careful to distinguish between definitions that
  only depend on the target cpu and those that are (also) OS-dependent.

  Instead of hardcoding all this, it may be worth having a look at how
  Go handles this: they dump the definitions with gcc
  -fdump-go-spec=tmp-gen-sysinfo.go and postprocess them in
  libgo/mksysinfo.sh.  This way, such errors and potential
  inconsistencies are avoided from the start.  This would also massivly
  simplify work for potential porters.

* My previous patch had a typo, now also fixed:

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:984:20: error: undefined identifier 'uint32_t'
  984 |       uint32_t[32] fpu_regs;
      |                    ^

While those were enough to finish the build, I noticed a couple of
additional issues:

* During make check, part (or all) of libphobos was rebuilt.  I strongly
  suspect that this happens because contrib/gcc_update doesn't handle
  libphobos yet: it needs to touch generated files to avoid exactly this
  sort of problem.  I'll post a separate patch once tested.

* Unlike the gdc.dg tests, many gdc.test tests appear as UNRESOLVED like
  this:

UNRESOLVED: runnable/A16.d   compilation failed to produce executable

  There's no preceding FAIL for the link failure itself.  Besides, the
  testname needs to include the gdc.test prefix.

* One issue I forgot last time: when defining the SPARC64 struct
  fpregset_t in libdruntime/core/sys/posix/ucontext.d, one field
  couldn't be represented: the structure contains a union

	    union fpu_fr
	    {
	    	uint[32]	fpu_regs;
		double[32]	fpu_dregs;
		/* long double[16]	fpu_qregs; */

  but there's no D type corresponding to long double: the D real type
  represents the biggest floating-point type implemented in hardware,
  and AFAIK no SPARC CPU ever implemented 128-bit floating point.
  Still, with this missing the alignment of the union is wrong.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Rainer Orth Oct. 31, 2018, 9:43 a.m. | #4
Hi Iain,

>> My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

>>

>> Upstream dmd use a poor man's alignment, from what I recall to be

>> compatible with the dmc compiler.

>>

>>         // Ensure that the union is suitably aligned.

>>         real_t for_alignment_only;

>>

>> What happens if you were to replace that with marking the type as

>> __attribute__ ((aligned (8))) ?

>

> thanks for the suggestion: this worked just fine.  After a couple more

> libphobos adjustments (described below), I was able to finish the build

> on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>

> The link tests still all fail as before, but sparc and x86 are now on

> par here :-)


and now with the updated patch ;-)

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2018-10-29  Iain Buclaw  <ibuclaw@gdcproject.org>

	gcc/d:
	* dmd/expression.h (UnionExp.u): Remove for_alignment_only.
	Force 8-byte alignment.

2018-10-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config/default-d.c: Include memmodel.h.

	* config/sol2-d.c: New file.
	* config/t-sol2 (sol2-d.o): New rule.
	* config.gcc <*-*-solaris2*>: Set d_target_objs,
	target_has_targetdm.

	libphobos:
	* libdruntime/core/stdc/fenv.d [SPARC, SPARC64]: Set SPARC_Any.
	[X86, X86_64]: Set X86_Any.
	[Solaris]: Provide FE_* constants.
	* libdruntime/core/sys/posix/aio.d [Solaris] (struct aio_result,
	struct aiocb): New types.
	* libdruntime/core/sys/posix/ucontext.d [SPARC64, SPARC] (_NGREG,
	greg_t): Define.
	[SPARC64, SPARC] (struct _fpq, struct fq, struct fpregset_t): New
	types.
	* libdruntime/core/thread.d (Class Thread) [Solaris]
	(m_isRTClass): Don't declare immutable.
	* libdruntime/rt/sections_solaris.d (SectionGroup.moduleGroup):
	Declare nothrow @nogc.
	(pinLoadedLibraries, unpinLoadedLibraries, inheritLoadedLibraries)
	(cleanupLoadedLibraries): New functions.
	* src/std/datetime/systime.d (class Clock) [Solaris]
	(clock_gettime): Import.
	* src/std/math.d [SPARC, SPARC64]: Set SPARC_Any.
	(struct FloatingPointControl): Use SPARC_Any for ExceptionMask,
	ControlState.
# HG changeset patch
# Parent  feb1bc98079b57185692621c744578b658d1fc1a
Fix D compilation on Solaris

diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -918,6 +918,7 @@ case ${target} in
   target_gtfiles="$target_gtfiles \$(srcdir)/config/sol2.c"
   c_target_objs="${c_target_objs} sol2-c.o"
   cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o"
+  d_target_objs="${d_target_objs} sol2-d.o"
   extra_objs="${extra_objs} sol2.o sol2-stubs.o"
   extra_options="${extra_options} sol2.opt"
   case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
@@ -925,6 +926,7 @@ case ${target} in
       thread_file=posix
       ;;
   esac
+  target_has_targetdm=yes
   ;;
 *-*-*vms*)
   extra_options="${extra_options} vms/vms.opt"
diff --git a/gcc/config/default-d.c b/gcc/config/default-d.c
--- a/gcc/config/default-d.c
+++ b/gcc/config/default-d.c
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.  
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "memmodel.h"
 #include "tm_d.h"
 #include "d/d-target.h"
 #include "d/d-target-def.h"
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
new file mode 100644
--- /dev/null
+++ b/gcc/config/sol2-d.c
@@ -0,0 +1,39 @@
+/* Solaris support needed only by D front-end.
+   Copyright (C) 2018 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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Solaris targets.  */
+
+static void
+solaris_d_os_builtins (void)
+{
+  d_add_builtin_version ("Posix");
+  d_add_builtin_version ("Solaris");			\
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -16,7 +16,7 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-# Solaris-specific format checking and pragmas
+# Solaris-specific format checking and pragmas.
 sol2-c.o: $(srcdir)/config/sol2-c.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
@@ -26,6 +26,11 @@ sol2-cxx.o: $(srcdir)/config/sol2-cxx.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+# Solaris-specific D support.
+sol2-d.o: $(srcdir)/config/sol2-d.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 # Corresponding stub routines.
 sol2-stubs.o: $(srcdir)/config/sol2-stubs.c
 	$(COMPILE) $<
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -1507,10 +1507,7 @@ private:
         char addrexp   [sizeof(AddrExp)];
         char indexexp  [sizeof(IndexExp)];
         char sliceexp  [sizeof(SliceExp)];
-
-        // Ensure that the union is suitably aligned.
-        real_t for_alignment_only;
-    } u;
+    } u __attribute__ ((aligned (8)));
 };
 
 /****************************************************************/
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -33,6 +33,16 @@ version (PPC)
 else version (PPC64)
     version = PPC_Any;
 
+version (SPARC)
+    version = SPARC_Any;
+version (SPARC64)
+    version = SPARC_Any;
+
+version (X86)
+    version = X86_Any;
+version (X86_64)
+    version = X86_Any;
+
 version (MinGW)
     version = GNUFP;
 version (CRuntime_Glibc)
@@ -451,6 +461,50 @@ version (CRuntime_Microsoft)
         FE_TOWARDZERO   = 0x300, ///
     }
 }
+else version (Solaris)
+{
+	version (SPARC_Any)
+	{
+	    enum
+	    {
+		FE_TONEAREST    = 0,
+		FE_TOWARDZERO   = 1,
+		FE_UPWARD       = 2,
+		FE_DOWNWARD     = 3,
+	    }
+
+	    enum
+	    {
+		FE_INEXACT      = 0x01,
+		FE_DIVBYZERO    = 0x02,
+		FE_UNDERFLOW    = 0x04,
+		FE_OVERFLOW     = 0x08,
+		FE_INVALID      = 0x10,
+		FE_ALL_EXCEPT   = 0x1f,
+	    }
+
+	}
+	else version (X86_Any)
+	{
+	    enum
+	    {
+		FE_TONEAREST    = 0,
+		FE_DOWNWARD     = 1,
+		FE_UPWARD       = 2,
+		FE_TOWARDZERO   = 3,
+	    }
+
+	    enum
+	    {
+		FE_INVALID      = 0x01,
+		FE_DIVBYZERO    = 0x04,
+		FE_OVERFLOW     = 0x08,
+		FE_UNDERFLOW    = 0x10,
+		FE_INEXACT      = 0x20,
+		FE_ALL_EXCEPT   = 0x3d,
+	    }
+	}
+}
 else
 {
     version (X86)
diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d
--- a/libphobos/libdruntime/core/sys/posix/aio.d
+++ b/libphobos/libdruntime/core/sys/posix/aio.d
@@ -123,6 +123,32 @@ else version (DragonFlyBSD)
 
     version = BSD_Posix;
 }
+else version (Solaris)
+{
+    struct aio_result_t
+    {
+	ssize_t aio_return;
+	int aio_errno;
+    };
+
+    struct aiocb
+    {
+        int aio_fildes;
+        void* aio_buf;   // volatile
+        size_t aio_nbytes;
+        off_t aio_offset;
+	int aio_reqprio;
+        sigevent aio_sigevent;
+        int aio_lio_opcode;
+	aio_result_t aio_result;
+	byte aio_state;
+	byte aio_returned;
+	byte[2] aio__pad1;
+	int aio_flags;
+    }
+
+    version = BSD_Posix;
+}
 else
     static assert(false, "Unsupported platform");
 
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -937,7 +937,17 @@ else version (Solaris)
 {
     alias uint[4] upad128_t;
 
-    version (X86_64)
+    version (SPARC64)
+    {
+        enum _NGREG = 21;
+        alias long greg_t;
+    }
+    else version (SPARC)
+    {
+        enum _NGREG = 19;
+        alias int greg_t;
+    }
+    else version (X86_64)
     {
         enum _NGREG = 28;
         alias long greg_t;
@@ -950,7 +960,70 @@ else version (Solaris)
 
     alias greg_t[_NGREG] gregset_t;
 
-    version (X86_64)
+    version (SPARC64)
+    {
+	struct _fpq
+	{
+	    uint *fpq_addr;
+	    uint fpq_instr;
+	}
+
+	struct fq
+	{
+	    union FQu
+	    {
+		double whole;
+		_fpq fpq;
+	    };
+	}
+
+        struct fpregset_t
+	{
+	    union fpu_fr
+	    {
+	    	uint[32]	fpu_regs;
+		double[32]	fpu_dregs;
+		/* long double[16]	fpu_qregs; */
+	    };
+	    fq		*fpu_q;
+	    ulong	fpu_fsr;
+	    ubyte	fpu_qcnt;
+	    ubyte	fpu_q_entrysize;
+	    ubyte	fpu_en;
+	}
+    }
+    else version (SPARC)
+    {
+	struct _fpq
+	{
+	    uint *fpq_addr;
+	    uint fpq_instr;
+	}
+
+	struct fq
+	{
+	    union FQu
+	    {
+		double whole;
+		_fpq fpq;
+	    };
+	}
+
+	struct fpregset_t
+	{
+	    union
+	    {
+		uint[32]	fpu_regs;
+		double[16]	fpu_dregs;
+	    };
+	    fq		*fpu_q;
+	    uint	fpu_fsr;
+	    ubyte	fpu_qcnt;
+	    ubyte	fpu_q_entrysize;
+	    ubyte	fpu_en;
+	}
+    }
+    else version (X86_64)
     {
         union _u_st
         {
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -1547,7 +1547,7 @@ private:
 
     version (Solaris)
     {
-        __gshared immutable bool m_isRTClass;
+        __gshared bool m_isRTClass;
     }
 
 private:
diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/rt/sections_solaris.d
--- a/libphobos/libdruntime/rt/sections_solaris.d
+++ b/libphobos/libdruntime/rt/sections_solaris.d
@@ -34,7 +34,7 @@ struct SectionGroup
         return _moduleGroup.modules;
     }
 
-    @property ref inout(ModuleGroup) moduleGroup() inout
+    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
     {
         return _moduleGroup;
     }
@@ -87,6 +87,24 @@ void scanTLSRanges(void[] rng, scope voi
     dg(rng.ptr, rng.ptr + rng.length);
 }
 
+// interface for core.thread to inherit loaded libraries
+void* pinLoadedLibraries() nothrow @nogc
+{
+    return null;
+}
+
+void unpinLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void inheritLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void cleanupLoadedLibraries() nothrow @nogc
+{
+}
+
 private:
 
 __gshared SectionGroup _sections;
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -221,6 +221,7 @@ public:
                 else
                 {
                     import core.sys.solaris.time : CLOCK_REALTIME;
+                    import core.sys.posix.time : clock_gettime;
                     static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME;
                     else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;
                     else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -160,6 +160,8 @@ version (MIPS32)    version = MIPS_Any;
 version (MIPS64)    version = MIPS_Any;
 version (AArch64)   version = ARM_Any;
 version (ARM)       version = ARM_Any;
+version (SPARC)     version = SPARC_Any;
+version (SPARC64)   version = SPARC_Any;
 
 version (D_InlineAsm_X86)
 {
@@ -5161,7 +5163,7 @@ struct FloatingPointControl
                                  | inexactException,
         }
     }
-    else version (SPARC64)
+    else version (SPARC_Any)
     {
         enum : ExceptionMask
         {
@@ -5291,7 +5293,7 @@ private:
     {
         alias ControlState = uint;
     }
-    else version (SPARC64)
+    else version (SPARC_Any)
     {
         alias ControlState = ulong;
     }
Iain Buclaw Oct. 31, 2018, 4:54 p.m. | #5
On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>

> Hi Iain,

>

> > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

> >

> > Upstream dmd use a poor man's alignment, from what I recall to be

> > compatible with the dmc compiler.

> >

> >         // Ensure that the union is suitably aligned.

> >         real_t for_alignment_only;

> >

> > What happens if you were to replace that with marking the type as

> > __attribute__ ((aligned (8))) ?

>

> thanks for the suggestion: this worked just fine.  After a couple more

> libphobos adjustments (described below), I was able to finish the build

> on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>

> The link tests still all fail as before, but sparc and x86 are now on

> par here :-)

>

> Here are the new issues I saw while completing the sparc build:

>

> * math.d has two problems on 32-bit sparc:

>

> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5278:18: error: undefined identifier 'ControlState'

>  5278 |     ControlState savedState;

>       |                  ^

> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5325:25: error: undefined identifier 'ControlState'

>  5325 |     static ControlState getControlState() @trusted nothrow @nogc

>       |                         ^

> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5390:17: error: undefined identifier 'ControlState'

>  5390 |     static void setControlState(ControlState newState) @trusted nothrow @nogc

>       |                 ^

>

>   Fixed by using the ControlState alias on both SPARC64 and SPARC.

>

> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5211:9: error: static assert  "Not implemented for this architecture"

>  5211 |         static assert(false, "Not implemented for this architecture");

>       |         ^

>

>   Similarly, ExceptionMask was only defined for SPARC64.  However,

>   looking closer it seems that the current definition only matches Linux

>   resp. Glibc fenv.h (FE_*).  The Solaris values are different on sparc.

>

>   This seems to be a recurring theme, unfortunately: definitions guarded

>   by version ($CPU) are really CRuntime_Glibc && $CPU.  I fear libphobos

>   has to be way more careful to distinguish between definitions that

>   only depend on the target cpu and those that are (also) OS-dependent.

>


The phobos part is largely free of version (CPU), the druntime
bindings are in a little better shape, despite there being a lot of
places dotted around the place that need to be checked.

>   Instead of hardcoding all this, it may be worth having a look at how

>   Go handles this: they dump the definitions with gcc

>   -fdump-go-spec=tmp-gen-sysinfo.go and postprocess them in

>   libgo/mksysinfo.sh.  This way, such errors and potential

>   inconsistencies are avoided from the start.  This would also massivly

>   simplify work for potential porters.

>


You mean a tool such as htod (header to D)?  I don't think that has
ever gained traction in upstream.

The existing C bindings for sure are brittle, and never take into
account changes between versions (FreeBSD comes to mind), but for new
ports, it at least tries to be consistent in that unhandled places
always end with a 'static assert (false)' compiler error.  If I was
just to defend the current status quo a little.

> * My previous patch had a typo, now also fixed:

>

> /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:984:20: error: undefined identifier 'uint32_t'

>   984 |       uint32_t[32] fpu_regs;

>       |                    ^

>

> While those were enough to finish the build, I noticed a couple of

> additional issues:

>

> * During make check, part (or all) of libphobos was rebuilt.  I strongly

>   suspect that this happens because contrib/gcc_update doesn't handle

>   libphobos yet: it needs to touch generated files to avoid exactly this

>   sort of problem.  I'll post a separate patch once tested.

>

> * Unlike the gdc.dg tests, many gdc.test tests appear as UNRESOLVED like

>   this:

>

> UNRESOLVED: runnable/A16.d   compilation failed to produce executable

>

>   There's no preceding FAIL for the link failure itself.  Besides, the

>   testname needs to include the gdc.test prefix.

>

> * One issue I forgot last time: when defining the SPARC64 struct

>   fpregset_t in libdruntime/core/sys/posix/ucontext.d, one field

>   couldn't be represented: the structure contains a union

>

>             union fpu_fr

>             {

>                 uint[32]        fpu_regs;

>                 double[32]      fpu_dregs;

>                 /* long double[16]      fpu_qregs; */

>

>   but there's no D type corresponding to long double: the D real type

>   represents the biggest floating-point type implemented in hardware,

>   and AFAIK no SPARC CPU ever implemented 128-bit floating point.

>   Still, with this missing the alignment of the union is wrong.

>


In practice however, the 'real' type maps to C 'long double', so you
can safely use real[16] here.

-- 
Iain
Iain Buclaw Oct. 31, 2018, 5:34 p.m. | #6
On Wed, 31 Oct 2018 at 10:43, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>

> Hi Iain,

>

> >> My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

> >>

> >> Upstream dmd use a poor man's alignment, from what I recall to be

> >> compatible with the dmc compiler.

> >>

> >>         // Ensure that the union is suitably aligned.

> >>         real_t for_alignment_only;

> >>

> >> What happens if you were to replace that with marking the type as

> >> __attribute__ ((aligned (8))) ?

> >

> > thanks for the suggestion: this worked just fine.  After a couple more

> > libphobos adjustments (described below), I was able to finish the build

> > on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

> >

> > The link tests still all fail as before, but sparc and x86 are now on

> > par here :-)

>

> and now with the updated patch ;-)

>


Thanks, the front-end and library parts should be posted upstream.

Mapping would be:
- d/dmd: https://github.com/dlang/dmd/tree/dmd-cxx
- libdruntime/core: https://github.com/dlang/druntime
- libphobos/src/std: https://github.com/dlang/phobos

I can take care of this, then backport/merge it down here.

As for the patch itself:

> --- a/gcc/config/default-d.c

> +++ b/gcc/config/default-d.c

> @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.

>  #include "config.h"

>  #include "system.h"

>  #include "coretypes.h"

> +#include "memmodel.h"

>  #include "tm_d.h"

>  #include "d/d-target.h"

>  #include "d/d-target-def.h"


Is this still required?  For sure it would cover non-glibc,
non-solaris sparc targets though.

> diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c

> new file mode 100644

> --- /dev/null

> +++ b/gcc/config/sol2-d.c


[-- snip --]

> +solaris_d_os_builtins (void)

> +{

> +  d_add_builtin_version ("Posix");

> +  d_add_builtin_version ("Solaris"); \

> +}

> +


I'll assume that backslash is a typo.

You'll also need to add this target hook:

    /* Implement TARGET_D_CRITSEC_SIZE for Solaris targets.  */

    static unsigned
    solaris_d_critsec_size (void)
    {
      /* This is the sizeof pthread_mutex_t.  */
      return 24;
    }

I hope that pthread_mutex_t does not differ between x86 and SPARC.

> diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2

> --- a/gcc/config/t-sol2

> +++ b/gcc/config/t-sol2

> @@ -16,7 +16,7 @@

>  # along with GCC; see the file COPYING3.  If not see

>  # <http://www.gnu.org/licenses/>.

>

> -# Solaris-specific format checking and pragmas

> +# Solaris-specific format checking and pragmas.

>  sol2-c.o: $(srcdir)/config/sol2-c.c

>  $(COMPILE) $<

>  $(POSTCOMPILE)


Not sure what the policy is about mixing unrelated changes in a patch here.

> diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d

> --- a/libphobos/libdruntime/core/sys/posix/ucontext.d

> +++ b/libphobos/libdruntime/core/sys/posix/ucontext.d


[-- snip --]

> + struct fq

> + {

> +     union FQu

> +     {

> + double whole;

> + _fpq fpq;

> +     };

> + }


Just an FYI, this won't do what I think you expect, 'struct fq' here
would be an empty struct.  Better make this an anonymous union, I can
see the same mistake done elsewhere.

struct fq
{
    union
    {
        double whole;
        _fpq fpq;
    }
}

> diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d

> --- a/libphobos/libdruntime/core/thread.d

> +++ b/libphobos/libdruntime/core/thread.d

> @@ -1547,7 +1547,7 @@ private:

>

>      version (Solaris)

>      {

> -        __gshared immutable bool m_isRTClass;

> +        __gshared bool m_isRTClass;

>      }

>

>  private:


This is curious, I wonder when was the last time someone tested x86
Solaris in upstream.  What was the compilation error?

> diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/rt/sections_solaris.d

> --- a/libphobos/libdruntime/rt/sections_solaris.d

> +++ b/libphobos/libdruntime/rt/sections_solaris.d


[-- snip --]

>

> +// interface for core.thread to inherit loaded libraries

> +void* pinLoadedLibraries() nothrow @nogc

> +{

> +    return null;

> +}

> +


I ran into this on OSX as well.  The problem lies elsewhere, and I'm
going to fix this.  The shared library is being built with
'-fversion=Shared', but this is only valid for targets that use
rt/sections_elf_shared.d

I suspect that Solaris/SPARC should be using the ELF sections support anyway.

Apart from comments, the GCC parts look OK to me.  Unless you want to
raise a pull request, I'll submit the library patches upstream later.

Thanks!
Iain
Iain Buclaw Nov. 3, 2018, 10:23 p.m. | #7
On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>

> Hi Iain,

>

> > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

> >

> > Upstream dmd use a poor man's alignment, from what I recall to be

> > compatible with the dmc compiler.

> >

> >         // Ensure that the union is suitably aligned.

> >         real_t for_alignment_only;

> >

> > What happens if you were to replace that with marking the type as

> > __attribute__ ((aligned (8))) ?

>

> thanks for the suggestion: this worked just fine.  After a couple more

> libphobos adjustments (described below), I was able to finish the build

> on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>

> The link tests still all fail as before, but sparc and x86 are now on

> par here :-)

>


Hi Rainer,

On making the relevant change to dmd, this header probably should
remain compatible with dmc++, which unfortunately doesn't implement
any __attribute__ extensions.  Does s/real_t/long double/ also prevent
the alignment error from occurring?

Iain.
Iain Buclaw Nov. 4, 2018, 12:08 a.m. | #8
On Sat, 3 Nov 2018 at 23:23, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
>

> On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:

> >

> > Hi Iain,

> >

> > > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

> > >

> > > Upstream dmd use a poor man's alignment, from what I recall to be

> > > compatible with the dmc compiler.

> > >

> > >         // Ensure that the union is suitably aligned.

> > >         real_t for_alignment_only;

> > >

> > > What happens if you were to replace that with marking the type as

> > > __attribute__ ((aligned (8))) ?

> >

> > thanks for the suggestion: this worked just fine.  After a couple more

> > libphobos adjustments (described below), I was able to finish the build

> > on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

> >

> > The link tests still all fail as before, but sparc and x86 are now on

> > par here :-)

> >

>

> Hi Rainer,

>

> On making the relevant change to dmd, this header probably should

> remain compatible with dmc++, which unfortunately doesn't implement

> any __attribute__ extensions.  Does s/real_t/long double/ also prevent

> the alignment error from occurring?

>


Actually, turns out I'm wrong and was grepping for the wrong name.

It is supported in the form of #pragma pack(8)

https://www.digitalmars.com/ctg/pragmas.html#pack

-- 
Iain
Rainer Orth Nov. 4, 2018, 4:46 p.m. | #9
Hi Iain,

> On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:

>>

>> Hi Iain,

>>

>> > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

>> >

>> > Upstream dmd use a poor man's alignment, from what I recall to be

>> > compatible with the dmc compiler.

>> >

>> >         // Ensure that the union is suitably aligned.

>> >         real_t for_alignment_only;

>> >

>> > What happens if you were to replace that with marking the type as

>> > __attribute__ ((aligned (8))) ?

>>

>> thanks for the suggestion: this worked just fine.  After a couple more

>> libphobos adjustments (described below), I was able to finish the build

>> on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>>

>> The link tests still all fail as before, but sparc and x86 are now on

>> par here :-)

>>

>> Here are the new issues I saw while completing the sparc build:

>>

>> * math.d has two problems on 32-bit sparc:

>>

>> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5278:18: error:

>> undefined identifier 'ControlState'

>>  5278 |     ControlState savedState;

>>       |                  ^

>> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5325:25: error:

>> undefined identifier 'ControlState'

>>  5325 |     static ControlState getControlState() @trusted nothrow @nogc

>>       |                         ^

>> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5390:17: error:

>> undefined identifier 'ControlState'

>>  5390 | static void setControlState(ControlState newState) @trusted

>> nothrow @nogc

>>       |                 ^

>>

>>   Fixed by using the ControlState alias on both SPARC64 and SPARC.

>>

>> /vol/gcc/src/hg/trunk/local/libphobos/src/std/math.d:5211:9: error: static assert  "Not implemented for this architecture"

>>  5211 |         static assert(false, "Not implemented for this architecture");

>>       |         ^

>>

>>   Similarly, ExceptionMask was only defined for SPARC64.  However,

>>   looking closer it seems that the current definition only matches Linux

>>   resp. Glibc fenv.h (FE_*).  The Solaris values are different on sparc.

>>

>>   This seems to be a recurring theme, unfortunately: definitions guarded

>>   by version ($CPU) are really CRuntime_Glibc && $CPU.  I fear libphobos

>>   has to be way more careful to distinguish between definitions that

>>   only depend on the target cpu and those that are (also) OS-dependent.

>>

>

> The phobos part is largely free of version (CPU), the druntime

> bindings are in a little better shape, despite there being a lot of

> places dotted around the place that need to be checked.

>

>>   Instead of hardcoding all this, it may be worth having a look at how

>>   Go handles this: they dump the definitions with gcc

>>   -fdump-go-spec=tmp-gen-sysinfo.go and postprocess them in

>>   libgo/mksysinfo.sh.  This way, such errors and potential

>>   inconsistencies are avoided from the start.  This would also massivly

>>   simplify work for potential porters.

>>

>

> You mean a tool such as htod (header to D)?  I don't think that has

> ever gained traction in upstream.


that's a pity.  It certainly would simplify things...

> The existing C bindings for sure are brittle, and never take into

> account changes between versions (FreeBSD comes to mind), but for new

> ports, it at least tries to be consistent in that unhandled places

> always end with a 'static assert (false)' compiler error.  If I was

> just to defend the current status quo a little.


I see.  Types and interfaces changing between versions can certainly be
a problem.  However, Solaris is usually very careful not to make
incompatible changes.

>> * My previous patch had a typo, now also fixed:

>>

>> /vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:984:20:

>> error: undefined identifier 'uint32_t'

>>   984 |       uint32_t[32] fpu_regs;

>>       |                    ^

>>

>> While those were enough to finish the build, I noticed a couple of

>> additional issues:

>>

>> * During make check, part (or all) of libphobos was rebuilt.  I strongly

>>   suspect that this happens because contrib/gcc_update doesn't handle

>>   libphobos yet: it needs to touch generated files to avoid exactly this

>>   sort of problem.  I'll post a separate patch once tested.

>>

>> * Unlike the gdc.dg tests, many gdc.test tests appear as UNRESOLVED like

>>   this:

>>

>> UNRESOLVED: runnable/A16.d   compilation failed to produce executable

>>

>>   There's no preceding FAIL for the link failure itself.  Besides, the

>>   testname needs to include the gdc.test prefix.

>>

>> * One issue I forgot last time: when defining the SPARC64 struct

>>   fpregset_t in libdruntime/core/sys/posix/ucontext.d, one field

>>   couldn't be represented: the structure contains a union

>>

>>             union fpu_fr

>>             {

>>                 uint[32]        fpu_regs;

>>                 double[32]      fpu_dregs;

>>                 /* long double[16]      fpu_qregs; */

>>

>>   but there's no D type corresponding to long double: the D real type

>>   represents the biggest floating-point type implemented in hardware,

>>   and AFAIK no SPARC CPU ever implemented 128-bit floating point.

>>   Still, with this missing the alignment of the union is wrong.

>>

>

> In practice however, the 'real' type maps to C 'long double', so you

> can safely use real[16] here.


Fine, that's what I did in the updated patch.

Thanks.
	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Rainer Orth Nov. 4, 2018, 4:47 p.m. | #10
Hi Iain,

> On Wed, 31 Oct 2018 at 10:43, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:

>>

>> Hi Iain,

>>

>> >> My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

>> >>

>> >> Upstream dmd use a poor man's alignment, from what I recall to be

>> >> compatible with the dmc compiler.

>> >>

>> >>         // Ensure that the union is suitably aligned.

>> >>         real_t for_alignment_only;

>> >>

>> >> What happens if you were to replace that with marking the type as

>> >> __attribute__ ((aligned (8))) ?

>> >

>> > thanks for the suggestion: this worked just fine.  After a couple more

>> > libphobos adjustments (described below), I was able to finish the build

>> > on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>> >

>> > The link tests still all fail as before, but sparc and x86 are now on

>> > par here :-)

>>

>> and now with the updated patch ;-)

>>

>

> Thanks, the front-end and library parts should be posted upstream.

>

> Mapping would be:

> - d/dmd: https://github.com/dlang/dmd/tree/dmd-cxx

> - libdruntime/core: https://github.com/dlang/druntime

> - libphobos/src/std: https://github.com/dlang/phobos

>

> I can take care of this, then backport/merge it down here.


that would be great.  I'd like to avoid becoming involved in the
procedures of too many upstream projects if possible.  The way Ian
handles my Solaris Go changes is very convenient for me ;-)

> As for the patch itself:

>

>> --- a/gcc/config/default-d.c

>> +++ b/gcc/config/default-d.c

>> @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.

>>  #include "config.h"

>>  #include "system.h"

>>  #include "coretypes.h"

>> +#include "memmodel.h"

>>  #include "tm_d.h"

>>  #include "d/d-target.h"

>>  #include "d/d-target-def.h"

>

> Is this still required?  For sure it would cover non-glibc,

> non-solaris sparc targets though.


There are other *-protos.h files using enum memmodel beside sparc:
alpha, ia64, and tilegx.  This may or may not be a reason to keep the
include.

>> diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c

>> new file mode 100644

>> --- /dev/null

>> +++ b/gcc/config/sol2-d.c

>

> [-- snip --]

>

>> +solaris_d_os_builtins (void)

>> +{

>> +  d_add_builtin_version ("Posix");

>> +  d_add_builtin_version ("Solaris"); \

>> +}

>> +

>

> I'll assume that backslash is a typo.

>

> You'll also need to add this target hook:

>

>     /* Implement TARGET_D_CRITSEC_SIZE for Solaris targets.  */

>

>     static unsigned

>     solaris_d_critsec_size (void)

>     {

>       /* This is the sizeof pthread_mutex_t.  */

>       return 24;

>     }

>

> I hope that pthread_mutex_t does not differ between x86 and SPARC.


I saw it in glibc-d.c, but initially thought it were Linux-only in some
way.  Fortunately, pthread_mutex_t is identical between sparc and x86,
32 and 64-bit on Solaris.  Added to the updated patch.

>> diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2

>> --- a/gcc/config/t-sol2

>> +++ b/gcc/config/t-sol2

>> @@ -16,7 +16,7 @@

>>  # along with GCC; see the file COPYING3.  If not see

>>  # <http://www.gnu.org/licenses/>.

>>

>> -# Solaris-specific format checking and pragmas

>> +# Solaris-specific format checking and pragmas.

>>  sol2-c.o: $(srcdir)/config/sol2-c.c

>>  $(COMPILE) $<

>>  $(POSTCOMPILE)

>

> Not sure what the policy is about mixing unrelated changes in a patch here.


In general, they are frowned upon ;-)  However, in this case for a
single-character comment change in code I maintain, I believe it would
be overkill to move it to a separate check-in.

>> diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d

>> b/libphobos/libdruntime/core/sys/posix/ucontext.d

>> --- a/libphobos/libdruntime/core/sys/posix/ucontext.d

>> +++ b/libphobos/libdruntime/core/sys/posix/ucontext.d

>

> [-- snip --]

>

>> + struct fq

>> + {

>> +     union FQu

>> +     {

>> + double whole;

>> + _fpq fpq;

>> +     };

>> + }

>

> Just an FYI, this won't do what I think you expect, 'struct fq' here

> would be an empty struct.  Better make this an anonymous union, I can

> see the same mistake done elsewhere.

>

> struct fq

> {

>     union

>     {

>         double whole;

>         _fpq fpq;

>     }

> }


Thanks, all instances fixed, I hope.

>> diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d

>> --- a/libphobos/libdruntime/core/thread.d

>> +++ b/libphobos/libdruntime/core/thread.d

>> @@ -1547,7 +1547,7 @@ private:

>>

>>      version (Solaris)

>>      {

>> -        __gshared immutable bool m_isRTClass;

>> +        __gshared bool m_isRTClass;

>>      }

>>

>>  private:

>

> This is curious, I wonder when was the last time someone tested x86

> Solaris in upstream.  What was the compilation error?


I got

/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d:989:21: error: cannot modify immutable expression m_isRTClass
  989 |                     m_isRTClass = true;
      |                     ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d:997:21: error: cannot modify immutable expression m_isRTClass
  997 |                     m_isRTClass = false;
      |                     ^

>> diff --git a/libphobos/libdruntime/rt/sections_solaris.d

>> b/libphobos/libdruntime/rt/sections_solaris.d

>> --- a/libphobos/libdruntime/rt/sections_solaris.d

>> +++ b/libphobos/libdruntime/rt/sections_solaris.d

>

> [-- snip --]

>

>>

>> +// interface for core.thread to inherit loaded libraries

>> +void* pinLoadedLibraries() nothrow @nogc

>> +{

>> +    return null;

>> +}

>> +

>

> I ran into this on OSX as well.  The problem lies elsewhere, and I'm

> going to fix this.  The shared library is being built with

> '-fversion=Shared', but this is only valid for targets that use

> rt/sections_elf_shared.d

>

> I suspect that Solaris/SPARC should be using the ELF sections support anyway.


Certainly, given that SysVr4 invented ELF and Solaris inherited it from
there.

> Apart from comments, the GCC parts look OK to me.  Unless you want to

> raise a pull request, I'll submit the library patches upstream later.


Excellent, thanks.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Rainer Orth Nov. 4, 2018, 4:47 p.m. | #11
Hi Iain,

> On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:

>>

>> Hi Iain,

>>

>> > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

>> >

>> > Upstream dmd use a poor man's alignment, from what I recall to be

>> > compatible with the dmc compiler.

>> >

>> >         // Ensure that the union is suitably aligned.

>> >         real_t for_alignment_only;

>> >

>> > What happens if you were to replace that with marking the type as

>> > __attribute__ ((aligned (8))) ?

>>

>> thanks for the suggestion: this worked just fine.  After a couple more

>> libphobos adjustments (described below), I was able to finish the build

>> on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>>

>> The link tests still all fail as before, but sparc and x86 are now on

>> par here :-)

>>

>

> Hi Rainer,

>

> On making the relevant change to dmd, this header probably should

> remain compatible with dmc++, which unfortunately doesn't implement

> any __attribute__ extensions.  Does s/real_t/long double/ also prevent

> the alignment error from occurring?


it does indeed, as checked by a sparc-sun-solaris2.11 bootstrap.

Thanks.
	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Rainer Orth Nov. 4, 2018, 4:50 p.m. | #12
Hi Iain,

> On Sat, 3 Nov 2018 at 23:23, Iain Buclaw <ibuclaw@gdcproject.org> wrote:

>>

>> On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:

>> >

>> > Hi Iain,

>> >

>> > > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

>> > >

>> > > Upstream dmd use a poor man's alignment, from what I recall to be

>> > > compatible with the dmc compiler.

>> > >

>> > >         // Ensure that the union is suitably aligned.

>> > >         real_t for_alignment_only;

>> > >

>> > > What happens if you were to replace that with marking the type as

>> > > __attribute__ ((aligned (8))) ?

>> >

>> > thanks for the suggestion: this worked just fine.  After a couple more

>> > libphobos adjustments (described below), I was able to finish the build

>> > on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

>> >

>> > The link tests still all fail as before, but sparc and x86 are now on

>> > par here :-)

>> >

>>

>> Hi Rainer,

>>

>> On making the relevant change to dmd, this header probably should

>> remain compatible with dmc++, which unfortunately doesn't implement

>> any __attribute__ extensions.  Does s/real_t/long double/ also prevent

>> the alignment error from occurring?

>>

>

> Actually, turns out I'm wrong and was grepping for the wrong name.

>

> It is supported in the form of #pragma pack(8)

>

> https://www.digitalmars.com/ctg/pragmas.html#pack


I tried wrapping union u in #pragma pack(8)/#pragma pack().
Unfortunately, this doesn't seem to work as I got the same SIGBUS errors
during a sparc-sun-solaris2.11 bootstrap.  Seems we have to stay with
the long double version instead.

I'm including the current patch here.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2018-10-29  Iain Buclaw  <ibuclaw@gdcproject.org>

	gcc/d:
	* dmd/expression.h (UnionExp.u): Change for_alignment_only to long
	double.

2018-10-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config/default-d.c: Include memmodel.h.

	* config/sol2-d.c: New file.
	* config/t-sol2 (sol2-d.o): New rule.
	* config.gcc <*-*-solaris2*>: Set d_target_objs,
	target_has_targetdm.

	libphobos:
	* libdruntime/core/stdc/fenv.d [SPARC, SPARC64]: Set SPARC_Any.
	[X86, X86_64]: Set X86_Any.
	[Solaris]: Provide FE_* constants.
	* libdruntime/core/sys/posix/aio.d [Solaris] (struct aio_result,
	struct aiocb): New types.
	* libdruntime/core/sys/posix/ucontext.d [SPARC64, SPARC] (_NGREG,
	greg_t): Define.
	[SPARC64, SPARC] (struct _fpq, struct fq, struct fpregset_t): New
	types.
	* libdruntime/core/thread.d (Class Thread) [Solaris]
	(m_isRTClass): Don't declare immutable.
	* libdruntime/rt/sections_solaris.d (SectionGroup.moduleGroup):
	Declare nothrow @nogc.
	(pinLoadedLibraries, unpinLoadedLibraries, inheritLoadedLibraries)
	(cleanupLoadedLibraries): New functions.
	* src/std/datetime/systime.d (class Clock) [Solaris]
	(clock_gettime): Import.
	* src/std/math.d [SPARC, SPARC64]: Set SPARC_Any.
	(struct FloatingPointControl): Use SPARC_Any for ExceptionMask,
	ControlState.
# HG changeset patch
# Parent  0f6ccc9cfd024f705876c70a6403268ea9dbf0a2
Fix D compilation on Solaris

diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -918,6 +918,7 @@ case ${target} in
   target_gtfiles="$target_gtfiles \$(srcdir)/config/sol2.c"
   c_target_objs="${c_target_objs} sol2-c.o"
   cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o"
+  d_target_objs="${d_target_objs} sol2-d.o"
   extra_objs="${extra_objs} sol2.o sol2-stubs.o"
   extra_options="${extra_options} sol2.opt"
   case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
@@ -925,6 +926,7 @@ case ${target} in
       thread_file=posix
       ;;
   esac
+  target_has_targetdm=yes
   ;;
 *-*-*vms*)
   extra_options="${extra_options} vms/vms.opt"
diff --git a/gcc/config/default-d.c b/gcc/config/default-d.c
--- a/gcc/config/default-d.c
+++ b/gcc/config/default-d.c
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.  
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "memmodel.h"
 #include "tm_d.h"
 #include "d/d-target.h"
 #include "d/d-target-def.h"
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
new file mode 100644
--- /dev/null
+++ b/gcc/config/sol2-d.c
@@ -0,0 +1,51 @@
+/* Solaris support needed only by D front-end.
+   Copyright (C) 2018 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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Solaris targets.  */
+
+static void
+solaris_d_os_builtins (void)
+{
+  d_add_builtin_version ("Posix");
+  d_add_builtin_version ("Solaris");			\
+}
+
+/* Implement TARGET_D_CRITSEC_SIZE for Solaris targets.  */
+
+static unsigned
+solaris_d_critsec_size (void)
+{
+  /* This is the sizeof pthread_mutex_t.  */
+  return 24;
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+
+#undef TARGET_D_CRITSEC_SIZE
+#define TARGET_D_CRITSEC_SIZE solaris_d_critsec_size
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -16,7 +16,7 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-# Solaris-specific format checking and pragmas
+# Solaris-specific format checking and pragmas.
 sol2-c.o: $(srcdir)/config/sol2-c.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
@@ -26,6 +26,11 @@ sol2-cxx.o: $(srcdir)/config/sol2-cxx.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+# Solaris-specific D support.
+sol2-d.o: $(srcdir)/config/sol2-d.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 # Corresponding stub routines.
 sol2-stubs.o: $(srcdir)/config/sol2-stubs.c
 	$(COMPILE) $<
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -1509,7 +1509,7 @@ private:
         char sliceexp  [sizeof(SliceExp)];
 
         // Ensure that the union is suitably aligned.
-        real_t for_alignment_only;
+        long double for_alignment_only;
     } u;
 };
 
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -33,6 +33,16 @@ version (PPC)
 else version (PPC64)
     version = PPC_Any;
 
+version (SPARC)
+    version = SPARC_Any;
+version (SPARC64)
+    version = SPARC_Any;
+
+version (X86)
+    version = X86_Any;
+version (X86_64)
+    version = X86_Any;
+
 version (MinGW)
     version = GNUFP;
 version (CRuntime_Glibc)
@@ -451,6 +461,50 @@ version (CRuntime_Microsoft)
         FE_TOWARDZERO   = 0x300, ///
     }
 }
+else version (Solaris)
+{
+	version (SPARC_Any)
+	{
+	    enum
+	    {
+		FE_TONEAREST    = 0,
+		FE_TOWARDZERO   = 1,
+		FE_UPWARD       = 2,
+		FE_DOWNWARD     = 3,
+	    }
+
+	    enum
+	    {
+		FE_INEXACT      = 0x01,
+		FE_DIVBYZERO    = 0x02,
+		FE_UNDERFLOW    = 0x04,
+		FE_OVERFLOW     = 0x08,
+		FE_INVALID      = 0x10,
+		FE_ALL_EXCEPT   = 0x1f,
+	    }
+
+	}
+	else version (X86_Any)
+	{
+	    enum
+	    {
+		FE_TONEAREST    = 0,
+		FE_DOWNWARD     = 1,
+		FE_UPWARD       = 2,
+		FE_TOWARDZERO   = 3,
+	    }
+
+	    enum
+	    {
+		FE_INVALID      = 0x01,
+		FE_DIVBYZERO    = 0x04,
+		FE_OVERFLOW     = 0x08,
+		FE_UNDERFLOW    = 0x10,
+		FE_INEXACT      = 0x20,
+		FE_ALL_EXCEPT   = 0x3d,
+	    }
+	}
+}
 else
 {
     version (X86)
diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d
--- a/libphobos/libdruntime/core/sys/posix/aio.d
+++ b/libphobos/libdruntime/core/sys/posix/aio.d
@@ -123,6 +123,32 @@ else version (DragonFlyBSD)
 
     version = BSD_Posix;
 }
+else version (Solaris)
+{
+    struct aio_result_t
+    {
+	ssize_t aio_return;
+	int aio_errno;
+    };
+
+    struct aiocb
+    {
+        int aio_fildes;
+        void* aio_buf;   // volatile
+        size_t aio_nbytes;
+        off_t aio_offset;
+	int aio_reqprio;
+        sigevent aio_sigevent;
+        int aio_lio_opcode;
+	aio_result_t aio_result;
+	byte aio_state;
+	byte aio_returned;
+	byte[2] aio__pad1;
+	int aio_flags;
+    }
+
+    version = BSD_Posix;
+}
 else
     static assert(false, "Unsupported platform");
 
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -937,7 +937,17 @@ else version (Solaris)
 {
     alias uint[4] upad128_t;
 
-    version (X86_64)
+    version (SPARC64)
+    {
+        enum _NGREG = 21;
+        alias long greg_t;
+    }
+    else version (SPARC)
+    {
+        enum _NGREG = 19;
+        alias int greg_t;
+    }
+    else version (X86_64)
     {
         enum _NGREG = 28;
         alias long greg_t;
@@ -950,7 +960,70 @@ else version (Solaris)
 
     alias greg_t[_NGREG] gregset_t;
 
-    version (X86_64)
+    version (SPARC64)
+    {
+	struct _fpq
+	{
+	    uint *fpq_addr;
+	    uint fpq_instr;
+	}
+
+	struct fq
+	{
+	    union
+	    {
+		double whole;
+		_fpq fpq;
+	    };
+	}
+
+        struct fpregset_t
+	{
+	    union
+	    {
+	    	uint[32]	fpu_regs;
+		double[32]	fpu_dregs;
+		real[16]	fpu_qregs;
+	    };
+	    fq		*fpu_q;
+	    ulong	fpu_fsr;
+	    ubyte	fpu_qcnt;
+	    ubyte	fpu_q_entrysize;
+	    ubyte	fpu_en;
+	}
+    }
+    else version (SPARC)
+    {
+	struct _fpq
+	{
+	    uint *fpq_addr;
+	    uint fpq_instr;
+	}
+
+	struct fq
+	{
+	    union
+	    {
+		double whole;
+		_fpq fpq;
+	    };
+	}
+
+	struct fpregset_t
+	{
+	    union
+	    {
+		uint[32]	fpu_regs;
+		double[16]	fpu_dregs;
+	    };
+	    fq		*fpu_q;
+	    uint	fpu_fsr;
+	    ubyte	fpu_qcnt;
+	    ubyte	fpu_q_entrysize;
+	    ubyte	fpu_en;
+	}
+    }
+    else version (X86_64)
     {
         union _u_st
         {
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -1547,7 +1547,7 @@ private:
 
     version (Solaris)
     {
-        __gshared immutable bool m_isRTClass;
+        __gshared bool m_isRTClass;
     }
 
 private:
diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/rt/sections_solaris.d
--- a/libphobos/libdruntime/rt/sections_solaris.d
+++ b/libphobos/libdruntime/rt/sections_solaris.d
@@ -34,7 +34,7 @@ struct SectionGroup
         return _moduleGroup.modules;
     }
 
-    @property ref inout(ModuleGroup) moduleGroup() inout
+    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
     {
         return _moduleGroup;
     }
@@ -87,6 +87,24 @@ void scanTLSRanges(void[] rng, scope voi
     dg(rng.ptr, rng.ptr + rng.length);
 }
 
+// interface for core.thread to inherit loaded libraries
+void* pinLoadedLibraries() nothrow @nogc
+{
+    return null;
+}
+
+void unpinLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void inheritLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void cleanupLoadedLibraries() nothrow @nogc
+{
+}
+
 private:
 
 __gshared SectionGroup _sections;
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -221,6 +221,7 @@ public:
                 else
                 {
                     import core.sys.solaris.time : CLOCK_REALTIME;
+                    import core.sys.posix.time : clock_gettime;
                     static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME;
                     else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;
                     else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -160,6 +160,8 @@ version (MIPS32)    version = MIPS_Any;
 version (MIPS64)    version = MIPS_Any;
 version (AArch64)   version = ARM_Any;
 version (ARM)       version = ARM_Any;
+version (SPARC)     version = SPARC_Any;
+version (SPARC64)   version = SPARC_Any;
 
 version (D_InlineAsm_X86)
 {
@@ -5161,7 +5163,7 @@ struct FloatingPointControl
                                  | inexactException,
         }
     }
-    else version (SPARC64)
+    else version (SPARC_Any)
     {
         enum : ExceptionMask
         {
@@ -5291,7 +5293,7 @@ private:
     {
         alias ControlState = uint;
     }
-    else version (SPARC64)
+    else version (SPARC_Any)
     {
         alias ControlState = ulong;
     }
Iain Buclaw Nov. 4, 2018, 6:31 p.m. | #13
On Sun, 4 Nov 2018 at 17:50, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>

> Hi Iain,

>

> > On Sat, 3 Nov 2018 at 23:23, Iain Buclaw <ibuclaw@gdcproject.org> wrote:

> >>

> >> On Wed, 31 Oct 2018 at 10:40, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:

> >> >

> >> > Hi Iain,

> >> >

> >> > > My first suspect here would be 'struct UnionExp', see d/dmd/expression.h

> >> > >

> >> > > Upstream dmd use a poor man's alignment, from what I recall to be

> >> > > compatible with the dmc compiler.

> >> > >

> >> > >         // Ensure that the union is suitably aligned.

> >> > >         real_t for_alignment_only;

> >> > >

> >> > > What happens if you were to replace that with marking the type as

> >> > > __attribute__ ((aligned (8))) ?

> >> >

> >> > thanks for the suggestion: this worked just fine.  After a couple more

> >> > libphobos adjustments (described below), I was able to finish the build

> >> > on both sparc-sun-solaris2.11 and i386-pc-solaris2.11.

> >> >

> >> > The link tests still all fail as before, but sparc and x86 are now on

> >> > par here :-)

> >> >

> >>

> >> Hi Rainer,

> >>

> >> On making the relevant change to dmd, this header probably should

> >> remain compatible with dmc++, which unfortunately doesn't implement

> >> any __attribute__ extensions.  Does s/real_t/long double/ also prevent

> >> the alignment error from occurring?

> >>

> >

> > Actually, turns out I'm wrong and was grepping for the wrong name.

> >

> > It is supported in the form of #pragma pack(8)

> >

> > https://www.digitalmars.com/ctg/pragmas.html#pack

>

> I tried wrapping union u in #pragma pack(8)/#pragma pack().

> Unfortunately, this doesn't seem to work as I got the same SIGBUS errors

> during a sparc-sun-solaris2.11 bootstrap.  Seems we have to stay with

> the long double version instead.

>


That's alright.  I meant that #pragma pack is for DMC compatibility.

I've the changes have been made upstream:

https://github.com/dlang/dmd/pull/8907
https://github.com/dlang/dmd/pull/8914  (Backport to C++)


> I'm including the current patch here.

>

>         Rainer

>

> --

> -----------------------------------------------------------------------------

> Rainer Orth, Center for Biotechnology, Bielefeld University

>

>

> 2018-10-29  Iain Buclaw  <ibuclaw@gdcproject.org>

>

>         gcc/d:

>         * dmd/expression.h (UnionExp.u): Change for_alignment_only to long

>         double.

>

> 2018-10-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

>

>         gcc:

>         * config/default-d.c: Include memmodel.h.

>

>         * config/sol2-d.c: New file.

>         * config/t-sol2 (sol2-d.o): New rule.

>         * config.gcc <*-*-solaris2*>: Set d_target_objs,

>         target_has_targetdm.

>

>         libphobos:

>         * libdruntime/core/stdc/fenv.d [SPARC, SPARC64]: Set SPARC_Any.

>         [X86, X86_64]: Set X86_Any.

>         [Solaris]: Provide FE_* constants.

>         * libdruntime/core/sys/posix/aio.d [Solaris] (struct aio_result,

>         struct aiocb): New types.

>         * libdruntime/core/sys/posix/ucontext.d [SPARC64, SPARC] (_NGREG,

>         greg_t): Define.

>         [SPARC64, SPARC] (struct _fpq, struct fq, struct fpregset_t): New

>         types.

>         * libdruntime/core/thread.d (Class Thread) [Solaris]

>         (m_isRTClass): Don't declare immutable.

>         * libdruntime/rt/sections_solaris.d (SectionGroup.moduleGroup):

>         Declare nothrow @nogc.

>         (pinLoadedLibraries, unpinLoadedLibraries, inheritLoadedLibraries)

>         (cleanupLoadedLibraries): New functions.

>         * src/std/datetime/systime.d (class Clock) [Solaris]

>         (clock_gettime): Import.

>         * src/std/math.d [SPARC, SPARC64]: Set SPARC_Any.

>         (struct FloatingPointControl): Use SPARC_Any for ExceptionMask,

>         ControlState.

>


The gcc changes look OK.  I will commit the front-end and library
changes though in a merge later today, as I've been sending them
upstream first.

-- 
Iain

Patch

# HG changeset patch
# Parent  21c0e7e50f9c14ddadbc6c3102da8956fb19e01f
Fix D compilation on Solaris

diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -918,6 +918,7 @@  case ${target} in
   target_gtfiles="$target_gtfiles \$(srcdir)/config/sol2.c"
   c_target_objs="${c_target_objs} sol2-c.o"
   cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o"
+  d_target_objs="${d_target_objs} sol2-d.o"
   extra_objs="${extra_objs} sol2.o sol2-stubs.o"
   extra_options="${extra_options} sol2.opt"
   case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
@@ -925,6 +926,7 @@  case ${target} in
       thread_file=posix
       ;;
   esac
+  target_has_targetdm=yes
   ;;
 *-*-*vms*)
   extra_options="${extra_options} vms/vms.opt"
diff --git a/gcc/config/default-d.c b/gcc/config/default-d.c
--- a/gcc/config/default-d.c
+++ b/gcc/config/default-d.c
@@ -18,6 +18,7 @@  along with GCC; see the file COPYING3.  
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "memmodel.h"
 #include "tm_d.h"
 #include "d/d-target.h"
 #include "d/d-target-def.h"
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
new file mode 100644
--- /dev/null
+++ b/gcc/config/sol2-d.c
@@ -0,0 +1,39 @@ 
+/* Solaris support needed only by D front-end.
+   Copyright (C) 2018 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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Solaris targets.  */
+
+static void
+solaris_d_os_builtins (void)
+{
+  d_add_builtin_version ("Posix");
+  d_add_builtin_version ("Solaris");			\
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -16,7 +16,7 @@ 
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-# Solaris-specific format checking and pragmas
+# Solaris-specific format checking and pragmas.
 sol2-c.o: $(srcdir)/config/sol2-c.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
@@ -26,6 +26,11 @@  sol2-cxx.o: $(srcdir)/config/sol2-cxx.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+# Solaris-specific D support.
+sol2-d.o: $(srcdir)/config/sol2-d.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 # Corresponding stub routines.
 sol2-stubs.o: $(srcdir)/config/sol2-stubs.c
 	$(COMPILE) $<
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -33,6 +33,16 @@  version (PPC)
 else version (PPC64)
     version = PPC_Any;
 
+version (SPARC)
+    version = SPARC_Any;
+version (SPARC64)
+    version = SPARC_Any;
+
+version (X86)
+    version = X86_Any;
+version (X86_64)
+    version = X86_Any;
+
 version (MinGW)
     version = GNUFP;
 version (CRuntime_Glibc)
@@ -451,6 +461,50 @@  version (CRuntime_Microsoft)
         FE_TOWARDZERO   = 0x300, ///
     }
 }
+else version (Solaris)
+{
+	version (SPARC_Any)
+	{
+	    enum
+	    {
+		FE_TONEAREST    = 0,
+		FE_TOWARDZERO   = 1,
+		FE_UPWARD       = 2,
+		FE_DOWNWARD     = 3,
+	    }
+
+	    enum
+	    {
+		FE_INEXACT      = 0x01,
+		FE_DIVBYZERO    = 0x02,
+		FE_UNDERFLOW    = 0x04,
+		FE_OVERFLOW     = 0x08,
+		FE_INVALID      = 0x10,
+		FE_ALL_EXCEPT   = 0x1f,
+	    }
+
+	}
+	else version (X86_Any)
+	{
+	    enum
+	    {
+		FE_TONEAREST    = 0,
+		FE_DOWNWARD     = 1,
+		FE_UPWARD       = 2,
+		FE_TOWARDZERO   = 3,
+	    }
+
+	    enum
+	    {
+		FE_INVALID      = 0x01,
+		FE_DIVBYZERO    = 0x04,
+		FE_OVERFLOW     = 0x08,
+		FE_UNDERFLOW    = 0x10,
+		FE_INEXACT      = 0x20,
+		FE_ALL_EXCEPT   = 0x3d,
+	    }
+	}
+}
 else
 {
     version (X86)
diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d
--- a/libphobos/libdruntime/core/sys/posix/aio.d
+++ b/libphobos/libdruntime/core/sys/posix/aio.d
@@ -123,6 +123,32 @@  else version (DragonFlyBSD)
 
     version = BSD_Posix;
 }
+else version (Solaris)
+{
+    struct aio_result_t
+    {
+	ssize_t aio_return;
+	int aio_errno;
+    };
+
+    struct aiocb
+    {
+        int aio_fildes;
+        void* aio_buf;   // volatile
+        size_t aio_nbytes;
+        off_t aio_offset;
+	int aio_reqprio;
+        sigevent aio_sigevent;
+        int aio_lio_opcode;
+	aio_result_t aio_result;
+	byte aio_state;
+	byte aio_returned;
+	byte[2] aio__pad1;
+	int aio_flags;
+    }
+
+    version = BSD_Posix;
+}
 else
     static assert(false, "Unsupported platform");
 
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -937,7 +937,17 @@  else version (Solaris)
 {
     alias uint[4] upad128_t;
 
-    version (X86_64)
+    version (SPARC64)
+    {
+        enum _NGREG = 21;
+        alias long greg_t;
+    }
+    else version (SPARC)
+    {
+        enum _NGREG = 19;
+        alias int greg_t;
+    }
+    else version (X86_64)
     {
         enum _NGREG = 28;
         alias long greg_t;
@@ -950,7 +960,70 @@  else version (Solaris)
 
     alias greg_t[_NGREG] gregset_t;
 
-    version (X86_64)
+    version (SPARC64)
+    {
+	struct _fpq
+	{
+	    uint *fpq_addr;
+	    uint fpq_instr;
+	}
+
+	struct fq
+	{
+	    union FQu
+	    {
+		double whole;
+		_fpq fpq;
+	    };
+	}
+
+        struct fpregset_t
+	{
+	    union fpu_fr
+	    {
+	    	uint32_t[32]	fpu_regs;
+		double[32]	fpu_dregs;
+		/* long double[16]	fpu_qregs; */
+	    };
+	    fq		*fpu_q;
+	    ulong	fpu_fsr;
+	    ubyte	fpu_qcnt;
+	    ubyte	fpu_q_entrysize;
+	    ubyte	fpu_en;
+	}
+    }
+    else version (SPARC)
+    {
+	struct _fpq
+	{
+	    uint *fpq_addr;
+	    uint fpq_instr;
+	}
+
+	struct fq
+	{
+	    union FQu
+	    {
+		double whole;
+		_fpq fpq;
+	    };
+	}
+
+	struct fpregset_t
+	{
+	    union
+	    {
+		uint[32]	fpu_regs;
+		double[16]	fpu_dregs;
+	    };
+	    fq		*fpu_q;
+	    uint	fpu_fsr;
+	    ubyte	fpu_qcnt;
+	    ubyte	fpu_q_entrysize;
+	    ubyte	fpu_en;
+	}
+    }
+    else version (X86_64)
     {
         union _u_st
         {
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -1547,7 +1547,7 @@  private:
 
     version (Solaris)
     {
-        __gshared immutable bool m_isRTClass;
+        __gshared bool m_isRTClass;
     }
 
 private:
diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/rt/sections_solaris.d
--- a/libphobos/libdruntime/rt/sections_solaris.d
+++ b/libphobos/libdruntime/rt/sections_solaris.d
@@ -34,7 +34,7 @@  struct SectionGroup
         return _moduleGroup.modules;
     }
 
-    @property ref inout(ModuleGroup) moduleGroup() inout
+    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
     {
         return _moduleGroup;
     }
@@ -87,6 +87,24 @@  void scanTLSRanges(void[] rng, scope voi
     dg(rng.ptr, rng.ptr + rng.length);
 }
 
+// interface for core.thread to inherit loaded libraries
+void* pinLoadedLibraries() nothrow @nogc
+{
+    return null;
+}
+
+void unpinLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void inheritLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void cleanupLoadedLibraries() nothrow @nogc
+{
+}
+
 private:
 
 __gshared SectionGroup _sections;
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -221,6 +221,7 @@  public:
                 else
                 {
                     import core.sys.solaris.time : CLOCK_REALTIME;
+                    import core.sys.posix.time : clock_gettime;
                     static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME;
                     else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;
                     else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;