1#!/bin/sh 2 3# Copyright 2016 The Go Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style 5# license that can be found in the LICENSE file. 6 7# Create runtime_sysinfo.go from gen-sysinfo.go and errno.i. 8 9OUT=tmp-runtime_sysinfo.go 10 11set -e 12 13echo 'package runtime' > ${OUT} 14 15# Get all the consts and types, skipping ones which could not be 16# represented in Go and ones which we need to rewrite. We also skip 17# function declarations, as we don't need them here. All the symbols 18# will all have a leading underscore. 19grep -v '^// ' gen-sysinfo.go | \ 20 grep -v '^func' | \ 21 grep -v '^var ' | \ 22 grep -v '^type _timeval ' | \ 23 grep -v '^type _timespec_t ' | \ 24 grep -v '^type _timespec ' | \ 25 grep -v '^type _epoll_' | \ 26 grep -v '^type _*locale[_ ]' | \ 27 grep -v 'in6_addr' | \ 28 grep -v 'sockaddr_in6' | \ 29 sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1timeval\2/g' \ 30 -e 's/\([^a-zA-Z0-9_]\)_timespec_t\([^a-zA-Z0-9_]\)/\1timespec\2/g' \ 31 -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1timespec\2/g' \ 32 >> ${OUT} 33 34# The C long type, needed because that is the type that ptrace returns. 35sizeof_long=`grep '^const ___SIZEOF_LONG__ = ' gen-sysinfo.go | sed -e 's/.*= //'` 36if test "$sizeof_long" = "4"; then 37 echo "type _C_long int32" >> ${OUT} 38 echo "type _C_ulong uint32" >> ${OUT} 39elif test "$sizeof_long" = "8"; then 40 echo "type _C_long int64" >> ${OUT} 41 echo "type _C_ulong uint64" >> ${OUT} 42else 43 echo 1>&2 "mkrsysinfo.sh: could not determine size of long (got $sizeof_long)" 44 exit 1 45fi 46 47# On AIX, the _arpcom struct, is filtered by the above grep sequence, as it as 48# a field of type _in6_addr, but other types depend on _arpcom, so we need to 49# put it back. 50grep '^type _arpcom ' gen-sysinfo.go | \ 51 sed -e 's/_in6_addr/[16]byte/' >> ${OUT} 52 53# Same on Solaris for _mld_hdr_t. 54grep '^type _mld_hdr_t ' gen-sysinfo.go | \ 55 sed -e 's/_in6_addr/[16]byte/' >> ${OUT} 56 57# The time structures need special handling: we need to name the 58# types, so that we can cast integers to the right types when 59# assigning to the structures. 60timeval=`grep '^type _timeval ' gen-sysinfo.go` 61timeval_sec=`echo $timeval | sed -n -e 's/^.*tv_sec \([^ ]*\);.*$/\1/p'` 62timeval_usec=`echo $timeval | sed -n -e 's/^.*tv_usec \([^ ]*\);.*$/\1/p'` 63echo "type timeval_sec_t $timeval_sec" >> ${OUT} 64echo "type timeval_usec_t $timeval_usec" >> ${OUT} 65echo $timeval | \ 66 sed -e 's/type _timeval /type timeval /' \ 67 -e 's/tv_sec *[a-zA-Z0-9_]*/tv_sec timeval_sec_t/' \ 68 -e 's/tv_usec *[a-zA-Z0-9_]*/tv_usec timeval_usec_t/' >> ${OUT} 69echo >> ${OUT} 70echo "func (tv *timeval) set_usec(x int32) {" >> ${OUT} 71echo " tv.tv_usec = timeval_usec_t(x)" >> ${OUT} 72echo "}" >> ${OUT} 73 74timespec=`grep '^type _timespec ' gen-sysinfo.go || true` 75if test "$timespec" = ""; then 76 # IRIX 6.5 has __timespec instead. 77 timespec=`grep '^type ___timespec ' gen-sysinfo.go || true` 78fi 79timespec_sec=`echo $timespec | sed -n -e 's/^.*tv_sec \([^ ]*\);.*$/\1/p'` 80timespec_nsec=`echo $timespec | sed -n -e 's/^.*tv_nsec \([^ ]*\);.*$/\1/p'` 81echo "type timespec_sec_t $timespec_sec" >> ${OUT} 82echo "type timespec_nsec_t $timespec_nsec" >> ${OUT} 83echo $timespec | \ 84 sed -e 's/^type ___timespec /type timespec /' \ 85 -e 's/^type _timespec /type timespec /' \ 86 -e 's/tv_sec *[a-zA-Z0-9_]*/tv_sec timespec_sec_t/' \ 87 -e 's/tv_nsec *[a-zA-Z0-9_]*/tv_nsec timespec_nsec_t/' >> ${OUT} 88echo >> ${OUT} 89echo "func (ts *timespec) setNsec(ns int64) {" >> ${OUT} 90echo " ts.tv_sec = timespec_sec_t(ns / 1e9)" >> ${OUT} 91echo " ts.tv_nsec = timespec_nsec_t(ns % 1e9)" >> ${OUT} 92echo "}" >> ${OUT} 93echo >> ${OUT} 94 95# Define the epollevent struct. This needs special attention because 96# the C definition uses a union and is sometimes packed. 97if grep '^const _epoll_data_offset ' ${OUT} >/dev/null 2>&1; then 98 val=`grep '^const _epoll_data_offset ' ${OUT} | sed -e 's/const _epoll_data_offset = \(.*\)$/\1/'` 99 if test "$val" = "4"; then 100 echo 'type epollevent struct { events uint32; data [8]byte }' >> ${OUT} 101 elif test "$val" = "8"; then 102 if test "$GOARCH" = "sparc64" -a "$GOOS" = "linux"; then 103 echo 'type epollevent struct { events uint32; pad [4]byte; data [8]byte; _align [0]int64 }' >> ${OUT} 104 else 105 echo 'type epollevent struct { events uint32; pad [4]byte; data [8]byte }' >> ${OUT} 106 fi 107 else 108 echo 1>&2 "unknown epoll data offset value ${val}" 109 exit 1 110 fi 111fi 112# Make sure EPOLLET is positive. 113if grep '^const _EPOLLET = [0-9]' gen-sysinfo.go > /dev/null 2>&1; then 114 echo "const _EPOLLETpos = _EPOLLET" >> ${OUT} 115else 116 echo "const _EPOLLETpos = 0x80000000" >> ${OUT} 117fi 118# Make sure EPOLLRDHUP and EPOLL_CLOEXEC are defined. 119if ! grep '^const _EPOLLRDHUP' ${OUT} >/dev/null 2>&1; then 120 echo "const _EPOLLRDHUP = 0x2000" >> ${OUT} 121fi 122if ! grep '^const _EPOLL_CLOEXEC' ${OUT} >/dev/null 2>&1; then 123 echo "const _EPOLL_CLOEXEC = 02000000" >> ${OUT} 124fi 125 126# AIX 7.1 is a 64 bits value for _FCLOEXEC (referenced by O_CLOEXEC) 127# which leads to a constant overflow when using O_CLOEXEC in some 128# go code. Issue wan not present in 6.1 (no O_CLOEXEC) and is no 129# more present in 7.2 (_FCLOEXEC is a 32 bit value). 130if test "${GOOS}" = "aix" && `oslevel | grep -q "^7.1"`; then 131 sed -e 's/const __FCLOEXEC = .*/const __FCLOEXEC = 0/' ${OUT} > ${OUT}-2 132 mv ${OUT}-2 ${OUT} 133fi 134 135# Make sure _MAP_FAILED is defined. 136if ! grep '^const _MAP_FAILED =' gen-sysinfo.go > /dev/null 2>&1; then 137 echo "const _MAP_FAILED = ^uintptr(0)" >> ${OUT} 138fi 139# Make sure _MAP_ANON is defined. 140if ! grep '^const _MAP_ANON =' gen-sysinfo.go > /dev/null 2>&1; then 141 if grep '^const _MAP_ANONYMOUS ' gen-sysinfo.go > /dev/null 2>&1; then 142 echo "const _MAP_ANON = _MAP_ANONYMOUS" >> ${OUT} 143 else 144 echo "const _MAP_ANON = 0" >> ${OUT} 145 fi 146fi 147# Make sure _MADV_DONTNEED is defined. 148if ! grep '^const _MADV_DONTNEED =' gen-sysinfo.go > /dev/null 2>&1; then 149 echo "const _MADV_DONTNEED = 0" >> ${OUT} 150fi 151# Make sure _MADV_FREE is defined. 152if ! grep '^const _MADV_FREE =' gen-sysinfo.go > /dev/null 2>&1; then 153 echo "const _MADV_FREE = 0" >> ${OUT} 154fi 155# Make sure _MADV_HUGEPAGE is defined. 156if ! grep '^const _MADV_HUGEPAGE =' gen-sysinfo.go > /dev/null 2>&1; then 157 echo "const _MADV_HUGEPAGE = 0" >> ${OUT} 158fi 159# Make sure _MADV_NOHUGEPAGE is defined. 160if ! grep '^const _MADV_NOHUGEPAGE =' gen-sysinfo.go > /dev/null 2>&1; then 161 echo "const _MADV_NOHUGEPAGE = 0" >> ${OUT} 162fi 163 164# The semt structure, for Solaris. 165grep '^type _sem_t ' gen-sysinfo.go | \ 166 sed -e 's/_sem_t/semt/' >> ${OUT} 167 168# Solaris 2 needs _u?pad128_t, but its default definition in terms of long 169# double is commented by -fdump-go-spec. 170if grep "^// type _pad128_t" gen-sysinfo.go > /dev/null 2>&1; then 171 echo "type _pad128_t struct { _l [4]int32; }" >> ${OUT} 172fi 173if grep "^// type _upad128_t" gen-sysinfo.go > /dev/null 2>&1; then 174 echo "type _upad128_t struct { _l [4]uint32; }" >> ${OUT} 175fi 176 177# The Solaris 11 Update 1 _zone_net_addr_t struct. 178grep '^type _zone_net_addr_t ' gen-sysinfo.go | \ 179 sed -e 's/_in6_addr/[16]byte/' \ 180 >> ${OUT} 181 182# The Solaris 11.4 _flow_arp_desc_t struct. 183grep '^type _flow_arp_desc_t ' gen-sysinfo.go | \ 184 sed -e 's/_in6_addr_t/[16]byte/g' \ 185 >> ${OUT} 186 187# The Solaris 11.4 _flow_l3_desc_t struct. 188grep '^type _flow_l3_desc_t ' gen-sysinfo.go | \ 189 sed -e 's/_in6_addr_t/[16]byte/g' \ 190 >> ${OUT} 191 192# The Solaris 11.3 _mac_ipaddr_t struct. 193grep '^type _mac_ipaddr_t ' gen-sysinfo.go | \ 194 sed -e 's/_in6_addr_t/[16]byte/g' \ 195 >> ${OUT} 196 197# The Solaris 11.3 _mactun_info_t struct. 198grep '^type _mactun_info_t ' gen-sysinfo.go | \ 199 sed -e 's/_in6_addr_t/[16]byte/g' \ 200 >> ${OUT} 201 202# The Solaris port_event_t struct. 203grep '^type _port_event_t ' gen-sysinfo.go | \ 204 sed -e s'/_port_event_t/portevent/' \ 205 >> ${OUT} 206 207# The *BSD kevent struct. 208grep '^type _kevent ' gen-sysinfo.go | \ 209 sed -e s'/_kevent/keventt/' \ 210 -e 's/ udata [^;}]*/ udata *byte/' \ 211 >> ${OUT} 212 213# Type 'uint128' is needed in a couple of type definitions on arm64,such 214# as _user_fpsimd_struct, _elf_fpregset_t, etc. 215if ! grep '^type uint128' ${OUT} > /dev/null 2>&1; then 216 echo "type uint128 [16]byte" >> ${OUT} 217fi 218