diff mbox

[libgo] Improve IRIX 6.5 support (PR go/47515)

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

Commit Message

Rainer Orth April 20, 2011, 11 a.m. UTC
There are still a couple of open issues with libgo on IRIX 6.5.  This
patch fixes some of them.

* As documented in the autoconf manual, some versions of sed and grep
  cannot handle \? and/or \(, \).  The Solaris 8 tools are among them,
  so this patch avoids those constructs.

* test $mips_abi != "" produces an error message with some shells, so
  avoid the empty string.

* IRIX 6 has its timezone files in /usr/lib/locale/TZ.

* One issue I'd been fighting with since I didn't understand the gccgo
  error message

/vol/gcc/src/hg/trunk/irix/libgo/go/os/file.go:432:12: error: incompatible types in assignment (implicit assignment of 'syscall.Timeval' hidden field '_f0')

  was a compilation failure of the 64-bit libgo.  <sys/time.h> has

struct timeval {
#if _MIPS_SZLONG == 64
	__int32_t :32;
#endif
	time_t	tv_sec;		/* seconds */
	long	tv_usec;	/* and microseconds */
};

  which is converted into

type _timeval struct { _f0 int32; tv_sec int32; tv_usec int64; }

  Just changing the field name in mksysinfo.sh allows the compilation to
  succeed.

* IRIX needs its own socket_irix.go.

* IRIX syslog has the same issue as the Solaris one.   syslogd(1M) states 

     syslogd reads from the stream device /dev/log, from an Internet domain
     socket specified in /etc/services, and from the special device /dev/klog
     (to read kernel messages).

  so I'm reusing the libc syslog variant.  Since it isn't Solaris
  specific, I've renamed to file to syslog_libc.go.

The remaining changes should be self-explanatory.  With this patch, a
mainline IRIX 6.5 bootstrap with Go included succeeds, although there's
still a considerable number of testsuite failures.  Some of them seem to
be common with Solaris/SPARC, so I suspect some endianess issues.

	Rainer


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

	libgo:
	PR go/47515
	* mksysinfo.sh: Avoid \(, \), \? with grep, sed REs.
        Handle _f0 in IRIX 6.5 N64 struct timeval.
	(sysinfo.c) [__sgi__]: Move ...
	* configure.ac: ... here.
	(OSCFLAGS) [mips-sgi-irix6.5]: Define.
	(mips_abi): Initialize to unknown.
	* configure: Regenerate.
	* config.h.in: Regenerate.
	* syscalls/socket_irix.go: New file.
	* go/syslog/syslog_solaris.go: Rename to ...
	* go/syslog/syslog_libc.go: ... this.
	* Makefile.am (gogo_syslog_file) [LIBGO_IS_SOLARIS]: Reflect this.
	[LIBGO_IS_IRIX]: Use it here, too.
	[LIBGO_IS_IRIX] (syscall_socket_os_file): Use it.
	* Makefile.in: Regenerate.

	* go/time/zoneinfo_unix.go (zoneDir, zoneDir2): Remove.
	(setupZone): Handle IRIX 6 zoneDir.

	gcc/testsuite:
	* go.test/go-test.exp (go-set-goarch): Accept mips*-*-*.

Comments

Ian Lance Taylor April 25, 2011, 7:45 p.m. UTC | #1
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> 2011-01-30  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
> 	libgo:
> 	PR go/47515
> 	* mksysinfo.sh: Avoid \(, \), \? with grep, sed REs.
>         Handle _f0 in IRIX 6.5 N64 struct timeval.
> 	(sysinfo.c) [__sgi__]: Move ...
> 	* configure.ac: ... here.
> 	(OSCFLAGS) [mips-sgi-irix6.5]: Define.
> 	(mips_abi): Initialize to unknown.
> 	* configure: Regenerate.
> 	* config.h.in: Regenerate.
> 	* syscalls/socket_irix.go: New file.
> 	* go/syslog/syslog_solaris.go: Rename to ...
> 	* go/syslog/syslog_libc.go: ... this.
> 	* Makefile.am (gogo_syslog_file) [LIBGO_IS_SOLARIS]: Reflect this.
> 	[LIBGO_IS_IRIX]: Use it here, too.
> 	[LIBGO_IS_IRIX] (syscall_socket_os_file): Use it.
> 	* Makefile.in: Regenerate.
>
> 	* go/time/zoneinfo_unix.go (zoneDir, zoneDir2): Remove.
> 	(setupZone): Handle IRIX 6 zoneDir.
>
> 	gcc/testsuite:
> 	* go.test/go-test.exp (go-set-goarch): Accept mips*-*-*.


Approved and applied with a couple of minor tweaks.

Thanks.

Ian
diff mbox

Patch

diff --git a/gcc/testsuite/go.test/go-test.exp b/gcc/testsuite/go.test/go-test.exp
--- a/gcc/testsuite/go.test/go-test.exp
+++ b/gcc/testsuite/go.test/go-test.exp
@@ -140,7 +140,7 @@  proc go-set-goarch { } {
 		set goarch "amd64"
 	    }
 	}
-	"mips-*-*" {
+	"mips*-*-*" {
 	    if [check_no_compiler_messages mipso32 assembly {
 		#if _MIPS_SIM != _ABIO32
 		#error FOO
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -822,10 +822,14 @@  go_sync_files = \
 	go/sync/waitgroup.go
 
 if LIBGO_IS_SOLARIS
-go_syslog_file = go/syslog/syslog_solaris.go
+go_syslog_file = go/syslog/syslog_libc.go
+else
+if LIBGO_IS_IRIX
+go_syslog_file = go/syslog/syslog_libc.go
 else
 go_syslog_file = go/syslog/syslog_unix.go
 endif
+endif
 
 go_syslog_files = \
 	go/syslog/syslog.go \
@@ -1303,9 +1307,13 @@  else
 if LIBGO_IS_SOLARIS
 syscall_socket_os_file = syscalls/socket_solaris.go
 else
+if LIBGO_IS_IRIX
+syscall_socket_os_file = syscalls/socket_irix.go
+else
 syscall_socket_os_file = syscalls/socket_bsd.go
 endif
 endif
+endif
 
 # Support for epoll.
 if LIBGO_IS_LINUX
diff --git a/libgo/configure.ac b/libgo/configure.ac
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -144,7 +144,7 @@  is_386=no
 is_alpha=no
 is_arm=no
 is_m68k=no
-mips_abi=""
+mips_abi=unknown
 is_ppc=no
 is_ppc64=no
 is_sparc=no
@@ -237,7 +237,7 @@  AM_CONDITIONAL(LIBGO_IS_386, test $is_38
 AM_CONDITIONAL(LIBGO_IS_ALPHA, test $is_alpha = yes)
 AM_CONDITIONAL(LIBGO_IS_ARM, test $is_arm = yes)
 AM_CONDITIONAL(LIBGO_IS_M68K, test $is_m68k = yes)
-AM_CONDITIONAL(LIBGO_IS_MIPS, test $mips_abi != "")
+AM_CONDITIONAL(LIBGO_IS_MIPS, test $mips_abi != unknown)
 AM_CONDITIONAL(LIBGO_IS_MIPSO32, test $mips_abi = o32)
 AM_CONDITIONAL(LIBGO_IS_MIPSN32, test $mips_abi = n32)
 AM_CONDITIONAL(LIBGO_IS_MIPSN64, test $mips_abi = n64)
@@ -264,6 +264,11 @@  AC_SUBST(GO_DEBUG_PROC_REGS_OS_ARCH_FILE
 
 dnl Some targets need special flags to build sysinfo.go.
 case "$target" in
+    mips-sgi-irix6.5)
+	# IRIX 6 needs _XOPEN_SOURCE=500 for the XPG5 version of struct
+	# msghdr in <sys/socket.h>.
+	OSCFLAGS='-D_XOPEN_SOURCE=500'
+	;;
     *-*-solaris2.[[89]])
 	# Solaris 8/9 need this so struct msghdr gets the msg_control
 	# etc. fields in <sys/socket.h> (_XPG4_2).
diff --git a/libgo/go/syslog/syslog_solaris.go b/libgo/go/syslog/syslog_libc.go
rename from libgo/go/syslog/syslog_solaris.go
rename to libgo/go/syslog/syslog_libc.go
diff --git a/libgo/go/time/zoneinfo_unix.go b/libgo/go/time/zoneinfo_unix.go
--- a/libgo/go/time/zoneinfo_unix.go
+++ b/libgo/go/time/zoneinfo_unix.go
@@ -17,8 +17,6 @@  import (
 
 const (
 	headerSize = 4 + 16 + 4*7
-	zoneDir    = "/usr/share/zoneinfo/"
-	zoneDir2   = "/usr/share/lib/zoneinfo/"
 )
 
 // Simple I/O interface to binary blob of data.
@@ -211,16 +209,22 @@  func setupZone() {
 	// no $TZ means use the system default /etc/localtime.
 	// $TZ="" means use UTC.
 	// $TZ="foo" means use /usr/share/zoneinfo/foo.
+	// Many systems use /usr/share/zoneinfo, Solaris 2 has
+	// /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
+	zoneDirs := []string{"/usr/share/zoneinfo/",
+		             "/usr/share/lib/zoneinfo/",
+			     "/usr/lib/locale/TZ/"}
 
 	tz, err := os.Getenverror("TZ")
 	switch {
 	case err == os.ENOENV:
 		zones, _ = readinfofile("/etc/localtime")
 	case len(tz) > 0:
-		var ok bool
-		zones, ok = readinfofile(zoneDir + tz)
-		if !ok {
-			zones, _ = readinfofile(zoneDir2 + tz)
+		for _, zoneDir := range zoneDirs {
+			var ok bool;
+			if zones, ok = readinfofile(zoneDir + tz); ok {
+				return
+			}
 		}
 	case len(tz) == 0:
 		// do nothing: use UTC
diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -29,12 +29,6 @@  cat > sysinfo.c <<EOF
 #define _LARGEFILE_SOURCE
 #define _FILE_OFFSET_BITS 64
 
-#ifdef __sgi__
-/* IRIX 6 needs _XOPEN_SOURCE=500 for the XPG5 version of struct msghdr in
-   <sys/socket.h>.  */
-#define _XOPEN_SOURCE 500
-#endif
-
 #include <sys/types.h>
 #include <dirent.h>
 #include <errno.h>
@@ -90,13 +84,15 @@  echo 'package syscall' > ${OUT}
 grep -v '^// ' gen-sysinfo.go | \
   grep -v '^func' | \
   grep -v '^type _timeval ' | \
-  grep -v '^type _timespec\(_t\)\? ' | \
+  grep -v '^type _timespec_t ' | \
+  grep -v '^type _timespec ' | \
   grep -v '^type _timestruc_t ' | \
   grep -v '^type _epoll_' | \
   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\(_t\)\?\([^a-zA-Z0-9_]\)/\1Timespec\3/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timespec_t\([^a-zA-Z0-9_]\)/\1Timespec\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}
 
@@ -294,10 +290,12 @@  timeval_sec=`echo $timeval | sed -n -e '
 timeval_usec=`echo $timeval | sed -n -e 's/^.*tv_usec \([^ ]*\);.*$/\1/p'`
 echo "type Timeval_sec_t $timeval_sec" >> ${OUT}
 echo "type Timeval_usec_t $timeval_usec" >> ${OUT}
+# IRIX 6.5 (N64 ABI) has an anonymous 32-bit field for padding.
 echo $timeval | \
   sed -e 's/type _timeval /type Timeval /' \
       -e 's/tv_sec *[a-zA-Z0-9_]*/Sec Timeval_sec_t/' \
-      -e 's/tv_usec *[a-zA-Z0-9_]*/Usec Timeval_usec_t/' >> ${OUT}
+      -e 's/tv_usec *[a-zA-Z0-9_]*/Usec Timeval_usec_t/' \
+      -e 's/_f0 /F0 /' >> ${OUT}
 timespec=`grep '^type _timespec ' gen-sysinfo.go || true`
 if test "$timespec" = ""; then
   # IRIX 6.5 has __timespec instead.
@@ -308,7 +306,8 @@  timespec_nsec=`echo $timespec | sed -n -
 echo "type Timespec_sec_t $timespec_sec" >> ${OUT}
 echo "type Timespec_nsec_t $timespec_nsec" >> ${OUT}
 echo $timespec | \
-  sed -e 's/^type \(__\)\?_timespec /type Timespec /' \
+  sed -e 's/^type ___timespec /type Timespec /' \
+      -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}
 
@@ -347,7 +346,8 @@  fi | sed -e 's/type _stat64/type Stat_t/
          -e 's/st_mtim/Mtime/' \
          -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\(_t\)\?\([^a-zA-Z0-9_]\)/\1Timespec\3/g' \
+         -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \
+         -e 's/\([^a-zA-Z0-9_]\)_timespec_t\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \
          -e 's/\([^a-zA-Z0-9_]\)_timestruc_t\([^a-zA-Z0-9_]\)/\1Timestruc\2/g' \
        >> ${OUT}
 
diff --git a/libgo/syscalls/socket_irix.go b/libgo/syscalls/socket_irix.go
new file mode 100644
--- /dev/null
+++ b/libgo/syscalls/socket_irix.go
@@ -0,0 +1,84 @@ 
+// socket_irix.go -- Socket handling specific to IRIX 6.
+
+// 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
+
+const SizeofSockaddrInet4 = 16
+const SizeofSockaddrInet6 = 28
+const SizeofSockaddrUnix = 110
+
+type RawSockaddrInet4 struct {
+	Family uint16
+	Port uint16
+	Addr [4]byte /* in_addr */
+	Zero [8]uint8
+}
+
+func (sa *RawSockaddrInet4) setLen() Socklen_t {
+	return SizeofSockaddrInet4
+}
+
+type RawSockaddrInet6 struct {
+	Family uint16
+	Port uint16
+	Flowinfo uint32
+	Addr [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+func (sa *RawSockaddrInet6) setLen() Socklen_t {
+	return SizeofSockaddrInet6
+}
+
+type RawSockaddrUnix struct {
+	Family uint16
+	Path [108]int8
+}
+
+func (sa *RawSockaddrUnix) setLen(int) {
+}
+
+func (sa *RawSockaddrUnix) getLen() (int, int) {
+	if sa.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.
+		sa.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(sa.Path) - 3 && sa.Path[n] != 0 {
+		n++
+	}
+
+	return n, 0
+}
+
+type RawSockaddr struct {
+	Family uint16
+	Data [14]int8
+}
+
+// BindToDevice binds the socket associated with fd to device.
+func BindToDevice(fd int, device string) (errno int) {
+	return ENOSYS
+}
+
+// struct ip_mreg is provived in <netinet/in.h>, but protected with _SGIAPI.
+// This could be enabled with -D_SGI_SOURCE, but conflicts with
+// -D_XOPEN_SOURCE=500 required for msg_control etc. in struct msghgr, so
+// simply provide it here.
+type IpMreq struct {
+	Multiaddr [4]byte
+	Interface [4]byte
+}