]>
git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
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.
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
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.
25 # The generated code looks like this
27 # zsyscall_aix_ppc64.go
28 # func asyscall(...) (n int, err error) {
30 # r1, e1 := callasyscall(...)
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
41 # func callasyscall(...) (r1 uintptr, e1 Errno) {
42 # r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
46 # zsyscall_aix_ppc64_ggcgo.go
53 # func callasyscall(...) (r1 uintptr, e1 Errno) {
54 # r1 = uintptr(C.asyscall(...))
55 # e1 = syscall.GetErrno()
63 my $cmdline = "mksyscall_aix_ppc64.pl " . join(' ', @ARGV);
66 my $tags = ""; # build tags
72 if($ARGV[0] eq "-b32") {
73 $_32bit = "big-endian";
75 } elsif($ARGV[0] eq "-l32") {
76 $_32bit = "little-endian";
79 if($ARGV[0] eq "-aix") {
83 if($ARGV[0] eq "-tags") {
89 if($ARGV[0] =~ /^-/) {
90 print STDERR
"usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
94 sub parseparamlist
($) {
101 return split(/\s*,\s*/, $list);
106 if($p !~ /^(\S*) (\S*)$/) {
107 print STDERR
"$ARGV:$.: malformed parameter: $p\n";
109 return ("xx", "int");
117 my $c_extern = "/*\n#include <stdint.h>\n";
131 $package = $1 if !$package && /^package (\S+)$/;
132 my $nonblock = /^\/\
/sysnb /;
133 next if !/^\/\
/sys / && !$nonblock;
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";
143 my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
145 # Split argument lists on comma.
146 my @in = parseparamlist
($in);
147 my @out = parseparamlist
($out);
149 $in = join(', ', @in);
150 $out = join(', ', @out);
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.
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.
167 $textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
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";
174 # Check if value return, err return available
178 foreach my $p (@out) {
179 my ($name, $type) = parseparam
($p);
180 if($type eq "error") {
189 $sysname =~ s/([a-z])([A-Z])/${1}_$2/g;
190 $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
192 # GCCGO Prototype return type
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") {
202 } elsif($rettype eq "int32") {
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";
213 if($sysname eq "exit") {
217 # GCCGO Prototype arguments type
219 foreach my $i (0 .. $#in) {
220 my ($name, $type) = parseparam
($in[$i]);
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";
240 } elsif($type eq "int32") {
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";
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";
263 $modname = "libc.a/shr_64.o";
265 print STDERR
"$func: only syscall using libc are available\n";
269 my $sysvarname = "libc_${sysname}";
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;
280 my $strconvfunc ="BytePtrFromString";
281 my $strconvtype = "*byte";
283 # Go function header.
287 if($textcommon ne "") {
291 $textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ;
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)
300 foreach my $p (@in) {
301 my ($name, $type) = parseparam
($p);
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";
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)";
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";
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)";
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)";
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)";
344 # push @args, "uintptr($name)", "uintptr($name >> 32)";
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";
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)";
366 push @argscommun, "$name";
367 push @argscall, "$name int";
368 push @argsgc, "uintptr($name)";
369 push @argsgccgo, "C.int($name)";
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)";
397 push @argscommun, "int($name)";
398 push @argscall, "$name int";
399 push @argsgc, "uintptr($name)";
400 push @argsgccgo, "C.int($name)";
406 # COMMUN function generation
407 my $argscommun = join(', ', @argscommun);
408 my $callcommun = "call$sysname($argscommun)";
409 my @ret = ("_", "_");
412 for(my $i=0; $i<@out; $i++) {
414 my ($name, $type) = parseparam
($p);
424 if($type eq "bool") {
428 $body .= "\t$name = $type($reg)\n";
431 if ($ret[0] eq "_" && $ret[1] eq "_") {
432 $textcommon .= "\t$callcommun\n";
434 $textcommon .= "\t$ret[0], $ret[1] := $callcommun\n";
436 $textcommon .= $body;
439 $textcommon .= "\tif e1 != 0 {\n";
440 $textcommon .= "\t\terr = errnoErr(e1)\n";
441 $textcommon .= "\t}\n";
443 $textcommon .= "\treturn\n";
444 $textcommon .= "}\n";
450 my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall);
452 # GC function generation
453 my $asm = "syscall6";
455 $asm = "rawSyscall6";
463 print STDERR
"$ARGV:$.: too many arguments to system call\n";
465 my $argsgc = join(', ', @argsgc);
466 my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)";
468 $textgc .= $callProto;
469 $textgc .= "\tr1, _, e1 = $callgc\n";
470 $textgc .= "\treturn\n}\n";
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";
485 # Print zsyscall_aix_ppc64.go
486 open(my $fcommun, '>', 'zsyscall_aix_ppc64.go');
487 my $tofcommun = <<EOF;
489 // Code generated by the command above; see README.md. DO NOT EDIT.
501 $tofcommun .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
507 print $fcommun $tofcommun;
510 # Print zsyscall_aix_ppc64_gc.go
511 open(my $fgc, '>', 'zsyscall_aix_ppc64_gc.go');
514 // Code generated by the command above; see README.md. DO NOT EDIT.
528 $tofgc .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
530 my $vardecls = "\t" . join(",\n\t", @vars);
531 $vardecls .= " syscallFunc";
536 type syscallFunc uintptr
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)
550 # Print zsyscall_aix_ppc64_gc.go
551 open(my $fgccgo, '>', 'zsyscall_aix_ppc64_gccgo.go');
552 my $tofgccgo = <<EOF;
554 // Code generated by the command above; see README.md. DO NOT EDIT.
572 $tofgccgo .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
578 print $fgccgo $tofgccgo;