mksyscall_aix_ppc64.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build ignore
  5. /*
  6. This program reads a file containing function prototypes
  7. (like syscall_aix.go) and generates system call bodies.
  8. The prototypes are marked by lines beginning with "//sys"
  9. and read like func declarations if //sys is replaced by func, but:
  10. * The parameter lists must give a name for each argument.
  11. This includes return parameters.
  12. * The parameter lists must give a type for each argument:
  13. the (x, y, z int) shorthand is not allowed.
  14. * If the return parameter is an error number, it must be named err.
  15. * If go func name needs to be different than its libc name,
  16. * or the function is not in libc, name could be specified
  17. * at the end, after "=" sign, like
  18. //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
  19. This program will generate three files and handle both gc and gccgo implementation:
  20. - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
  21. - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
  22. - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
  23. The generated code looks like this
  24. zsyscall_aix_ppc64.go
  25. func asyscall(...) (n int, err error) {
  26. // Pointer Creation
  27. r1, e1 := callasyscall(...)
  28. // Type Conversion
  29. // Error Handler
  30. return
  31. }
  32. zsyscall_aix_ppc64_gc.go
  33. //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
  34. //go:linkname libc_asyscall libc_asyscall
  35. var asyscall syscallFunc
  36. func callasyscall(...) (r1 uintptr, e1 Errno) {
  37. r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
  38. return
  39. }
  40. zsyscall_aix_ppc64_ggcgo.go
  41. // int asyscall(...)
  42. import "C"
  43. func callasyscall(...) (r1 uintptr, e1 Errno) {
  44. r1 = uintptr(C.asyscall(...))
  45. e1 = syscall.GetErrno()
  46. return
  47. }
  48. */
  49. package main
  50. import (
  51. "bufio"
  52. "flag"
  53. "fmt"
  54. "io/ioutil"
  55. "os"
  56. "regexp"
  57. "strings"
  58. )
  59. var (
  60. b32 = flag.Bool("b32", false, "32bit big-endian")
  61. l32 = flag.Bool("l32", false, "32bit little-endian")
  62. aix = flag.Bool("aix", false, "aix")
  63. tags = flag.String("tags", "", "build tags")
  64. )
  65. // cmdLine returns this programs's commandline arguments
  66. func cmdLine() string {
  67. return "go run mksyscall_aix_ppc64.go " + strings.Join(os.Args[1:], " ")
  68. }
  69. // buildTags returns build tags
  70. func buildTags() string {
  71. return *tags
  72. }
  73. // Param is function parameter
  74. type Param struct {
  75. Name string
  76. Type string
  77. }
  78. // usage prints the program usage
  79. func usage() {
  80. fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc64.go [-b32 | -l32] [-tags x,y] [file ...]\n")
  81. os.Exit(1)
  82. }
  83. // parseParamList parses parameter list and returns a slice of parameters
  84. func parseParamList(list string) []string {
  85. list = strings.TrimSpace(list)
  86. if list == "" {
  87. return []string{}
  88. }
  89. return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
  90. }
  91. // parseParam splits a parameter into name and type
  92. func parseParam(p string) Param {
  93. ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
  94. if ps == nil {
  95. fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
  96. os.Exit(1)
  97. }
  98. return Param{ps[1], ps[2]}
  99. }
  100. func main() {
  101. flag.Usage = usage
  102. flag.Parse()
  103. if len(flag.Args()) <= 0 {
  104. fmt.Fprintf(os.Stderr, "no files to parse provided\n")
  105. usage()
  106. }
  107. endianness := ""
  108. if *b32 {
  109. endianness = "big-endian"
  110. } else if *l32 {
  111. endianness = "little-endian"
  112. }
  113. pack := ""
  114. // GCCGO
  115. textgccgo := ""
  116. cExtern := "/*\n#include <stdint.h>\n"
  117. // GC
  118. textgc := ""
  119. dynimports := ""
  120. linknames := ""
  121. var vars []string
  122. // COMMON
  123. textcommon := ""
  124. for _, path := range flag.Args() {
  125. file, err := os.Open(path)
  126. if err != nil {
  127. fmt.Fprintf(os.Stderr, err.Error())
  128. os.Exit(1)
  129. }
  130. s := bufio.NewScanner(file)
  131. for s.Scan() {
  132. t := s.Text()
  133. t = strings.TrimSpace(t)
  134. t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
  135. if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
  136. pack = p[1]
  137. }
  138. nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
  139. if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
  140. continue
  141. }
  142. // Line must be of the form
  143. // func Open(path string, mode int, perm int) (fd int, err error)
  144. // Split into name, in params, out params.
  145. f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
  146. if f == nil {
  147. fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
  148. os.Exit(1)
  149. }
  150. funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
  151. // Split argument lists on comma.
  152. in := parseParamList(inps)
  153. out := parseParamList(outps)
  154. inps = strings.Join(in, ", ")
  155. outps = strings.Join(out, ", ")
  156. if sysname == "" {
  157. sysname = funct
  158. }
  159. onlyCommon := false
  160. if funct == "readlen" || funct == "writelen" || funct == "FcntlInt" || funct == "FcntlFlock" {
  161. // This function call another syscall which is already implemented.
  162. // Therefore, the gc and gccgo part must not be generated.
  163. onlyCommon = true
  164. }
  165. // Try in vain to keep people from editing this file.
  166. // The theory is that they jump into the middle of the file
  167. // without reading the header.
  168. textcommon += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
  169. if !onlyCommon {
  170. textgccgo += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
  171. textgc += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
  172. }
  173. // Check if value return, err return available
  174. errvar := ""
  175. rettype := ""
  176. for _, param := range out {
  177. p := parseParam(param)
  178. if p.Type == "error" {
  179. errvar = p.Name
  180. } else {
  181. rettype = p.Type
  182. }
  183. }
  184. sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
  185. sysname = strings.ToLower(sysname) // All libc functions are lowercase.
  186. // GCCGO Prototype return type
  187. cRettype := ""
  188. if rettype == "unsafe.Pointer" {
  189. cRettype = "uintptr_t"
  190. } else if rettype == "uintptr" {
  191. cRettype = "uintptr_t"
  192. } else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
  193. cRettype = "uintptr_t"
  194. } else if rettype == "int" {
  195. cRettype = "int"
  196. } else if rettype == "int32" {
  197. cRettype = "int"
  198. } else if rettype == "int64" {
  199. cRettype = "long long"
  200. } else if rettype == "uint32" {
  201. cRettype = "unsigned int"
  202. } else if rettype == "uint64" {
  203. cRettype = "unsigned long long"
  204. } else {
  205. cRettype = "int"
  206. }
  207. if sysname == "exit" {
  208. cRettype = "void"
  209. }
  210. // GCCGO Prototype arguments type
  211. var cIn []string
  212. for i, param := range in {
  213. p := parseParam(param)
  214. if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
  215. cIn = append(cIn, "uintptr_t")
  216. } else if p.Type == "string" {
  217. cIn = append(cIn, "uintptr_t")
  218. } else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
  219. cIn = append(cIn, "uintptr_t", "size_t")
  220. } else if p.Type == "unsafe.Pointer" {
  221. cIn = append(cIn, "uintptr_t")
  222. } else if p.Type == "uintptr" {
  223. cIn = append(cIn, "uintptr_t")
  224. } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
  225. cIn = append(cIn, "uintptr_t")
  226. } else if p.Type == "int" {
  227. if (i == 0 || i == 2) && funct == "fcntl" {
  228. // These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
  229. cIn = append(cIn, "uintptr_t")
  230. } else {
  231. cIn = append(cIn, "int")
  232. }
  233. } else if p.Type == "int32" {
  234. cIn = append(cIn, "int")
  235. } else if p.Type == "int64" {
  236. cIn = append(cIn, "long long")
  237. } else if p.Type == "uint32" {
  238. cIn = append(cIn, "unsigned int")
  239. } else if p.Type == "uint64" {
  240. cIn = append(cIn, "unsigned long long")
  241. } else {
  242. cIn = append(cIn, "int")
  243. }
  244. }
  245. if !onlyCommon {
  246. // GCCGO Prototype Generation
  247. // Imports of system calls from libc
  248. if sysname == "select" {
  249. // select is a keyword of Go. Its name is
  250. // changed to c_select.
  251. cExtern += "#define c_select select\n"
  252. }
  253. cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
  254. cIn := strings.Join(cIn, ", ")
  255. cExtern += fmt.Sprintf("(%s);\n", cIn)
  256. }
  257. // GC Library name
  258. if modname == "" {
  259. modname = "libc.a/shr_64.o"
  260. } else {
  261. fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
  262. os.Exit(1)
  263. }
  264. sysvarname := fmt.Sprintf("libc_%s", sysname)
  265. if !onlyCommon {
  266. // GC Runtime import of function to allow cross-platform builds.
  267. dynimports += fmt.Sprintf("//go:cgo_import_dynamic %s %s \"%s\"\n", sysvarname, sysname, modname)
  268. // GC Link symbol to proc address variable.
  269. linknames += fmt.Sprintf("//go:linkname %s %s\n", sysvarname, sysvarname)
  270. // GC Library proc address variable.
  271. vars = append(vars, sysvarname)
  272. }
  273. strconvfunc := "BytePtrFromString"
  274. strconvtype := "*byte"
  275. // Go function header.
  276. if outps != "" {
  277. outps = fmt.Sprintf(" (%s)", outps)
  278. }
  279. if textcommon != "" {
  280. textcommon += "\n"
  281. }
  282. textcommon += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
  283. // Prepare arguments tocall.
  284. var argscommon []string // Arguments in the common part
  285. var argscall []string // Arguments for call prototype
  286. var argsgc []string // Arguments for gc call (with syscall6)
  287. var argsgccgo []string // Arguments for gccgo call (with C.name_of_syscall)
  288. n := 0
  289. argN := 0
  290. for _, param := range in {
  291. p := parseParam(param)
  292. if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
  293. argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.Name))
  294. argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
  295. argsgc = append(argsgc, p.Name)
  296. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
  297. } else if p.Type == "string" && errvar != "" {
  298. textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
  299. textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
  300. textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
  301. argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
  302. argscall = append(argscall, fmt.Sprintf("_p%d uintptr ", n))
  303. argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
  304. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
  305. n++
  306. } else if p.Type == "string" {
  307. fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
  308. textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
  309. textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
  310. textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
  311. argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
  312. argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n))
  313. argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
  314. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
  315. n++
  316. } else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
  317. // Convert slice into pointer, length.
  318. // Have to be careful not to take address of &a[0] if len == 0:
  319. // pass nil in that case.
  320. textcommon += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
  321. textcommon += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
  322. argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("len(%s)", p.Name))
  323. argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n), fmt.Sprintf("_lenp%d int", n))
  324. argsgc = append(argsgc, fmt.Sprintf("_p%d", n), fmt.Sprintf("uintptr(_lenp%d)", n))
  325. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n), fmt.Sprintf("C.size_t(_lenp%d)", n))
  326. n++
  327. } else if p.Type == "int64" && endianness != "" {
  328. fmt.Fprintf(os.Stderr, path+":"+funct+" uses int64 with 32 bits mode. Case not yet implemented\n")
  329. } else if p.Type == "bool" {
  330. fmt.Fprintf(os.Stderr, path+":"+funct+" uses bool. Case not yet implemented\n")
  331. } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil || p.Type == "unsafe.Pointer" {
  332. argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
  333. argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
  334. argsgc = append(argsgc, p.Name)
  335. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
  336. } else if p.Type == "int" {
  337. if (argN == 0 || argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt") || (funct == "FcntlFlock")) {
  338. // These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
  339. argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
  340. argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
  341. argsgc = append(argsgc, p.Name)
  342. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
  343. } else {
  344. argscommon = append(argscommon, p.Name)
  345. argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
  346. argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
  347. argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
  348. }
  349. } else if p.Type == "int32" {
  350. argscommon = append(argscommon, p.Name)
  351. argscall = append(argscall, fmt.Sprintf("%s int32", p.Name))
  352. argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
  353. argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
  354. } else if p.Type == "int64" {
  355. argscommon = append(argscommon, p.Name)
  356. argscall = append(argscall, fmt.Sprintf("%s int64", p.Name))
  357. argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
  358. argsgccgo = append(argsgccgo, fmt.Sprintf("C.longlong(%s)", p.Name))
  359. } else if p.Type == "uint32" {
  360. argscommon = append(argscommon, p.Name)
  361. argscall = append(argscall, fmt.Sprintf("%s uint32", p.Name))
  362. argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
  363. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uint(%s)", p.Name))
  364. } else if p.Type == "uint64" {
  365. argscommon = append(argscommon, p.Name)
  366. argscall = append(argscall, fmt.Sprintf("%s uint64", p.Name))
  367. argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
  368. argsgccgo = append(argsgccgo, fmt.Sprintf("C.ulonglong(%s)", p.Name))
  369. } else if p.Type == "uintptr" {
  370. argscommon = append(argscommon, p.Name)
  371. argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
  372. argsgc = append(argsgc, p.Name)
  373. argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
  374. } else {
  375. argscommon = append(argscommon, fmt.Sprintf("int(%s)", p.Name))
  376. argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
  377. argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
  378. argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
  379. }
  380. argN++
  381. }
  382. nargs := len(argsgc)
  383. // COMMON function generation
  384. argscommonlist := strings.Join(argscommon, ", ")
  385. callcommon := fmt.Sprintf("call%s(%s)", sysname, argscommonlist)
  386. ret := []string{"_", "_"}
  387. body := ""
  388. doErrno := false
  389. for i := 0; i < len(out); i++ {
  390. p := parseParam(out[i])
  391. reg := ""
  392. if p.Name == "err" {
  393. reg = "e1"
  394. ret[1] = reg
  395. doErrno = true
  396. } else {
  397. reg = "r0"
  398. ret[0] = reg
  399. }
  400. if p.Type == "bool" {
  401. reg = fmt.Sprintf("%s != 0", reg)
  402. }
  403. if reg != "e1" {
  404. body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
  405. }
  406. }
  407. if ret[0] == "_" && ret[1] == "_" {
  408. textcommon += fmt.Sprintf("\t%s\n", callcommon)
  409. } else {
  410. textcommon += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], callcommon)
  411. }
  412. textcommon += body
  413. if doErrno {
  414. textcommon += "\tif e1 != 0 {\n"
  415. textcommon += "\t\terr = errnoErr(e1)\n"
  416. textcommon += "\t}\n"
  417. }
  418. textcommon += "\treturn\n"
  419. textcommon += "}\n"
  420. if onlyCommon {
  421. continue
  422. }
  423. // CALL Prototype
  424. callProto := fmt.Sprintf("func call%s(%s) (r1 uintptr, e1 Errno) {\n", sysname, strings.Join(argscall, ", "))
  425. // GC function generation
  426. asm := "syscall6"
  427. if nonblock != nil {
  428. asm = "rawSyscall6"
  429. }
  430. if len(argsgc) <= 6 {
  431. for len(argsgc) < 6 {
  432. argsgc = append(argsgc, "0")
  433. }
  434. } else {
  435. fmt.Fprintf(os.Stderr, "%s: too many arguments to system call", funct)
  436. os.Exit(1)
  437. }
  438. argsgclist := strings.Join(argsgc, ", ")
  439. callgc := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, argsgclist)
  440. textgc += callProto
  441. textgc += fmt.Sprintf("\tr1, _, e1 = %s\n", callgc)
  442. textgc += "\treturn\n}\n"
  443. // GCCGO function generation
  444. argsgccgolist := strings.Join(argsgccgo, ", ")
  445. var callgccgo string
  446. if sysname == "select" {
  447. // select is a keyword of Go. Its name is
  448. // changed to c_select.
  449. callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist)
  450. } else {
  451. callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
  452. }
  453. textgccgo += callProto
  454. textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo)
  455. textgccgo += "\te1 = syscall.GetErrno()\n"
  456. textgccgo += "\treturn\n}\n"
  457. }
  458. if err := s.Err(); err != nil {
  459. fmt.Fprintf(os.Stderr, err.Error())
  460. os.Exit(1)
  461. }
  462. file.Close()
  463. }
  464. imp := ""
  465. if pack != "unix" {
  466. imp = "import \"golang.org/x/sys/unix\"\n"
  467. }
  468. // Print zsyscall_aix_ppc64.go
  469. err := ioutil.WriteFile("zsyscall_aix_ppc64.go",
  470. []byte(fmt.Sprintf(srcTemplate1, cmdLine(), buildTags(), pack, imp, textcommon)),
  471. 0644)
  472. if err != nil {
  473. fmt.Fprintf(os.Stderr, err.Error())
  474. os.Exit(1)
  475. }
  476. // Print zsyscall_aix_ppc64_gc.go
  477. vardecls := "\t" + strings.Join(vars, ",\n\t")
  478. vardecls += " syscallFunc"
  479. err = ioutil.WriteFile("zsyscall_aix_ppc64_gc.go",
  480. []byte(fmt.Sprintf(srcTemplate2, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, textgc)),
  481. 0644)
  482. if err != nil {
  483. fmt.Fprintf(os.Stderr, err.Error())
  484. os.Exit(1)
  485. }
  486. // Print zsyscall_aix_ppc64_gccgo.go
  487. err = ioutil.WriteFile("zsyscall_aix_ppc64_gccgo.go",
  488. []byte(fmt.Sprintf(srcTemplate3, cmdLine(), buildTags(), pack, cExtern, imp, textgccgo)),
  489. 0644)
  490. if err != nil {
  491. fmt.Fprintf(os.Stderr, err.Error())
  492. os.Exit(1)
  493. }
  494. }
  495. const srcTemplate1 = `// %s
  496. // Code generated by the command above; see README.md. DO NOT EDIT.
  497. // +build %s
  498. package %s
  499. import (
  500. "unsafe"
  501. )
  502. %s
  503. %s
  504. `
  505. const srcTemplate2 = `// %s
  506. // Code generated by the command above; see README.md. DO NOT EDIT.
  507. // +build %s
  508. // +build !gccgo
  509. package %s
  510. import (
  511. "unsafe"
  512. )
  513. %s
  514. %s
  515. %s
  516. type syscallFunc uintptr
  517. var (
  518. %s
  519. )
  520. // Implemented in runtime/syscall_aix.go.
  521. func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
  522. func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
  523. %s
  524. `
  525. const srcTemplate3 = `// %s
  526. // Code generated by the command above; see README.md. DO NOT EDIT.
  527. // +build %s
  528. // +build gccgo
  529. package %s
  530. %s
  531. */
  532. import "C"
  533. import (
  534. "syscall"
  535. )
  536. %s
  537. %s
  538. `