Patchwork libgo patch committed: Fix GNU/Linux netlink code for big-endian

login
register
mail settings
Submitter Ian Taylor
Date April 3, 2012, 11:45 p.m.
Message ID <mcrmx6swfar.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/150568/
State New
Headers show

Comments

Ian Taylor - April 3, 2012, 11:45 p.m.
This patch to libgo fixes the support for GNU/Linux netlink code, used
to retrieve network interfaces, for big-endian systems.  Bootstrapped
and ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to
mainline and 4.7 branch.

Ian

Patch

diff -r a2de1f2e5bf8 libgo/Makefile.am
--- a/libgo/Makefile.am	Tue Apr 03 12:36:26 2012 -0700
+++ b/libgo/Makefile.am	Tue Apr 03 16:41:49 2012 -0700
@@ -1559,6 +1559,7 @@ 
 	echo "package syscall" > syscall_arch.go.tmp
 	echo 'const ARCH = "'$(GOARCH)'"' >> syscall_arch.go.tmp
 	echo 'const OS = "'$(GOOS)'"' >> syscall_arch.go.tmp
+	echo 'const BigEndian = $(GO_BIGENDIAN)' >> syscall_arch.go.tmp
 	$(SHELL) $(srcdir)/../move-if-change syscall_arch.go.tmp syscall_arch.go
 	$(STAMP) $@
 
diff -r a2de1f2e5bf8 libgo/configure.ac
--- a/libgo/configure.ac	Tue Apr 03 12:36:26 2012 -0700
+++ b/libgo/configure.ac	Tue Apr 03 16:41:49 2012 -0700
@@ -400,6 +400,12 @@ 
 AC_SEARCH_LIBS([sched_yield], [rt])
 
 AC_C_BIGENDIAN
+case $ac_cv_c_bigendian in
+  yes) GO_BIGENDIAN=true ;;
+  no) GO_BIGENDIAN=false ;;
+  *) AC_MSG_ERROR([unknown endianness]) ;;
+esac
+AC_SUBST(GO_BIGENDIAN)
 
 GCC_CHECK_UNWIND_GETIPINFO
 
diff -r a2de1f2e5bf8 libgo/go/net/interface_linux.go
--- a/libgo/go/net/interface_linux.go	Tue Apr 03 12:36:26 2012 -0700
+++ b/libgo/go/net/interface_linux.go	Tue Apr 03 16:41:49 2012 -0700
@@ -64,7 +64,11 @@ 
 		case syscall.IFLA_IFNAME:
 			ifi.Name = string(a.Value[:len(a.Value)-1])
 		case syscall.IFLA_MTU:
-			ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0]))
+			if syscall.BigEndian {
+				ifi.MTU = int(uint32(a.Value[0])<<24 | uint32(a.Value[1])<<16 | uint32(a.Value[2])<<8 | uint32(a.Value[3]))
+			} else {
+				ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0]))
+			}
 		}
 	}
 	return ifi
@@ -196,7 +200,12 @@ 
 				for i := 0; i+1 < len(f[0]); i += 2 {
 					b[i/2], _ = xtoi2(f[0][i:i+2], 0)
 				}
-				ifma := IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])}
+				var ifma IPAddr
+				if syscall.BigEndian {
+					ifma = IPAddr{IP: IPv4(b[0], b[1], b[2], b[3])}
+				} else {
+					ifma = IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])}
+				}
 				ifmat = append(ifmat, ifma.toAddr())
 			}
 		}
diff -r a2de1f2e5bf8 libgo/go/syscall/netlink_linux.go
--- a/libgo/go/syscall/netlink_linux.go	Tue Apr 03 12:36:26 2012 -0700
+++ b/libgo/go/syscall/netlink_linux.go	Tue Apr 03 16:41:49 2012 -0700
@@ -30,23 +30,43 @@ 
 
 func (rr *NetlinkRouteRequest) toWireFormat() []byte {
 	b := make([]byte, rr.Header.Len)
-	b[0] = byte(rr.Header.Len)
-	b[1] = byte(rr.Header.Len >> 8)
-	b[2] = byte(rr.Header.Len >> 16)
-	b[3] = byte(rr.Header.Len >> 24)
-	b[4] = byte(rr.Header.Type)
-	b[5] = byte(rr.Header.Type >> 8)
-	b[6] = byte(rr.Header.Flags)
-	b[7] = byte(rr.Header.Flags >> 8)
-	b[8] = byte(rr.Header.Seq)
-	b[9] = byte(rr.Header.Seq >> 8)
-	b[10] = byte(rr.Header.Seq >> 16)
-	b[11] = byte(rr.Header.Seq >> 24)
-	b[12] = byte(rr.Header.Pid)
-	b[13] = byte(rr.Header.Pid >> 8)
-	b[14] = byte(rr.Header.Pid >> 16)
-	b[15] = byte(rr.Header.Pid >> 24)
-	b[16] = byte(rr.Data.Family)
+	if BigEndian {
+		b[0] = byte(rr.Header.Len >> 24)
+		b[1] = byte(rr.Header.Len >> 16)
+		b[2] = byte(rr.Header.Len >> 8)
+		b[3] = byte(rr.Header.Len)
+		b[4] = byte(rr.Header.Type >> 8)
+		b[5] = byte(rr.Header.Type)
+		b[6] = byte(rr.Header.Flags >> 8)
+		b[7] = byte(rr.Header.Flags)
+		b[8] = byte(rr.Header.Seq >> 24)
+		b[9] = byte(rr.Header.Seq >> 16)
+		b[10] = byte(rr.Header.Seq >> 8)
+		b[11] = byte(rr.Header.Seq)
+		b[12] = byte(rr.Header.Pid >> 24)
+		b[13] = byte(rr.Header.Pid >> 16)
+		b[14] = byte(rr.Header.Pid >> 8)
+		b[15] = byte(rr.Header.Pid)
+		b[16] = byte(rr.Data.Family)
+	} else {
+		b[0] = byte(rr.Header.Len)
+		b[1] = byte(rr.Header.Len >> 8)
+		b[2] = byte(rr.Header.Len >> 16)
+		b[3] = byte(rr.Header.Len >> 24)
+		b[4] = byte(rr.Header.Type)
+		b[5] = byte(rr.Header.Type >> 8)
+		b[6] = byte(rr.Header.Flags)
+		b[7] = byte(rr.Header.Flags >> 8)
+		b[8] = byte(rr.Header.Seq)
+		b[9] = byte(rr.Header.Seq >> 8)
+		b[10] = byte(rr.Header.Seq >> 16)
+		b[11] = byte(rr.Header.Seq >> 24)
+		b[12] = byte(rr.Header.Pid)
+		b[13] = byte(rr.Header.Pid >> 8)
+		b[14] = byte(rr.Header.Pid >> 16)
+		b[15] = byte(rr.Header.Pid >> 24)
+		b[16] = byte(rr.Data.Family)
+	}
 	return b
 }