diff mbox

[build] Support libgo on Solaris 2

Message ID yddei8kaili.fsf@CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth Jan. 10, 2011, 3:23 p.m. UTC
Ian Lance Taylor <ian@airs.com> writes:

>> * Building in a configured tree doesn't work, e.g. mksysinfo.sh uses
>>   ${CC:-gcc}, which is wrong if the installed gcc isn't Go-capably
>>   (which it most likely isn't).  Either fix the invokation or substitute
>>   the value into mksysinfo.sh.
>
> It should work fine if you build using "make all-target-libgo" from the
> top level.  I have no objection to making it work if you build in the
> libgo directory directly.

Fine.  It certainly makes development far easier.

>> * go1 is linked with libstdc++.so.6, but if that isn't installed (or too
>>   old), compilation won't work.  I had to manually set LD_LIBRARY_PATH
>>   (both for libstdc++.so.6 and libgcc_s.so.1) to avoid that.
>
> If you do not use --disable-bootstrap, then go1 should be built with
> -static-libstdc++ and this should not happen.  So, I assume you did
> disable bootstrap.  In that case go1 will be built with the installed
> g++, and the assumption is that the installed g++ uses a libstdc++.so
> which the dynamic linker knows how to find.  I assume that is not the
> case on your system, but I don't know what else to do when bootstrap is
> disabled.  You can of course use the --with-host-libstdcxx or
> --with-stage1-libs options to set -rpath options as appropriate for your
> system.

I didn't use --disable-bootstrap, and -static-libstdc++ -static-libgcc
are already used.  As mentioned in my response to Joseph, the issue is
far easier, though: -static-libstdc++ depends on the correct detection
of -Bstatic/-Bdynamic, and the test is currently (again ;-)
gld-specific.  Solaris ld (and most likely even SunOS 4 ld) has
supported this since day 1.  If I fix gcc/configure.ac to know about
this, go1 is indeed linked statically with libstdc++ and libgcc.

>> * Since mksysinfo.sh uses set -e, it silently exists upon the first
>>   error.  This script is massively unportable (e.g. if ! ...), heavily
>>   Linux-specific, and I'm uncertain if this is the best approach here.
>>   Anyway, I've removed the set -e and manually fixed the issues with the
>>   generated sysinfo.go until it's decided how to proceed.  Perhaps it
>>   could be replaced by a C program and autoconf tests?
>
> Removing the set -e will just tend to hide problems, though I'm
> certainly open to suggestions for how to make the script easier to work
> with.  As far as I know "if !" is POSIX, but if it doesn't work it can
> be removed easily enough.
>
> The script can be augmented by autoconf tests where that makes sense,
> but it can't really be replaced by them.  I don't think a C program is
> really right here, because the script is mainly running sed, which is a
> job more appropriate for the shell than for a C program.

Ok.  I've coaxed the Solaris changes into the script, and expect do be
able to do the same for IRIX and Tru64 UNIX later.  As I said, so far
I've been lasy here to get someting running at all.

>>   Here are the changes I had to make:
>>
>> -type _pad128_t struct { _q float80; }
>> -type _upad128_t struct { _q float80; }
>> +type _pad128_t struct { _l [4]int32; }
>> +type _upad128_t struct { _l [4]uint32; }
>>
>>   Without this, I get
>>
>> sysinfo.go:1841:28: error: use of undefined type 'float80'
>> sysinfo.go:1841:25: error: struct field type is incomplete
>
> The use of float80 is a bug in godump.c.  The Go language used to have a
> float80 type but it no longer does.

I see.  For the moment, I've include a workaround in mksysinfo.sh.  Do
you envision this being fixed soon?

>>   I got
>>
>> sysinfo.go:2132:5: error: redefinition of '_timezone'
>> sysinfo.go:1921:6: note: previous definition of '_timezone' was here
>>
>>   corresponding to
>>
>> type _timezone struct { tz_minuteswest int32; tz_dsttime int32; }
>> var _timezone int32
>>
>>   I'm removing the var for now.
>
> I guess this should be handled in godump.c too, somehow.  In Go all
> names are in the same namespace, unlike C.

Ok.  Also worked around for the moment.

>> * It's currently hard to identify which libgo sources require which OS
>>   features and which are completely portable.  The deeply nested
>>   automake conditionals don't help either, especially since they give no
>>   real indication why which file is used where.
>>
>>   I've tried to improve things by adding comments liberally.  As usual,
>>   Solaris needs -lsocket (and eventually -lnsl, though things work
>>   without so far), so I've added support for NET_LIBS.  The configure
>>   test is obviously a hack that needs to be done properly, though the
>>   code in libjava/configure.ac might be overkill.
>
> Thanks.  This stuff is definitely awkward.  Part of the complexity comes
> from the master Go library; I want to minimize differences with that.

Understood: if we can up with something understandable (and be it even
comments about the different variants), hopefully this can go upstream?

>> * Several other changes should be clear from comments in the code.
>>   Unfortunately, many files in syscalls seem to be largely identical
>>   copies of each other.  It would be helpful to modularize this
>>   somewhat.
>
> Where possible, yes.

I'll check, especially when I (ever) get to trying this on anything but
Solaris.

>>   I often see dummy implementations (like go/debug/regs/{proc, regs}_*);
>>   perhaps there should be a single dummy to use until a real one is
>>   provided?
>
> That comes from the master library, which would be the place to fix it.

I see.  A misunderstanding on my part: I had misread that only the go
subdirectory was from upstream.

>> * testsuite/gotest again calls nm -s, who'se output format isn't
>>   portable.  nm -ps works on Solaris, though.
>
> Actually using -s is a bug inherited from the master gotest script.  The
> intent is to use the option which avoids sorting the symbols.

Ok.  It would be nice to centralize knowledge about how to invoke nm
somewhere, because this issue crops up over and over again.

>> * Currently, libgo prefers the gotest-bases testsuite instead of
>>   DejaGnu, which IMO is highly unfortunate since this gives us yet
>>   another test framework in GCC with a different output format and not
>>   integrated with mail-report.log.  We should strive for the opposite
>>   here!  Even if I force the DejaGnu-based one, it fails immediately
>>   since it sets GO_UNDER_TEST while the testsuite in gcc/testsuite/lib
>>   uses GOC_UNDER_TEST :-)
>
> Let's just make the libgo testsuite output match whatever
> mail-report.log wants.  Using DejaGNU for the libgo tests will just make
> them harder to run.  The output is determined by the CHECK variable in
> libgo/Makefile.am.

No!  I'm currently working to get as many of the GCC testsuites as
possible to use DejaGnu, among others for reasons discussed in

	http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00244.html

It would be a maintenance nightmare to have to coax many different
testsuite frameworks to both produce the DejaGnu output format (not that
hard, probably, but there have been differences that
e.g. dg-extract-results.sh had to be taught about) and to have many

Comments

Joseph Myers Jan. 10, 2011, 3:42 p.m. UTC | #1
On Mon, 10 Jan 2011, Rainer Orth wrote:

> +    case "$with_multisubdir" in

Checking the name of a multilib directory to work out whether the ABI is 
32-bit or 64-bit is a bad idea and liable to fail with custom multilib 
configurations.  Instead, make both x86 and x86_64 configurations do a 
test of what preprocessor macros the compiler defines (as done in 
libgcc/configure.ac, for example) and that way it will work for all x86 
targets and all multilib configurations of those targets.  Likewise for 
SPARC; the multilib directory names for SPARC GNU/Linux are different from 
those for Solaris, a test of preprocessor macros should be able to work 
for both.
Rainer Orth Jan. 10, 2011, 4 p.m. UTC | #2
"Joseph S. Myers" <joseph@codesourcery.com> writes:

> On Mon, 10 Jan 2011, Rainer Orth wrote:
>
>> +    case "$with_multisubdir" in
>
> Checking the name of a multilib directory to work out whether the ABI is 
> 32-bit or 64-bit is a bad idea and liable to fail with custom multilib 

I've just been generalizing what libgo/configure.ac did before, though
I'm aware that it is fragile and would need to be adapted to the
different multilib conventions of various OSes.

> configurations.  Instead, make both x86 and x86_64 configurations do a 
> test of what preprocessor macros the compiler defines (as done in 
> libgcc/configure.ac, for example) and that way it will work for all x86 
> targets and all multilib configurations of those targets.  Likewise for 
> SPARC; the multilib directory names for SPARC GNU/Linux are different from 
> those for Solaris, a test of preprocessor macros should be able to work 
> for both.

Excellent tip, thanks.

	Rainer
Rainer Orth Jan. 19, 2011, 5:12 p.m. UTC | #3
Hi Ian,

>>> * libgo make check results are not too bad either.  I've manually
>>>   cleaned the output for two issues: the echo -n stuff above and ld
>>>   warnings:
>>>
>>> asn1 ld: warning: relocation warning: R_386_COPY: file /vol/gcc/obj/gcc-4.6.0-20101223/11-gcc-go/i386-pc-solaris2.11/libgo/.libs/libgo.so: symbol __go_tdn_libgo_reflect.reflect.Type: relocation bound to a symbol with STV_PROTECTED visibility
>>>
>>>   I still need to look into them.
>>
>> The symbol should be in the read-only data section.  I'm not sure why
>> the linker is creating a COPY reloc for it.
>
> It isn't:
>
> $ elfdump -s .libs/libgo.so|grep __go_tdn_libgo_reflect.reflect.Type
>     [6196]  0x004974e0 0x00000028  OBJT GLOB  P    1 .data.rel.ro   __go_tdn_libgo_reflect.reflect.Type
>    [45868]  0x004974e0 0x00000028  OBJT GLOB  P    0 .data.rel.ro   __go_tdn_libgo_reflect.reflect.Type
> $ elfdump -c -N .data.rel.ro .libs/libgo.so
>
> Section Header[29]:  sh_name: .data.rel.ro
>     sh_addr:      0x491660        sh_flags:   [ SHF_WRITE SHF_ALLOC ]
>     sh_size:      0x14dc8         sh_type:    [ SHT_PROGBITS ]
>     sh_offset:    0x481660        sh_entsize: 0
>     sh_link:      0               sh_info:    0
>     sh_addralign: 0x20      
>
> I'll have a look why not.  It turns out that the issue exists with both
> Sun as and gas when used together with Sun ld, while gas/gld is fine.
> Thinks look exactly the same with gas/gld, though, there's just no
> warning.

I've investigated further, but to no avail: without -fPIC, the variable
goes into .rodata and all is fine.  With -fPIC, it goes into
.data.rel.ro, which despite it's name is read-write.

I've talked to the Sun linker guys, and they explained that ld creates
the copy relocation to keep the text segment read-only, but warn since
now there are two copies of a presumably writable data item: the
variable directly bound inside the shared library with protected
visibility and the copy in the executable.

I've not been able to construct a minimal testcase: something like

const int cip __attribute__((visibility("protected"))) = 1;

goes into .rodata without and with -fPIC.

Any suggestions?

Thanks.
	Rainer
Ian Lance Taylor Jan. 20, 2011, 5:14 a.m. UTC | #4
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

>>>> * libgo make check results are not too bad either.  I've manually
>>>>   cleaned the output for two issues: the echo -n stuff above and ld
>>>>   warnings:
>>>>
>>>> asn1 ld: warning: relocation warning: R_386_COPY: file /vol/gcc/obj/gcc-4.6.0-20101223/11-gcc-go/i386-pc-solaris2.11/libgo/.libs/libgo.so: symbol __go_tdn_libgo_reflect.reflect.Type: relocation bound to a symbol with STV_PROTECTED visibility
>>>>
>>>>   I still need to look into them.
>>>
>>> The symbol should be in the read-only data section.  I'm not sure why
>>> the linker is creating a COPY reloc for it.
>>
>> It isn't:
>>
>> $ elfdump -s .libs/libgo.so|grep __go_tdn_libgo_reflect.reflect.Type
>>     [6196]  0x004974e0 0x00000028  OBJT GLOB  P    1 .data.rel.ro   __go_tdn_libgo_reflect.reflect.Type
>>    [45868]  0x004974e0 0x00000028  OBJT GLOB  P    0 .data.rel.ro   __go_tdn_libgo_reflect.reflect.Type
>> $ elfdump -c -N .data.rel.ro .libs/libgo.so
>>
>> Section Header[29]:  sh_name: .data.rel.ro
>>     sh_addr:      0x491660        sh_flags:   [ SHF_WRITE SHF_ALLOC ]
>>     sh_size:      0x14dc8         sh_type:    [ SHT_PROGBITS ]
>>     sh_offset:    0x481660        sh_entsize: 0
>>     sh_link:      0               sh_info:    0
>>     sh_addralign: 0x20      
>>
>> I'll have a look why not.  It turns out that the issue exists with both
>> Sun as and gas when used together with Sun ld, while gas/gld is fine.
>> Thinks look exactly the same with gas/gld, though, there's just no
>> warning.
>
> I've investigated further, but to no avail: without -fPIC, the variable
> goes into .rodata and all is fine.  With -fPIC, it goes into
> .data.rel.ro, which despite it's name is read-write.
>
> I've talked to the Sun linker guys, and they explained that ld creates
> the copy relocation to keep the text segment read-only, but warn since
> now there are two copies of a presumably writable data item: the
> variable directly bound inside the shared library with protected
> visibility and the copy in the executable.
>
> I've not been able to construct a minimal testcase: something like
>
> const int cip __attribute__((visibility("protected"))) = 1;
>
> goes into .rodata without and with -fPIC.

OK, it's going into .data.rel.ro because there are relocations in the
initializer, in order to make it position independent.  Thus it goes
into a writable section, which after dynamic relocation is complete can
be made read-only.  Presumably the Sun linker doesn't know about
.data.rel.ro, and so doesn't realize that the variable really is
read-only.  Hence the warning.

Since the variable is read-only, there is no actual problem here.  The
COPY reloc will cause there to be two copies, but that doesn't matter
since the two copies will hold the same values, and the code does not
require that the pointers be the same.  But of course the warning is not
particularly desirable.

I'm declaring these as protected because in the x86_64 small model,
which is the default for gcc, the references in the shared library may
be out of range if they have to refer to the version copied into the
executable.  So I don't think it will work to give them normal
visibility.

A similar issue arises for C++ typeinfo structures.  I think C++ may get
away with it because there are no direct references to the typeinfo
structures, only references from other data structures, which use
64-bit relocations even in the small model.  An approach like that might
work: use variables initialized to the address of the type descriptors,
rather than direct code references.

Or it's also quite possible that I misunderstand something.

Would you mind opening a bug report about this?  The code is fine on
GNU/Linux, and it should run fine even on Solaris, but I guess we should
do something to avoid the linker warnings.

Ian
Rainer Orth Jan. 20, 2011, 2:26 p.m. UTC | #5
Ian Lance Taylor <ian@airs.com> writes:

> OK, it's going into .data.rel.ro because there are relocations in the
> initializer, in order to make it position independent.  Thus it goes
> into a writable section, which after dynamic relocation is complete can
> be made read-only.  Presumably the Sun linker doesn't know about
> .data.rel.ro, and so doesn't realize that the variable really is
> read-only.  Hence the warning.

it doesn't and doesn't care about section names AFAIK.  Even gld places
the section into a read-write segment, although it does know about
.data.rel.ro.

> Since the variable is read-only, there is no actual problem here.  The
> COPY reloc will cause there to be two copies, but that doesn't matter
> since the two copies will hold the same values, and the code does not
> require that the pointers be the same.  But of course the warning is not
> particularly desirable.

True, but given the information Sun ld has, it cannot know that the
section is really read-only and there's nothing to warn about.  While we
could prune the warning in the libgo testsuite, it would be good to
avoid it in the first place.

> Would you mind opening a bug report about this?  The code is fine on
> GNU/Linux, and it should run fine even on Solaris, but I guess we should
> do something to avoid the linker warnings.

Done:

target/47378	ld warning linking with libgo.so: relocation bound to a symbol with STV_PROTECTED visibility

I'll also engage the Sun linker maintainers; perhaps they have an idea
what to do.

Thanks.
	Rainer
diff mbox

Patch

different ways (or, more likely, none) to achieve what you can do in
DejaGnu (like selectively XFAILing cases and doing all other sorts of
stuff).  As an OS port maintainer, it's hard enough to have to cope with
many different languages and target libraries; multiplying this with
different test frameworks might be the deathnail to efforts trying to
improve platform coverage.

By standardizing on DejaGnu, despite all its quirks, you have to fight
only a single framework, not many.  I know that the current lack of a
testsuite maintainer doesn't help, though.

>> * With this stuff fixed, I can finally get a clean compile and link of
>>   the 32-bit libgo.  64-bit is strange, though: the build fails with
>>
>> mv: cannot stat `version.o': No such file or directory
>> make[6]: *** [runtime/libruntime.a] Error 1
>> libtool: compile: mv -f "vector.o" "container/.libs/libvector.a.o"
>> mv: cannot stat `vector.o': No such file or directory
>> make[6]: *** [container/libvector.a] Error 1
>> libtool: compile: mv -f "tables.o" "unicode/.libs/libunicode.a.o"
>> mv: cannot stat `tables.o': No such file or directory
>> make[6]: *** [unicode/libunicode.a] Error 1
>> libtool: compile: mv -f "unsafe.o" "math/.libs/libmath.a.o"
>> mv: cannot stat `unsafe.o': No such file or directory
>> make[6]: *** [math/libmath.a] Error 1
>> make[6]: Target `all-am' not remade because of errors.
>>
>>   and I find that in (some, all?) compilations with several .go source
>>   files, only the first is compiled.  I've yet no idea what's going on
>>   here.
>
> I think this means that libtool got confused and thought that it had to
> pass the sources to gccgo one at a time rather than all at once.  They
> must be passed all at once for gccgo to work correctly.  This happens
> when some libtool test fails, so check your config.log.

The only relevant differences in config.status between i386 and amd64
are

@@ -696 +696 @@ 
-lt_prog_compiler_pic_GO=' -fPIC'
+lt_prog_compiler_pic_GO=''
@@ -698 +698 @@ 
-lt_cv_prog_compiler_c_o_GO='yes'
+lt_cv_prog_compiler_c_o_GO='no'

It seems that this was a consequence of the problems with
-static-libstdc++ not working initially, though.  With that fixed, the
64-bit compilations work fine.

>> FAIL: go.test/test/env.go execution,  -O2 -g 
>>
>> $GOARCH: no such environment variable
>>
>>   Where would this be set?
>
> This test, like everything under go.test/test, comes from the master
> sources.  GOARCH should really be set by go-test.exp.

Ok, done.

>>   Only defined in libgo/syscalls/syscall_linux_*.go, probably need 4 files:
>>
>>   syscall_solaris_{386, amd64, sparc, sparcv9}.go
>>
>>   What is syscall.ARCH supposed to be anyway?  I.e. how would I handle
>>
>>   Solaris/SPARC (always 64-bit kernel), 32 or 64-bit binaries
>>   Solaris/x86 (32 or 64-bit kernel), 32 or 64-bit binaries
>
> The possible values for syscall.ARCH today are: 386, amd64, arm.  For
> SPARC we can pick whatever we want, presumably sparc32 and sparc64 or
> something like that.  For x86 it should be 386 or amd64.

I'd go for the customary sparc (32-bit SPARC) vs. sparcv9 (64-bit SPARC)
here, though I still don't fully understand the semantics of
GOARCH/syscall.ARCH: I suppose it depends on the multilib used,
i.e. i?86-*-* and x86_64-*-* -m32 are 386, i?86-*-* and x86_64-*-* are
amd64?

>> FAIL: go.test/test/chan/goroutines.go execution,  -O2 -g 
>>
>> /vol/gcc/src/hg/trunk/solaris/libgo/runtime/go-go.c:251: libgo assertion failure
>>
>>   __go_go:
>>
>>   /* Start the thread.  */
>>   i = pthread_create (&tid, &attr, start_go_thread, newm);
>>   __go_assert (i == 0);
>>
>>   No wonder, the test tries to create 10000 threads, pthread_creates
>>   returns with ENOMEM at 3944 threads, each taking 4 kB of stack, default
>>   stack limit is 10240 kB.  In pmap output, I see
>>
>> 08062000     160K rwx--    [ heap ]
>> 081BD000       4K rwx-R    [ anon ]
>> 082BC000       4K rwx-R    [ anon ]
>> 083BB000       4K rwx-R    [ anon ]
>> 084BA000       4K rwx-R    [ anon ]
>> 085B9000       4K rwx-R    [ anon ]
>> 086B8000       4K rwx-R    [ anon ]
>> 087B7000       4K rwx-R    [ stack tid=3938 ]
>> 088B6000       4K rwx-R    [ stack tid=3937 ]
>>
>>   The stacks are placed widely apart, easily exhausting the address space.
>>   The delta is FF000, i.e 1044480, close to 1 MB, any way to influence
>>   that?
>>
>>   pthread_attr_init(3C) documents
>>
>>          Attribute             Default Value                Meaning of Default
>>
>>      stacksize            0                         1 or 2 megabyte
>>
>>   Maybe we need to lower the default for Solaris?  But how low is still
>>   safe?
>
> It depends on whether you are using gold with split stack support or
> not.  On SPARC you are presumably not, since it is not implemented for
> SPARC.  There is no right answer to how low the stack size can get when
> split stacks are not supported; it's going to depend on the program.

I don't even know if gold works on Solaris 2/x86.  We had some try at
Solaris 2/SPARC some time ago, but didn't get anywhere.

Do you have a pointer to the split stack specs?  The Solaris linker
maintainers may be amenable to implementing it, given a sufficient case.

>> * libgo make check results are not too bad either.  I've manually
>>   cleaned the output for two issues: the echo -n stuff above and ld
>>   warnings:
>>
>> asn1 ld: warning: relocation warning: R_386_COPY: file /vol/gcc/obj/gcc-4.6.0-20101223/11-gcc-go/i386-pc-solaris2.11/libgo/.libs/libgo.so: symbol __go_tdn_libgo_reflect.reflect.Type: relocation bound to a symbol with STV_PROTECTED visibility
>>
>>   I still need to look into them.
>
> The symbol should be in the read-only data section.  I'm not sure why
> the linker is creating a COPY reloc for it.

It isn't:

$ elfdump -s .libs/libgo.so|grep __go_tdn_libgo_reflect.reflect.Type
    [6196]  0x004974e0 0x00000028  OBJT GLOB  P    1 .data.rel.ro   __go_tdn_libgo_reflect.reflect.Type
   [45868]  0x004974e0 0x00000028  OBJT GLOB  P    0 .data.rel.ro   __go_tdn_libgo_reflect.reflect.Type
$ elfdump -c -N .data.rel.ro .libs/libgo.so

Section Header[29]:  sh_name: .data.rel.ro
    sh_addr:      0x491660        sh_flags:   [ SHF_WRITE SHF_ALLOC ]
    sh_size:      0x14dc8         sh_type:    [ SHT_PROGBITS ]
    sh_offset:    0x481660        sh_entsize: 0
    sh_link:      0               sh_info:    0
    sh_addralign: 0x20      

I'll have a look why not.  It turns out that the issue exists with both
Sun as and gas when used together with Sun ld, while gas/gld is fine.
Thinks look exactly the same with gas/gld, though, there's just no
warning.

>> Btw., could this be 4.6.0 material, given how new Go support in GCC is?
>
> Yes, I think so.

Fine: I'll try to get something ready in time.  Seems doable judging
from the current results.

>> 2011-01-03  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
> No ChangeLog file in libgo, the master sources are not in the gcc
> repository.  I'm not sure if there is going to be a split in libgo
> between gcc-specific code and non-gcc-specific code.  I'm not opposed to
> it at all, but there is very little code that is gcc-specific.

Ok.  I'll keep posting the ChangeLog entries nonetheless, if only for me
keeping an overview of what changed.

So here's the second round of the patch: it worked for both 32 and
64-bit on i386-pc-solaris2.11.  The gcc/testsuite/go* results are mostly
clean:

		=== go tests ===


Running target unix
FAIL: go.test/test/chan/powser2.go execution,  -O2 -g 

		=== go Summary for unix ===

# of expected passes		2882
# of unexpected failures	1
# of expected failures		24

Running target unix/-m64
FAIL: go.test/test/chan/powser2.go execution,  -O2 -g 

		=== go Summary for unix/-m64 ===

# of expected passes		2882
# of unexpected failures	1
# of expected failures		24

		=== go Summary ===

# of expected passes		5764
# of unexpected failures	2
# of expected failures		48
/vol/gcc/obj/gcc-4.6.0-20110107/11-gcc-go/gcc/testsuite/go/../../gccgo  version 4.6.0 20110107 (experimental) [trunk revision 168568] (GCC) 

The test fails with

panic: runtime error: invalid memory address or nil pointer dereference

I haven't yet investigated what's up there.

I'll have to look at the libgo testsuite results later, but have already
found a couple of issues that still need fixing.

How should we proceed from here: wait until everything is fine, or check
in an initial version that mostly works and fix that up later?

	Rainer


2011-01-03  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* configure.ac (gcc_cv_ld_static_dynamic): Enable on *-*-solaris2*.
	* configure: Regenerate:

	gcc/testsuite:
	* go.test/go-test.exp (go-set-goarch): New proc.
	(go-gc-tests): Use it.

	libgo:
	* configure.ac (ECHO): Substitute.
	(LIBGO_IS_SOLARIS): New conditional.
	Sort os cases.
	Handle i[34567]86-*-* multilibs.
	Sort arch cases.
	(LIBGO_IS_SPARC): New conditional.
	(LIBGO_IS_SPARCV9): New conditional.
	(NET_LIBS): Check for -lsocket -lnsl.
	* Makefile.am: Handle LIBGO_IS_SOLARIS for OS-dependent files.
	(GOARCH): Handle sparc, sparcv9.
	Sort cases.
	(GOOS): Handle solaris.
	Sort cases.
	(proc_file, regs_file): Sort by OS.
	(go_syscall_files): Use $(syscall_sysfile_arch_file).
	(libgo_la_LDFLAGS): Define.
	(libgo_la_LIBADD): Add $(NET_LIB).
	(GOLINK): Fix typo.
	Remove $(PTHREAD_LIBS) $(MATH_LIBS).
	(CHECK): Use $(ECHO), $(ECHO_N).
	Pass $(NM) to gotest.
	(sysinfo.go): Pass $(CC) to mksysinfo.sh, add $(host_triplet) arg.
	* configure: Regenerate.
	* Makefile.in: Regenerate.
	* testsuite/Makefile.in: Regenerate.
	* mksysinfo.sh: Fix comment.
	Handle host argument.
	Handle _timestruc_t, _u?pad128_t.
	Ignore var _timezone, _utsname.
	(O_ASYNC) Provide if missing.
	(_PTRACE_TRACEME): Provide if missing.
	(PtraceRegs): Restrict to *-*-linux*.
	(_pad128_t): Work around missing float80 on *-*-solaris2*.
	(_upad128_t): Likewise.
	* runtime/go-go.c (__go_go) [!LINKER_SUPPORTS_SPLIT_STACK &&
	__sun__ && __svr4__]: Reduce default thread stack size.
	* syscalls/socket.go (SizeofSockaddr*): May be Linux-specific.
	* syscalls/socket_solaris.go: New file.
	* syscalls/syscall_solaris.go: New file.
	* syscalls/syscall_solaris_386.go: New file.
	* syscalls/syscall_solaris_amd64.go: New file.
	* syscalls/sysfile_solaris.go: New file.
	* syscalls/sysfile_solaris_386.go: New file.
	* syscalls/sysfile_solaris_amd64.go: New file.
	* testsuite/gotest: Use $NM, add -p.
	* testsuite/lib/libgo.exp (GO_UNDER_TEST): Rename to
	GOC_UNDER_TEST.
	* testsuite/libgo.testmain/testmain.exp (gluefile): Comment.

diff -r 72fce0443d71 gcc/configure.ac
--- a/gcc/configure.ac	Sat Jan 08 12:30:04 2011 +0100
+++ b/gcc/configure.ac	Sun Jan 09 12:31:06 2011 +0100
@@ -3166,11 +3166,18 @@ 
     gcc_cv_ld_static_dynamic=yes
   fi
 elif test x$gcc_cv_ld != x; then
-	# Check if linker supports -Bstatic/-Bdynamic option
-	if $gcc_cv_ld --help 2>/dev/null | grep -- -Bstatic > /dev/null \
-	  && $gcc_cv_ld --help 2>/dev/null | grep -- -Bdynamic > /dev/null; then
-		gcc_cv_ld_static_dynamic=yes
-	fi
+  # Check if linker supports -Bstatic/-Bdynamic option
+  if $gcc_cv_ld --help 2>/dev/null | grep -- -Bstatic > /dev/null \
+     && $gcc_cv_ld --help 2>/dev/null | grep -- -Bdynamic > /dev/null; then
+      gcc_cv_ld_static_dynamic=yes
+  else
+    case "$target" in
+      # Solaris 2 ld always supports -Bstatic/-Bdynamic.
+      *-*-solaris2*)
+        gcc_cv_ld_static_dynamic=yes
+        ;;
+    esac
+  fi
 fi
 if test x"$gcc_cv_ld_static_dynamic" = xyes; then
 	AC_DEFINE(HAVE_LD_STATIC_DYNAMIC, 1,
diff -r 72fce0443d71 gcc/testsuite/go.test/go-test.exp
--- a/gcc/testsuite/go.test/go-test.exp	Sat Jan 08 12:30:04 2011 +0100
+++ b/gcc/testsuite/go.test/go-test.exp	Sun Jan 09 12:31:06 2011 +0100
@@ -1,4 +1,4 @@ 
-#   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+#   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
 #   Written by Ian Lance Taylor <iant@google.com>.
 
 # This program is free software; you can redistribute it and/or modify
@@ -106,6 +106,41 @@ 
     file delete $filename
 }
 
+# N.B. Keep in sync with libgo/configure.ac.
+proc go-set-goarch { } {
+    global target_triplet
+
+    switch -glob $target_triplet {
+	"arm*-*-*" -
+	"ep9312*-*-*" -
+	"strongarm*-*-*" -
+	"xscale-*-*" {
+	    set goarch "arm"
+	}
+	"i?86-*-*" -
+	"x86_64-*-*" {
+	    if [check_effective_target_ilp32] {
+		set goarch "386"
+	    } else {
+		set goarch "amd64"
+	    }
+	}
+	"sparc*-*-*" {
+	    if [check_effective_target_ilp32] {
+		set goarch "sparc"
+	    } else {
+		set goarch "sparcv9"
+	    }
+	}
+	default {
+	    perror "$target_triplet: unhandled architecture"
+	    return ""
+	}	
+    }
+    verbose -log "Setting GOARCH=$goarch" 1
+    setenv GOARCH $goarch
+}
+
 proc go-gc-tests { } {
     global srcdir subdir
     global runtests
@@ -122,6 +157,9 @@ 
 	set DEFAULT_GOCFLAGS " -pedantic-errors"
     }
 
+    # Set GOARCH for tests that need it.
+    go-set-goarch
+
     # Running all the torture options takes too long and, since the
     # frontend ignores the standard options, it doesn't significantly
     # improve testing.
diff -r 72fce0443d71 libgo/Makefile.am
--- a/libgo/Makefile.am	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/Makefile.am	Sun Jan 09 12:31:06 2011 +0100
@@ -1,6 +1,6 @@ 
 # Makefile.am -- Go library Makefile.
 
-# Copyright 2009, 2010 The Go Authors. All rights reserved.
+# Copyright 2009, 2010, 2011 The Go Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
@@ -592,12 +592,19 @@ 
 	go/mime/mediatype.go \
 	go/mime/type.go
 
-if LIBGO_IS_RTEMS
-go_net_fd_os_file = go/net/fd_rtems.go
-go_net_newpollserver_file = go/net/newpollserver_rtems.go
-else
+if LIBGO_IS_LINUX
+# Uses epoll(2), probably Linux-specfic.
 go_net_fd_os_file = go/net/fd_linux.go
 go_net_newpollserver_file = go/net/newpollserver.go
+else
+# Uses select(2), probably portable.
+go_net_fd_os_file = go/net/fd_rtems.go
+if LIBGO_IS_SOLARIS
+# Solaris doesn't support self-connected sockets, it seems.
+go_net_newpollserver_file = go/net/newpollserver.go
+else
+go_net_newpollserver_file = go/net/newpollserver_rtems.go
+endif
 endif
 
 go_net_files = \
@@ -684,34 +691,46 @@ 
 if LIBGO_IS_386
 GOARCH = 386
 else
+if LIBGO_IS_ARM
+GOARCH = arm
+else
+if LIBGO_IS_SPARC
+GOARCH = sparc
+else
+if LIBGO_IS_SPARCV9
+GOARCH = sparcv9
+else
 if LIBGO_IS_X86_64
 GOARCH = amd64
 else
-if LIBGO_IS_ARM
-GOARCH = arm
-else
 GOARCH = unknown
 endif
 endif
 endif
+endif
+endif
 
-if LIBGO_IS_LINUX
-GOOS = linux
-else
 if LIBGO_IS_DARWIN
 GOOS = darwin
 else
 if LIBGO_IS_FREEBSD
 GOOS = freebsd
 else
+if LIBGO_IS_LINUX
+GOOS = linux
+else
 if LIBGO_IS_RTEMS
 GOOS = rtems
 else
+if LIBGO_IS_SOLARIS
+GOOS = solaris
+else
 GOOS = unknown
 endif
 endif
 endif
 endif
+endif
 
 version.go: s-version; @true
 s-version: Makefile
@@ -929,18 +948,6 @@ 
 	go/debug/pe/file.go \
 	go/debug/pe/pe.go
 
-if LIBGO_IS_LINUX
-proc_file = go/debug/proc/proc_linux.go
-if LIBGO_IS_386
-regs_file = go/debug/proc/regs_linux_386.go
-else
-if LIBGO_IS_X86_64
-regs_file = go/debug/proc/regs_linux_amd64.go
-else
-regs_file =
-endif
-endif
-else
 if LIBGO_IS_DARWIN
 proc_file = go/debug/proc/proc_darwin.go
 if LIBGO_IS_386
@@ -965,6 +972,18 @@ 
 endif
 endif
 else
+if LIBGO_IS_LINUX
+proc_file = go/debug/proc/proc_linux.go
+if LIBGO_IS_386
+regs_file = go/debug/proc/regs_linux_386.go
+else
+if LIBGO_IS_X86_64
+regs_file = go/debug/proc/regs_linux_amd64.go
+else
+regs_file =
+endif
+endif
+else
 proc_file =
 regs_file =
 endif
@@ -1104,9 +1123,22 @@ 
 endif
 endif
 else
+if LIBGO_IS_SOLARIS
+syscall_os_file = syscalls/syscall_solaris.go
+if LIBGO_IS_386
+syscall_arch_file = syscalls/syscall_solaris_386.go
+else
+if LIBGO_IS_X86_64
+syscall_arch_file = syscalls/syscall_solaris_amd64.go
+else
+syscall_arch_file =
+endif
+endif
+else
 syscall_os_file =
 syscall_arch_file =
 endif
+endif
 
 if LIBGO_IS_RTEMS
 syscall_exec_os_file = syscalls/exec_stubs.go
@@ -1118,12 +1150,35 @@ 
 syscall_errstr_decl_file = syscalls/errstr_decl_rtems.go
 else
 syscall_exec_os_file = syscalls/exec.go
+if LIBGO_IS_LINUX
+syscall_socket_epoll_file = syscalls/socket_epoll.go
 syscall_socket_os_file = syscalls/socket_linux.go
-syscall_socket_epoll_file = syscalls/socket_epoll.go
-syscall_sysfile_os_file = syscalls/sysfile_linux.go
+else
+if LIBGO_IS_SOLARIS
+syscall_socket_os_file = syscalls/socket_solaris.go
+else
+# FIXME: Really everywhere else?
+syscall_socket_os_file = syscalls/socket_bsd.go
+endif
+endif
+# FIXME: Works beyond Linux?
 syscall_syscall_file = syscalls/syscall.go
 syscall_errstr_file = syscalls/errstr.go
 if LIBGO_IS_LINUX
+syscall_sysfile_os_file = syscalls/sysfile_linux.go
+else
+if LIBGO_IS_SOLARIS
+syscall_sysfile_os_file = syscalls/sysfile_solaris.go
+if LIBGO_IS_386
+syscall_sysfile_arch_file = syscalls/sysfile_solaris_386.go
+else
+if LIBGO_IS_X86_64
+syscall_sysfile_arch_file = syscalls/sysfile_solaris_amd64.go
+endif
+endif
+endif
+endif
+if LIBGO_IS_LINUX
 syscall_errstr_decl_file = syscalls/errstr_decl_linux.go
 else
 syscall_errstr_decl_file = syscalls/errstr_decl.go
@@ -1145,6 +1200,7 @@ 
 	$(syscall_arch_file) \
 	syscalls/sysfile_posix.go \
 	$(syscall_sysfile_os_file) \
+	$(syscall_sysfile_arch_file) \
 	sysinfo.go
 go_syscall_c_files = \
 	syscalls/errno.c
@@ -1268,7 +1324,10 @@ 
 
 libgo_la_SOURCES = $(runtime_files)
 
-libgo_la_LIBADD = $(libgo_go_objs) $(LIBFFI) $(PTHREAD_LIBS) $(MATH_LIBS)
+libgo_la_LDFLAGS = -Wc,-shared-libgcc
+
+libgo_la_LIBADD = $(libgo_go_objs) $(LIBFFI) $(PTHREAD_LIBS) $(MATH_LIBS) \
+	$(NET_LIBS)
 
 libgobegin_a_SOURCES = \
 	runtime/go-main.c
@@ -1282,9 +1341,8 @@ 
 LTGOCOMPILE = $(LIBTOOL) --tag GO --mode=compile $(GOC) $(INCLUDES) \
 	$(AM_GOCFLAGS) $(GOCFLAGS)
 
-GOLINK = $(LIBTOOL) --tag GO --mode-link $(GOC) \
-	$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_GOCFLAGS) $(LTLDFLAGS) \
-	$(PTHREAD_LIBS) $(MATH_LIBS) -o $@
+GOLINK = $(LIBTOOL) --tag GO --mode=link $(GOC) \
+	$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_GOCFLAGS) $(LTLDFLAGS) -o $@
 
 # Build a package.
 BUILDARCHIVE = \
@@ -1315,10 +1373,10 @@ 
 	MAKE="$(MAKE)"; \
 	export MAKE; \
 	rm -f $@-log; \
-	echo -n "$(@D) " >$@-log 2>&1; \
+	$(ECHO) $(ECHO_N) "$(@D) " >$@-log 2>&1; \
 	prefix=`if test "$(@D)" = "regexp"; then echo regexp-test; else dirname $(@D); fi`; \
 	test "$${prefix}" != "." || prefix="$(@D)"; \
-	$(srcdir)/testsuite/gotest --dejagnu=$(use_dejagnu) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --prefix="libgo_$${prefix}" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" >>$@-log 2>&1; \
+	NM="$(NM)" $(srcdir)/testsuite/gotest --dejagnu=$(use_dejagnu) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --prefix="libgo_$${prefix}" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" >>$@-log 2>&1; \
 	x=$$?; \
 	cat $@-log; \
 	exit $$x
@@ -2306,7 +2364,7 @@ 
 .PHONY: testing/script/check
 
 sysinfo.go: $(srcdir)/mksysinfo.sh config.h
-	$(SHELL) $(srcdir)/mksysinfo.sh
+	CC="$(CC)" $(SHELL) $(srcdir)/mksysinfo.sh $(host_triplet)
 syscalls/libsyscall.a: $(go_syscall_files) $(go_syscall_c_files) sync.gox
 	rm -f syscall.gox syscalls/libsyscall.a
 	test -d syscalls || $(MKDIR_P) syscalls
diff -r 72fce0443d71 libgo/configure.ac
--- a/libgo/configure.ac	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/configure.ac	Sun Jan 09 12:31:06 2011 +0100
@@ -1,6 +1,6 @@ 
 # configure.ac -- Go library configure script.
 
-# Copyright 2009 The Go Authors. All rights reserved.
+# Copyright 2009, 2011 The Go Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
@@ -36,6 +36,7 @@ 
 AC_PROG_LD
 AC_PROG_RANLIB
 AC_CHECK_TOOL(OBJCOPY, objcopy, missing-objcopy)
+AC_SUBST(ECHO)
 
 AC_LIBTOOL_DLOPEN
 AM_PROG_LIBTOOL
@@ -116,40 +117,68 @@ 
 is_freebsd=no
 is_linux=no
 is_rtems=no
+is_solaris=no
 case ${host} in
-  *-*-darwin*) is_darwin=yes ;;
-  *-*-freebsd*) is_freebsd=yes ;;
-  *-*-linux*)  is_linux=yes  ;;
-  *-*-rtems*)  is_rtems=yes  ;;
+  *-*-darwin*)   is_darwin=yes  ;;
+  *-*-freebsd*)  is_freebsd=yes ;;
+  *-*-linux*)    is_linux=yes   ;;
+  *-*-rtems*)    is_rtems=yes   ;;
+  *-*-solaris2*) is_solaris=yes ;;
 esac
 AM_CONDITIONAL(LIBGO_IS_DARWIN, test $is_darwin = yes)
 AM_CONDITIONAL(LIBGO_IS_FREEBSD, test $is_freebsd = yes)
 AM_CONDITIONAL(LIBGO_IS_LINUX, test $is_linux = yes)
 AM_CONDITIONAL(LIBGO_IS_RTEMS, test $is_rtems = yes)
+AM_CONDITIONAL(LIBGO_IS_SOLARIS, test $is_solaris = yes)
 
+# N.B. Keep in sync with gcc/testsuite/go.test/go-test.exp (go-set-goarch).
 is_386=no
+is_arm=no
+is_sparc=no
+is_sparcv9=no
 is_x86_64=no
-is_arm=no
 case ${host} in
+  arm*-*-* | ep9312*-*-* | strongarm*-*-* | xscale-*-*)
+    is_arm=yes
+    ;;
 changequote(,)dnl
   i[34567]86-*-*)
 changequote([,])dnl
-    is_386=yes
+    case "$with_multisubdir" in
+    amd64)
+      is_x86_64=yes
+      ;;
+    *)
+      is_386=yes
+      ;;
+    esac
+    ;;
+  sparc*-*-*)
+    case "$with_multilibsubdir" in
+    sparcv9)
+      is_sparcv9=yes
+      ;;
+    *)
+      is_sparc=yes
+      ;;
+    esac      
     ;;
   x86_64-*-*)
-    if test "$with_multisubdir" = "32"; then
+    case "$with_multisubdir" in
+    32)
       is_386=yes
-    else
+      ;;
+    *)
       is_x86_64=yes
-    fi
-    ;;
-  arm*-*-* | strongarm*-*-* | ep9312*-*-* | xscale-*-*)
-    is_arm=yes
+      ;;
+    esac
     ;;
 esac
 AM_CONDITIONAL(LIBGO_IS_386, test $is_386 = yes)
 AM_CONDITIONAL(LIBGO_IS_X86_64, test $is_x86_64 = yes)
 AM_CONDITIONAL(LIBGO_IS_ARM, test $is_arm = yes)
+AM_CONDITIONAL(LIBGO_IS_SPARC, test $is_sparc = yes)
+AM_CONDITIONAL(LIBGO_IS_SPARCV9, test $is_sparcv9 = yes)
 
 dnl Use -fsplit-stack when compiling C code if available.
 AC_CACHE_CHECK([whether -fsplit-stack is supported],
@@ -192,6 +221,13 @@ 
 AC_CHECK_LIB([m], [sqrt], MATH_LIBS=-lm)
 AC_SUBST(MATH_LIBS)
 
+dnl Test for the -lsocket library.
+NET_LIBS=
+dnl FIXME: How to do this properly?
+dnl There's code in libjava/configure.ac to handle this.
+NET_LIBS="-lsocket -lnsl"
+AC_SUBST(NET_LIBS)
+
 dnl Test whether the compiler supports the -pthread option.
 AC_CACHE_CHECK([whether -pthread is supported],
 [ac_cv_libgo_pthread_supported],
diff -r 72fce0443d71 libgo/mksysinfo.sh
--- a/libgo/mksysinfo.sh	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/mksysinfo.sh	Sun Jan 09 12:31:06 2011 +0100
@@ -1,6 +1,6 @@ 
 #!/bin/sh
 
-# Copyright 2009 The Go Authors. All rights reserved.
+# Copyright 2009, 2011 The Go Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
@@ -8,8 +8,8 @@ 
 
 # This shell script creates the sysinfo.go file which holds types and
 # constants extracted from the system header files.  This relies on a
-# hook in gcc: the -ggo option will generate debugging information in
-# Go syntax.
+# hook in gcc: the -fdump-go-spec option will generate debugging information
+# in Go syntax.
 
 # We currently #include all the files at once, which works, but leads
 # to exposing some names which ideally should not be exposed, as they
@@ -18,6 +18,7 @@ 
 
 CC=${CC:-gcc}
 OUT=tmp-sysinfo.go
+host=$1
 
 set -e
 
@@ -69,11 +70,16 @@ 
   grep -v '^func' | \
   grep -v '^type _timeval ' | \
   grep -v '^type _timespec ' | \
+  grep -v '^type _timestruc_t ' | \
   grep -v '^type _epoll_' | \
+  grep -v '^type _u\?pad128_t' | \
+  grep -v '^var _timezone' | \
+  grep -v '^var _utsname' | \
   grep -v 'in6_addr' | \
   grep -v 'sockaddr_in6' | \
   sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timestruc_t\([^a-zA-Z0-9_]\)/\1Timestruc\2/g' \
     >> ${OUT}
 
 # The errno constants.
@@ -83,6 +89,9 @@ 
 # The O_xxx flags.
 grep '^const _\(O\|F\|FD\)_' gen-sysinfo.go | \
   sed -e 's/^\(const \)_\([^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+if ! grep '^const O_ASYNC' ${OUT} >/dev/null 2>&1; then
+  echo "const O_ASYNC = 0" >> ${OUT}
+fi
 if ! grep '^const O_CLOEXEC' ${OUT} >/dev/null 2>&1; then
   echo "const O_CLOEXEC = 0" >> ${OUT}
 fi
@@ -195,26 +204,33 @@ 
 if ! grep '^const PTRACE_EVENT_EXIT' ${OUT} > /dev/null 2>&1; then
   echo "const PTRACE_EVENT_EXIT = 6" >> ${OUT}
 fi
+if ! grep '^const _PTRACE_TRACEME' ${OUT} > /dev/null 2>&1; then
+  echo "const _PTRACE_TRACEME = 0" >> ${OUT}
+fi
 
 # The registers returned by PTRACE_GETREGS.  This is probably
 # GNU/Linux specific.
-regs=`grep '^type _user_regs_struct struct' gen-sysinfo.go`
-if test "$regs" != ""; then
-  regs=`echo $regs | sed -e 's/type _user_regs_struct struct //' -e 's/[{}]//g'`
-  regs=`echo $regs | sed -e s'/^ *//'`
-  nregs=
-  while test -n "$regs"; do
-    field=`echo $regs | sed -e 's/^\([^;]*\);.*$/\1/'`
-    regs=`echo $regs | sed -e 's/^[^;]*; *\(.*\)$/\1/'`
-    # Capitalize the first character of the field.
-    f=`echo $field | sed -e 's/^\(.\).*$/\1/'`
-    r=`echo $field | sed -e 's/^.\(.*\)$/\1/'`
-    f=`echo $f | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
-    field="$f$r"
-    nregs="$nregs $field;"
-  done
-  echo "type PtraceRegs struct {$nregs }" >> ${OUT}
-fi
+case $host in
+*-*-linux*)
+  regs=`grep '^type _user_regs_struct struct' gen-sysinfo.go`
+  if test "$regs" != ""; then
+    regs=`echo $regs | sed -e 's/type _user_regs_struct struct //' -e 's/[{}]//g'`
+    regs=`echo $regs | sed -e s'/^ *//'`
+    nregs=
+    while test -n "$regs"; do
+      field=`echo $regs | sed -e 's/^\([^;]*\);.*$/\1/'`
+      regs=`echo $regs | sed -e 's/^[^;]*; *\(.*\)$/\1/'`
+      # Capitalize the first character of the field.
+      f=`echo $field | sed -e 's/^\(.\).*$/\1/'`
+      r=`echo $field | sed -e 's/^.\(.*\)$/\1/'`
+      f=`echo $f | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+      field="$f$r"
+      nregs="$nregs $field;"
+    done
+    echo "type PtraceRegs struct {$nregs }" >> ${OUT}
+  fi
+  ;;
+esac
 
 # Some basic types.
 echo 'type Size_t _size_t' >> ${OUT}
@@ -241,6 +257,16 @@ 
   exit 1
 fi
 
+# Work around -fdump-go-spec bug: float80 no longer exists.
+case $host in
+*-*-solaris2*)
+  grep '^type _pad128_t ' gen-sysinfo.go | \
+    sed -e 's/_q float80/_l [4]int32/g' >> ${OUT}
+  grep '^type _upad128_t ' gen-sysinfo.go | \
+    sed -e 's/_q float80/_l [4]uint32/g' >> ${OUT}
+  ;;
+esac
+
 # The time structures need special handling: we need to name the
 # types, so that we can cast integers to the right types when
 # assigning to the structures.
@@ -262,6 +288,15 @@ 
   sed -e 's/^type _timespec /type Timespec /' \
       -e 's/tv_sec *[a-zA-Z0-9_]*/Sec Timespec_sec_t/' \
       -e 's/tv_nsec *[a-zA-Z0-9_]*/Nsec Timespec_nsec_t/' >> ${OUT}
+timestruc=`grep '^type _timestruc_t ' gen-sysinfo.go`
+timestruc_sec=`echo $timestruc | sed -n -e 's/^.*tv_sec \([^ ]*\);.*$/\1/p'`
+timestruc_nsec=`echo $timestruc | sed -n -e 's/^.*tv_nsec \([^ ]*\);.*$/\1/p'`
+echo "type Timestruc_sec_t $timestruc_sec" >> ${OUT}
+echo "type Timestruc_nsec_t $timestruc_nsec" >> ${OUT}
+echo $timestruc | \
+  sed -e 's/^type _timestruc_t /type Timestruc /' \
+      -e 's/tv_sec *[a-zA-Z0-9_]*/Sec Timestruc_sec_t/' \
+      -e 's/tv_nsec *[a-zA-Z0-9_]*/Nsec Timestruc_nsec_t/' >> ${OUT}
 
 # The stat type.
 grep 'type _stat ' gen-sysinfo.go | \
@@ -281,6 +316,7 @@ 
       -e 's/st_ctim/Ctime/' \
       -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timestruc_t\([^a-zA-Z0-9_]\)/\1Timestruc\2/g' \
     >> ${OUT}
 
 # The directory searching types.
@@ -309,9 +345,10 @@ 
     f=`echo $field | sed -e 's/^\(.\).*$/\1/'`
     r=`echo $field | sed -e 's/^.\(.*\)$/\1/'`
     f=`echo $f | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
-    # Fix _timeval and _timespec.
+    # Fix _timeval, _timespec, and _timestruc_t.
     r=`echo $r | sed -e s'/ _timeval$/ Timeval/'`
     r=`echo $r | sed -e s'/ _timespec$/ Timespec/'`
+    r=`echo $r | sed -e s'/ _timestruc_t$/ Timestruc/'`
     field="$f$r"
     nrusage="$nrusage $field;"
   done
diff -r 72fce0443d71 libgo/runtime/go-go.c
--- a/libgo/runtime/go-go.c	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/runtime/go-go.c	Sun Jan 09 12:31:06 2011 +0100
@@ -1,6 +1,6 @@ 
 /* go-go.c -- the go function.
 
-   Copyright 2009 The Go Authors. All rights reserved.
+   Copyright 2009, 2011 The Go Authors. All rights reserved.
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
@@ -196,7 +196,21 @@ 
 #endif
   i = pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
   __go_assert (i == 0);
+
+#else /* !LINKER_SUPPORTS_SPLIT_STACK */
+
+#if defined __sun__ && defined __svr4__
+  /* Reduce the thread stack size from the Solaris 2 default of 1 MB
+     (32-bit) or 2 MB (64-bit) to allow go.test/test/chan/goroutines.go to
+     work.  The value is just a guess.  */
+#ifndef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN (128*1024)
 #endif
+  i = pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+  __go_assert (i == 0);
+#endif /* __sun__ && __svr4__ */
+
+#endif /* !LINKER_SUPPORTS_SPLIT_STACK */
 
   newm = __go_alloc (sizeof (M));
 
diff -r 72fce0443d71 libgo/syscalls/socket.go
--- a/libgo/syscalls/socket.go	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/syscalls/socket.go	Sun Jan 09 12:31:06 2011 +0100
@@ -1,6 +1,6 @@ 
 // socket.go -- Socket handling.
 
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009, 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
@@ -12,6 +12,7 @@ 
 
 import "unsafe"
 
+// FIXME: Partially Linux-specific, at least SizeofSockaddrInet6.
 const SizeofSockaddrInet4 = 16
 const SizeofSockaddrInet6 = 28
 const SizeofSockaddrUnix = 110
diff -r 72fce0443d71 libgo/syscalls/socket_solaris.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/socket_solaris.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,144 @@ 
+// socket_linux.go -- Socket handling specific to Solaris.
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Low-level socket interface.
+// Only for implementing net package.
+
+// DO NOT USE DIRECTLY.
+
+package syscall
+
+import "unsafe"
+
+type RawSockaddrInet4 struct {
+	Family uint16;
+	Port uint16;
+	Addr [4]byte /* in_addr */;
+	Zero [8]uint8;
+}
+
+type RawSockaddrInet6 struct {
+	Family uint16;
+	Port uint16;
+	Flowinfo uint32;
+	Addr [16]byte /* in6_addr */;
+	Scope_id uint32;
+	__Src_id uint32;
+}
+
+type RawSockaddrUnix struct {
+	Family uint16;
+	Path [108]int8;
+}
+
+type RawSockaddr struct {
+	Family uint16;
+	Data [14]int8;
+}
+
+func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL;
+	}
+	sa.raw.Family = AF_INET;
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port));
+	p[0] = byte(sa.Port>>8);
+	p[1] = byte(sa.Port);
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i];
+	}
+	return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, 0;
+}
+
+func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL;
+	}
+	sa.raw.Family = AF_INET6;
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port));
+	p[0] = byte(sa.Port>>8);
+	p[1] = byte(sa.Port);
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i];
+	}
+	// FIXME: socket.go SizeofSockaddrInet6 is wrong on Solaris due to
+	// __sin6_src_id member.
+	//return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, 0;
+	return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6 + 4, 0;
+}
+
+func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
+	name := sa.Name;
+	n := len(name);
+	if n >= len(sa.raw.Path) || n == 0 {
+		return nil, 0, EINVAL;
+	}
+	sa.raw.Family = AF_UNIX;
+	for i := 0; i < n; i++ {
+		sa.raw.Path[i] = int8(name[i]);
+	}
+	if sa.raw.Path[0] == '@' {
+		sa.raw.Path[0] = 0;
+	}
+
+	// length is family, name, NUL.
+	return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), 1 + Socklen_t(n) + 1, 0;
+}
+
+func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
+	switch rsa.Addr.Family {
+	case AF_UNIX:
+		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa));
+		sa := new(SockaddrUnix);
+		if pp.Path[0] == 0 {
+			// "Abstract" Unix domain socket.
+			// Rewrite leading NUL as @ for textual display.
+			// (This is the standard convention.)
+			// Not friendly to overwrite in place,
+			// but the callers below don't care.
+			pp.Path[0] = '@';
+		}
+
+		// Assume path ends at NUL.
+		// This is not technically the Linux semantics for
+		// abstract Unix domain sockets--they are supposed
+		// to be uninterpreted fixed-size binary blobs--but
+		// everyone uses this convention.
+		n := 0;
+		for n < len(pp.Path) - 3 && pp.Path[n] != 0 {
+			n++;
+		}
+		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]));
+		sa.Name = string(bytes[0:n]);
+		return sa, 0;
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa));
+		sa := new(SockaddrInet4);
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port));
+		sa.Port = int(p[0])<<8 + int(p[1]);
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i];
+		}
+		return sa, 0;
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa));
+		sa := new(SockaddrInet6);
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port));
+		sa.Port = int(p[0])<<8 + int(p[1]);
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i];
+		}
+		return sa, 0;
+	}
+	return nil, EAFNOSUPPORT;
+}
+
+// BindToDevice binds the socket associated with fd to device.
+func BindToDevice(fd int, device string) (errno int) {
+	return ENOSYS
+}
diff -r 72fce0443d71 libgo/syscalls/syscall_solaris.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/syscall_solaris.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,7 @@ 
+// syscall_solaris.go -- Solaris 2 specific syscall interface.
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
diff -r 72fce0443d71 libgo/syscalls/syscall_solaris_386.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/syscall_solaris_386.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,19 @@ 
+// syscall_solaris_386.go -- Solaris/x86 specific support
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import "unsafe"
+
+const ARCH = "386"
+
+// FIXME: ptrace(3C) has this, but exec.go expects the next.
+//func libc_ptrace(request int, pid Pid_t, addr int, data int) int __asm__ ("ptrace")
+
+func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) int __asm__ ("ptrace")
+
+var dummy *byte
+const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy))
diff -r 72fce0443d71 libgo/syscalls/syscall_solaris_amd64.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/syscall_solaris_amd64.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,23 @@ 
+// syscall_solaris_amd64.go -- Solaris/x64 specific support
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import "unsafe"
+
+const ARCH = "amd64"
+
+// FIXME: ptrace(3C) has this, but exec.go expects the next.
+//func libc_ptrace(request int, pid Pid_t, addr int, data int) int __asm__ ("ptrace")
+
+// 64-bit ptrace(3C) doesn't exist
+func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) int {
+	errno := ENOSYS
+	return -1
+}
+
+var dummy *byte
+const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy))
diff -r 72fce0443d71 libgo/syscalls/sysfile_solaris.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/sysfile_solaris.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,33 @@ 
+// sysfile_solaris.go -- Solaris specific file handling.
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Support for basic Unix file operations.  This file simply
+// translates from Go data types to Unix data types, and handles
+// errno.  FIXME: This could probably be done mechanically.
+
+package syscall
+
+const OS = "solaris"
+
+func libc_setgroups(size Size_t, list *Gid_t) int __asm__ ("setgroups")
+
+func Sleep(nsec int64) (errno int) {
+	tv := NsecToTimeval(nsec);
+	n, err := Select(0, nil, nil, nil, &tv);
+	return err;
+}
+
+func Setgroups(gids []int) (errno int) {
+	if len(gids) == 0 {
+		return libc_setgroups(0, nil);
+	}
+
+	a := make([]Gid_t, len(gids));
+	for i, v := range gids {
+		a[i] = Gid_t(v);
+	}
+	return libc_setgroups(Size_t(len(a)), &a[0]);
+}
diff -r 72fce0443d71 libgo/syscalls/sysfile_solaris_386.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/sysfile_solaris_386.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,17 @@ 
+// sysfile_solaris_386.go -- 32-bit Solaris/x86 specific file handling.
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Support for basic Unix file operations.  This file simply
+// translates from Go data types to Unix data types, and handles
+// errno.  FIXME: This could probably be done mechanically.
+
+package syscall
+
+func libc_pread(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pread64")
+func libc_pwrite(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pwrite64")
+func libc_lseek64(int, Offset_t, int) Offset_t __asm__ ("lseek64")
+func libc_truncate64(path *byte, length Offset_t) int __asm__ ("truncate64")
+func libc_ftruncate64(fd int, length Offset_t) int __asm__ ("ftruncate64")
diff -r 72fce0443d71 libgo/syscalls/sysfile_solaris_amd64.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/sysfile_solaris_amd64.go	Sun Jan 09 12:31:06 2011 +0100
@@ -0,0 +1,17 @@ 
+// sysfile_solaris_amd64.go -- 64-bit Solaris/x86 specific file handling.
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Support for basic Unix file operations.  This file simply
+// translates from Go data types to Unix data types, and handles
+// errno.  FIXME: This could probably be done mechanically.
+
+package syscall
+
+func libc_pread(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pread")
+func libc_pwrite(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pwrite")
+func libc_lseek64(int, Offset_t, int) Offset_t __asm__ ("lseek")
+func libc_truncate64(path *byte, length Offset_t) int __asm__ ("truncate")
+func libc_ftruncate64(fd int, length Offset_t) int __asm__ ("ftruncate")
diff -r 72fce0443d71 libgo/testsuite/gotest
--- a/libgo/testsuite/gotest	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/testsuite/gotest	Sun Jan 09 12:31:06 2011 +0100
@@ -1,5 +1,5 @@ 
 #!/bin/sh
-# Copyright 2009 The Go Authors. All rights reserved.
+# Copyright 2009, 2011 The Go Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
@@ -272,7 +272,8 @@ 
 	# the grep -v eliminates methods and other special names
 	# that have multiple dots.
 	pattern='Test([^a-z].*)?'
-	tests=$(nm -s _gotest_.o $xofile | egrep ' T .*\.'$pattern'$' | grep -v '\..*\..*\.' | sed 's/.* //' | sed 's/.*\.\(.*\.\)/\1/')
+	# FIXME: nm options aren't portable.
+	tests=$(${NM:-nm} -ps _gotest_.o $xofile | egrep ' T .*\.'$pattern'$' | grep -v '\..*\..*\.' | sed 's/.* //' | sed 's/.*\.\(.*\.\)/\1/')
 	if [ "x$tests" = x ]; then
 		echo 'gotest: warning: no tests matching '$pattern in _gotest_.o $xofile 1>&2
 		exit 2
diff -r 72fce0443d71 libgo/testsuite/lib/libgo.exp
--- a/libgo/testsuite/lib/libgo.exp	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/testsuite/lib/libgo.exp	Sun Jan 09 12:31:06 2011 +0100
@@ -1,4 +1,4 @@ 
-# Copyright (C) 2010 Free Software Foundation, Inc.
+# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@ 
 if {$gccdir != ""} {
     set gccdir [file dirname $gccdir]
 }
-set GO_UNDER_TEST "$gccdir/gccgo -B$gccdir/"
+set GOC_UNDER_TEST "$gccdir/gccgo -B$gccdir/"
 set TESTING_IN_BUILD_TREE 1
 
 proc go_maybe_build_wrapper { args } {
diff -r 72fce0443d71 libgo/testsuite/libgo.testmain/testmain.exp
--- a/libgo/testsuite/libgo.testmain/testmain.exp	Sat Jan 08 12:30:04 2011 +0100
+++ b/libgo/testsuite/libgo.testmain/testmain.exp	Sun Jan 09 12:31:06 2011 +0100
@@ -1,4 +1,4 @@ 
-# Copyright (C) 2010 Free Software Foundation, Inc.
+# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -44,7 +44,8 @@ 
 }
 
 set object_files [glob -nocomplain "*.o"]
-regsub $gluefile $object_files "" object_files
+# FIXME: Not found, even with global gluefile!?
+#regsub $gluefile $object_files "" object_files
 
 lappend options $ld_options