]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | #!/usr/bin/env perl |
2 | # Copyright 2018 The Go Authors. All rights reserved. | |
3 | # Use of this source code is governed by a BSD-style | |
4 | # license that can be found in the LICENSE file. | |
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 | ||
20 | # This program will generate three files and handle both gc and gccgo implementation: | |
21 | # - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation) | |
22 | # - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6 | |
23 | # - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type. | |
24 | ||
25 | # The generated code looks like this | |
26 | # | |
27 | # zsyscall_aix_ppc64.go | |
28 | # func asyscall(...) (n int, err error) { | |
29 | # // Pointer Creation | |
30 | # r1, e1 := callasyscall(...) | |
31 | # // Type Conversion | |
32 | # // Error Handler | |
33 | # return | |
34 | # } | |
35 | # | |
36 | # zsyscall_aix_ppc64_gc.go | |
37 | # //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o" | |
38 | # //go:linkname libc_asyscall libc_asyscall | |
39 | # var asyscall syscallFunc | |
40 | # | |
41 | # func callasyscall(...) (r1 uintptr, e1 Errno) { | |
42 | # r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... ) | |
43 | # return | |
44 | # } | |
45 | # | |
46 | # zsyscall_aix_ppc64_ggcgo.go | |
47 | # /* | |
48 | # int asyscall(...) | |
49 | # | |
50 | # */ | |
51 | # import "C" | |
52 | # | |
53 | # func callasyscall(...) (r1 uintptr, e1 Errno) { | |
54 | # r1 = uintptr(C.asyscall(...)) | |
55 | # e1 = syscall.GetErrno() | |
56 | # return | |
57 | # } | |
58 | ||
59 | ||
60 | ||
61 | use strict; | |
62 | ||
63 | my $cmdline = "mksyscall_aix_ppc64.pl " . join(' ', @ARGV); | |
64 | my $errors = 0; | |
65 | my $_32bit = ""; | |
66 | my $tags = ""; # build tags | |
67 | my $aix = 0; | |
68 | my $solaris = 0; | |
69 | ||
70 | binmode STDOUT; | |
71 | ||
72 | if($ARGV[0] eq "-b32") { | |
73 | $_32bit = "big-endian"; | |
74 | shift; | |
75 | } elsif($ARGV[0] eq "-l32") { | |
76 | $_32bit = "little-endian"; | |
77 | shift; | |
78 | } | |
79 | if($ARGV[0] eq "-aix") { | |
80 | $aix = 1; | |
81 | shift; | |
82 | } | |
83 | if($ARGV[0] eq "-tags") { | |
84 | shift; | |
85 | $tags = $ARGV[0]; | |
86 | shift; | |
87 | } | |
88 | ||
89 | if($ARGV[0] =~ /^-/) { | |
90 | print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n"; | |
91 | exit 1; | |
92 | } | |
93 | ||
94 | sub parseparamlist($) { | |
95 | my ($list) = @_; | |
96 | $list =~ s/^\s*//; | |
97 | $list =~ s/\s*$//; | |
98 | if($list eq "") { | |
99 | return (); | |
100 | } | |
101 | return split(/\s*,\s*/, $list); | |
102 | } | |
103 | ||
104 | sub parseparam($) { | |
105 | my ($p) = @_; | |
106 | if($p !~ /^(\S*) (\S*)$/) { | |
107 | print STDERR "$ARGV:$.: malformed parameter: $p\n"; | |
108 | $errors = 1; | |
109 | return ("xx", "int"); | |
110 | } | |
111 | return ($1, $2); | |
112 | } | |
113 | ||
114 | my $package = ""; | |
115 | # GCCGO | |
116 | my $textgccgo = ""; | |
117 | my $c_extern = "/*\n#include <stdint.h>\n"; | |
118 | # GC | |
119 | my $textgc = ""; | |
120 | my $dynimports = ""; | |
121 | my $linknames = ""; | |
122 | my @vars = (); | |
123 | # COMMUN | |
124 | my $textcommon = ""; | |
125 | ||
126 | while(<>) { | |
127 | chomp; | |
128 | s/\s+/ /g; | |
129 | s/^\s+//; | |
130 | s/\s+$//; | |
131 | $package = $1 if !$package && /^package (\S+)$/; | |
132 | my $nonblock = /^\/\/sysnb /; | |
133 | next if !/^\/\/sys / && !$nonblock; | |
134 | ||
135 | # Line must be of the form | |
136 | # func Open(path string, mode int, perm int) (fd int, err error) | |
137 | # Split into name, in params, out params. | |
138 | if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) { | |
139 | print STDERR "$ARGV:$.: malformed //sys declaration\n"; | |
140 | $errors = 1; | |
141 | next; | |
142 | } | |
143 | my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6); | |
144 | ||
145 | # Split argument lists on comma. | |
146 | my @in = parseparamlist($in); | |
147 | my @out = parseparamlist($out); | |
148 | ||
149 | $in = join(', ', @in); | |
150 | $out = join(', ', @out); | |
151 | ||
152 | if($sysname eq "") { | |
153 | $sysname = "$func"; | |
154 | } | |
155 | ||
156 | my $onlyCommon = 0; | |
157 | if ($func eq "readlen" || $func eq "writelen" || $func eq "FcntlInt" || $func eq "FcntlFlock") { | |
158 | # This function call another syscall which is already implemented. | |
159 | # Therefore, the gc and gccgo part must not be generated. | |
160 | $onlyCommon = 1 | |
161 | } | |
162 | ||
163 | # Try in vain to keep people from editing this file. | |
164 | # The theory is that they jump into the middle of the file | |
165 | # without reading the header. | |
166 | ||
167 | $textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; | |
168 | if (!$onlyCommon) { | |
169 | $textgccgo .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; | |
170 | $textgc .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; | |
171 | } | |
172 | ||
173 | ||
174 | # Check if value return, err return available | |
175 | my $errvar = ""; | |
176 | my $retvar = ""; | |
177 | my $rettype = ""; | |
178 | foreach my $p (@out) { | |
179 | my ($name, $type) = parseparam($p); | |
180 | if($type eq "error") { | |
181 | $errvar = $name; | |
182 | } else { | |
183 | $retvar = $name; | |
184 | $rettype = $type; | |
185 | } | |
186 | } | |
187 | ||
188 | ||
189 | $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; | |
190 | $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. | |
191 | ||
192 | # GCCGO Prototype return type | |
193 | my $C_rettype = ""; | |
194 | if($rettype eq "unsafe.Pointer") { | |
195 | $C_rettype = "uintptr_t"; | |
196 | } elsif($rettype eq "uintptr") { | |
197 | $C_rettype = "uintptr_t"; | |
198 | } elsif($rettype =~ /^_/) { | |
199 | $C_rettype = "uintptr_t"; | |
200 | } elsif($rettype eq "int") { | |
201 | $C_rettype = "int"; | |
202 | } elsif($rettype eq "int32") { | |
203 | $C_rettype = "int"; | |
204 | } elsif($rettype eq "int64") { | |
205 | $C_rettype = "long long"; | |
206 | } elsif($rettype eq "uint32") { | |
207 | $C_rettype = "unsigned int"; | |
208 | } elsif($rettype eq "uint64") { | |
209 | $C_rettype = "unsigned long long"; | |
210 | } else { | |
211 | $C_rettype = "int"; | |
212 | } | |
213 | if($sysname eq "exit") { | |
214 | $C_rettype = "void"; | |
215 | } | |
216 | ||
217 | # GCCGO Prototype arguments type | |
218 | my @c_in = (); | |
219 | foreach my $i (0 .. $#in) { | |
220 | my ($name, $type) = parseparam($in[$i]); | |
221 | if($type =~ /^\*/) { | |
222 | push @c_in, "uintptr_t"; | |
223 | } elsif($type eq "string") { | |
224 | push @c_in, "uintptr_t"; | |
225 | } elsif($type =~ /^\[\](.*)/) { | |
226 | push @c_in, "uintptr_t", "size_t"; | |
227 | } elsif($type eq "unsafe.Pointer") { | |
228 | push @c_in, "uintptr_t"; | |
229 | } elsif($type eq "uintptr") { | |
230 | push @c_in, "uintptr_t"; | |
231 | } elsif($type =~ /^_/) { | |
232 | push @c_in, "uintptr_t"; | |
233 | } elsif($type eq "int") { | |
234 | if (($i == 0 || $i == 2) && $func eq "fcntl"){ | |
235 | # These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock | |
236 | push @c_in, "uintptr_t"; | |
237 | } else { | |
238 | push @c_in, "int"; | |
239 | } | |
240 | } elsif($type eq "int32") { | |
241 | push @c_in, "int"; | |
242 | } elsif($type eq "int64") { | |
243 | push @c_in, "long long"; | |
244 | } elsif($type eq "uint32") { | |
245 | push @c_in, "unsigned int"; | |
246 | } elsif($type eq "uint64") { | |
247 | push @c_in, "unsigned long long"; | |
248 | } else { | |
249 | push @c_in, "int"; | |
250 | } | |
251 | } | |
252 | ||
253 | if (!$onlyCommon){ | |
254 | # GCCGO Prototype Generation | |
255 | # Imports of system calls from libc | |
256 | $c_extern .= "$C_rettype $sysname"; | |
257 | my $c_in = join(', ', @c_in); | |
258 | $c_extern .= "($c_in);\n"; | |
259 | } | |
260 | ||
261 | # GC Library name | |
262 | if($modname eq "") { | |
263 | $modname = "libc.a/shr_64.o"; | |
264 | } else { | |
265 | print STDERR "$func: only syscall using libc are available\n"; | |
266 | $errors = 1; | |
267 | next; | |
268 | } | |
269 | my $sysvarname = "libc_${sysname}"; | |
270 | ||
271 | if (!$onlyCommon){ | |
272 | # GC Runtime import of function to allow cross-platform builds. | |
273 | $dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname\"\n"; | |
274 | # GC Link symbol to proc address variable. | |
275 | $linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n"; | |
276 | # GC Library proc address variable. | |
277 | push @vars, $sysvarname; | |
278 | } | |
279 | ||
280 | my $strconvfunc ="BytePtrFromString"; | |
281 | my $strconvtype = "*byte"; | |
282 | ||
283 | # Go function header. | |
284 | if($out ne "") { | |
285 | $out = " ($out)"; | |
286 | } | |
287 | if($textcommon ne "") { | |
288 | $textcommon .= "\n" | |
289 | } | |
290 | ||
291 | $textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ; | |
292 | ||
293 | # Prepare arguments to call. | |
294 | my @argscommun = (); # Arguments in the commun part | |
295 | my @argscall = (); # Arguments for call prototype | |
296 | my @argsgc = (); # Arguments for gc call (with syscall6) | |
297 | my @argsgccgo = (); # Arguments for gccgo call (with C.name_of_syscall) | |
298 | my $n = 0; | |
299 | my $arg_n = 0; | |
300 | foreach my $p (@in) { | |
301 | my ($name, $type) = parseparam($p); | |
302 | if($type =~ /^\*/) { | |
303 | push @argscommun, "uintptr(unsafe.Pointer($name))"; | |
304 | push @argscall, "$name uintptr"; | |
305 | push @argsgc, "$name"; | |
306 | push @argsgccgo, "C.uintptr_t($name)"; | |
307 | } elsif($type eq "string" && $errvar ne "") { | |
308 | $textcommon .= "\tvar _p$n $strconvtype\n"; | |
309 | $textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n"; | |
310 | $textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; | |
311 | ||
312 | push @argscommun, "uintptr(unsafe.Pointer(_p$n))"; | |
313 | push @argscall, "_p$n uintptr "; | |
314 | push @argsgc, "_p$n"; | |
315 | push @argsgccgo, "C.uintptr_t(_p$n)"; | |
316 | $n++; | |
317 | } elsif($type eq "string") { | |
318 | print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; | |
319 | $textcommon .= "\tvar _p$n $strconvtype\n"; | |
320 | $textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n"; | |
321 | $textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; | |
322 | ||
323 | push @argscommun, "uintptr(unsafe.Pointer(_p$n))"; | |
324 | push @argscall, "_p$n uintptr"; | |
325 | push @argsgc, "_p$n"; | |
326 | push @argsgccgo, "C.uintptr_t(_p$n)"; | |
327 | $n++; | |
328 | } elsif($type =~ /^\[\](.*)/) { | |
329 | # Convert slice into pointer, length. | |
330 | # Have to be careful not to take address of &a[0] if len == 0: | |
331 | # pass nil in that case. | |
332 | $textcommon .= "\tvar _p$n *$1\n"; | |
333 | $textcommon .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; | |
334 | push @argscommun, "uintptr(unsafe.Pointer(_p$n))", "len($name)"; | |
335 | push @argscall, "_p$n uintptr", "_lenp$n int"; | |
336 | push @argsgc, "_p$n", "uintptr(_lenp$n)"; | |
337 | push @argsgccgo, "C.uintptr_t(_p$n)", "C.size_t(_lenp$n)"; | |
338 | $n++; | |
339 | } elsif($type eq "int64" && $_32bit ne "") { | |
340 | print STDERR "$ARGV:$.: $func uses int64 with 32 bits mode. Case not yet implemented\n"; | |
341 | # if($_32bit eq "big-endian") { | |
342 | # push @args, "uintptr($name >> 32)", "uintptr($name)"; | |
343 | # } else { | |
344 | # push @args, "uintptr($name)", "uintptr($name >> 32)"; | |
345 | # } | |
346 | # $n++; | |
347 | } elsif($type eq "bool") { | |
348 | print STDERR "$ARGV:$.: $func uses bool. Case not yet implemented\n"; | |
349 | # $text .= "\tvar _p$n uint32\n"; | |
350 | # $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n"; | |
351 | # push @args, "_p$n"; | |
352 | # $n++; | |
353 | } elsif($type =~ /^_/ ||$type eq "unsafe.Pointer") { | |
354 | push @argscommun, "uintptr($name)"; | |
355 | push @argscall, "$name uintptr"; | |
356 | push @argsgc, "$name"; | |
357 | push @argsgccgo, "C.uintptr_t($name)"; | |
358 | } elsif($type eq "int") { | |
359 | if (($arg_n == 0 || $arg_n == 2) && ($func eq "fcntl" || $func eq "FcntlInt" || $func eq "FcntlFlock")) { | |
360 | # These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock | |
361 | push @argscommun, "uintptr($name)"; | |
362 | push @argscall, "$name uintptr"; | |
363 | push @argsgc, "$name"; | |
364 | push @argsgccgo, "C.uintptr_t($name)"; | |
365 | } else { | |
366 | push @argscommun, "$name"; | |
367 | push @argscall, "$name int"; | |
368 | push @argsgc, "uintptr($name)"; | |
369 | push @argsgccgo, "C.int($name)"; | |
370 | } | |
371 | } elsif($type eq "int32") { | |
372 | push @argscommun, "$name"; | |
373 | push @argscall, "$name int32"; | |
374 | push @argsgc, "uintptr($name)"; | |
375 | push @argsgccgo, "C.int($name)"; | |
376 | } elsif($type eq "int64") { | |
377 | push @argscommun, "$name"; | |
378 | push @argscall, "$name int64"; | |
379 | push @argsgc, "uintptr($name)"; | |
380 | push @argsgccgo, "C.longlong($name)"; | |
381 | } elsif($type eq "uint32") { | |
382 | push @argscommun, "$name"; | |
383 | push @argscall, "$name uint32"; | |
384 | push @argsgc, "uintptr($name)"; | |
385 | push @argsgccgo, "C.uint($name)"; | |
386 | } elsif($type eq "uint64") { | |
387 | push @argscommun, "$name"; | |
388 | push @argscall, "$name uint64"; | |
389 | push @argsgc, "uintptr($name)"; | |
390 | push @argsgccgo, "C.ulonglong($name)"; | |
391 | } elsif($type eq "uintptr") { | |
392 | push @argscommun, "$name"; | |
393 | push @argscall, "$name uintptr"; | |
394 | push @argsgc, "$name"; | |
395 | push @argsgccgo, "C.uintptr_t($name)"; | |
396 | } else { | |
397 | push @argscommun, "int($name)"; | |
398 | push @argscall, "$name int"; | |
399 | push @argsgc, "uintptr($name)"; | |
400 | push @argsgccgo, "C.int($name)"; | |
401 | } | |
402 | $arg_n++; | |
403 | } | |
404 | my $nargs = @argsgc; | |
405 | ||
406 | # COMMUN function generation | |
407 | my $argscommun = join(', ', @argscommun); | |
408 | my $callcommun = "call$sysname($argscommun)"; | |
409 | my @ret = ("_", "_"); | |
410 | my $body = ""; | |
411 | my $do_errno = 0; | |
412 | for(my $i=0; $i<@out; $i++) { | |
413 | my $p = $out[$i]; | |
414 | my ($name, $type) = parseparam($p); | |
415 | my $reg = ""; | |
416 | if($name eq "err") { | |
417 | $reg = "e1"; | |
418 | $ret[1] = $reg; | |
419 | $do_errno = 1; | |
420 | } else { | |
421 | $reg = "r0"; | |
422 | $ret[0] = $reg; | |
423 | } | |
424 | if($type eq "bool") { | |
425 | $reg = "$reg != 0"; | |
426 | } | |
427 | if($reg ne "e1") { | |
428 | $body .= "\t$name = $type($reg)\n"; | |
429 | } | |
430 | } | |
431 | if ($ret[0] eq "_" && $ret[1] eq "_") { | |
432 | $textcommon .= "\t$callcommun\n"; | |
433 | } else { | |
434 | $textcommon .= "\t$ret[0], $ret[1] := $callcommun\n"; | |
435 | } | |
436 | $textcommon .= $body; | |
437 | ||
438 | if ($do_errno) { | |
439 | $textcommon .= "\tif e1 != 0 {\n"; | |
440 | $textcommon .= "\t\terr = errnoErr(e1)\n"; | |
441 | $textcommon .= "\t}\n"; | |
442 | } | |
443 | $textcommon .= "\treturn\n"; | |
444 | $textcommon .= "}\n"; | |
445 | ||
446 | if ($onlyCommon){ | |
447 | next | |
448 | } | |
449 | # CALL Prototype | |
450 | my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall); | |
451 | ||
452 | # GC function generation | |
453 | my $asm = "syscall6"; | |
454 | if ($nonblock) { | |
455 | $asm = "rawSyscall6"; | |
456 | } | |
457 | ||
458 | if(@argsgc <= 6) { | |
459 | while(@argsgc < 6) { | |
460 | push @argsgc, "0"; | |
461 | } | |
462 | } else { | |
463 | print STDERR "$ARGV:$.: too many arguments to system call\n"; | |
464 | } | |
465 | my $argsgc = join(', ', @argsgc); | |
466 | my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)"; | |
467 | ||
468 | $textgc .= $callProto; | |
469 | $textgc .= "\tr1, _, e1 = $callgc\n"; | |
470 | $textgc .= "\treturn\n}\n"; | |
471 | ||
472 | # GCCGO function generation | |
473 | my $argsgccgo = join(', ', @argsgccgo); | |
474 | my $callgccgo = "C.$sysname($argsgccgo)"; | |
475 | $textgccgo .= $callProto; | |
476 | $textgccgo .= "\tr1 = uintptr($callgccgo)\n"; | |
477 | $textgccgo .= "\te1 = syscall.GetErrno()\n"; | |
478 | $textgccgo .= "\treturn\n}\n"; | |
479 | } | |
480 | ||
481 | if($errors) { | |
482 | exit 1; | |
483 | } | |
484 | ||
485 | # Print zsyscall_aix_ppc64.go | |
486 | open(my $fcommun, '>', 'zsyscall_aix_ppc64.go'); | |
487 | my $tofcommun = <<EOF; | |
488 | // $cmdline | |
489 | // Code generated by the command above; see README.md. DO NOT EDIT. | |
490 | ||
491 | // +build $tags | |
492 | ||
493 | package $package | |
494 | ||
495 | import ( | |
496 | "unsafe" | |
497 | ) | |
498 | ||
499 | EOF | |
500 | ||
501 | $tofcommun .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |
502 | ||
503 | $tofcommun .=<<EOF; | |
504 | ||
505 | $textcommon | |
506 | EOF | |
507 | print $fcommun $tofcommun; | |
508 | ||
509 | ||
510 | # Print zsyscall_aix_ppc64_gc.go | |
511 | open(my $fgc, '>', 'zsyscall_aix_ppc64_gc.go'); | |
512 | my $tofgc = <<EOF; | |
513 | // $cmdline | |
514 | // Code generated by the command above; see README.md. DO NOT EDIT. | |
515 | ||
516 | // +build $tags | |
517 | // +build !gccgo | |
518 | ||
519 | package $package | |
520 | ||
521 | import ( | |
522 | "unsafe" | |
523 | ) | |
524 | ||
525 | ||
526 | EOF | |
527 | ||
528 | $tofgc .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |
529 | ||
530 | my $vardecls = "\t" . join(",\n\t", @vars); | |
531 | $vardecls .= " syscallFunc"; | |
532 | ||
533 | $tofgc .=<<EOF; | |
534 | $dynimports | |
535 | $linknames | |
536 | type syscallFunc uintptr | |
537 | ||
538 | var ( | |
539 | $vardecls | |
540 | ) | |
541 | ||
542 | // Implemented in runtime/syscall_aix.go. | |
543 | func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |
544 | func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |
545 | ||
546 | $textgc | |
547 | EOF | |
548 | print $fgc $tofgc; | |
549 | ||
550 | # Print zsyscall_aix_ppc64_gc.go | |
551 | open(my $fgccgo, '>', 'zsyscall_aix_ppc64_gccgo.go'); | |
552 | my $tofgccgo = <<EOF; | |
553 | // $cmdline | |
554 | // Code generated by the command above; see README.md. DO NOT EDIT. | |
555 | ||
556 | // +build $tags | |
557 | // +build gccgo | |
558 | ||
559 | package $package | |
560 | ||
561 | ||
562 | $c_extern | |
563 | */ | |
564 | import "C" | |
565 | import ( | |
566 | "syscall" | |
567 | ) | |
568 | ||
569 | ||
570 | EOF | |
571 | ||
572 | $tofgccgo .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |
573 | ||
574 | $tofgccgo .=<<EOF; | |
575 | ||
576 | $textgccgo | |
577 | EOF | |
578 | print $fgccgo $tofgccgo; | |
579 | exit 0; |