Merge "SYSCALLS.TXT: improve the docs." into main
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 7c09e88..31651cd 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -1,32 +1,37 @@
 # This file is used to automatically generate bionic's system call stubs.
 #
+# It is processed by a python script named gensyscalls.py,
+# normally run via the genrules in libc/Android.bp.
+#
 # Each non-blank, non-comment line has the following format:
 #
-# func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
+#     func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
 #
 # where:
-#       arch_list ::= "all" | arches
-#       arches    ::= arch |  arch "," arches
-#       arch      ::= "arm" | "arm64" | "riscv64" | "x86" | "x86_64" | "lp32" | "lp64"
+#     arch_list ::= "all" | arches
+#     arches    ::= arch |  arch "," arches
+#     arch      ::= "arm" | "arm64" | "riscv64" | "x86" | "x86_64" | "lp32" | "lp64"
 #
-# Note:
-#      - syscall_name corresponds to the name of the syscall, which may differ from
-#        the exported function name (example: the exit syscall is implemented by the _exit()
-#        function, which is not the same as the standard C exit() function which calls it)
+# syscall_name corresponds to the name of the syscall, which may differ from
+# the exported function name func_name. For example: the exit_group syscall
+# is exported by libc as the _exit() function, not exit() (which does more
+# work before calling _exit()).
 #
-#      - alias_list is optional comma separated list of function aliases.
+# alias_list is optional comma-separated list of function aliases.
+# For example, the traditional _exit() function has a C99 alias _Exit().
 #
-#      - No return type is specified.
+# No return type is specified, because it's not needed.
 #
-#      - The call_id parameter, given that func_name and syscall_name have
-#        been provided, allows the user to specify dispatch style syscalls.
-#        For example, socket() syscall on i386 actually becomes:
-#          socketcall(__NR_socket, 1, *(rest of args on stack)).
+# The socketcall_id parameter supports x86's
+# https://man7.org/linux/man-pages/man2/socketcall.2.html
+# and can be ignored for all other syscalls and architectures.
 #
-#      - Each parameter type is assumed to be stored in 32 bits.
+# The number of registers required for the arguments is computed by the script,
+# based on the parameter list given here. It handles the need for register
+# pairs for 64-bit arguments on ILP32, and also arm32's requirement for such
+# pairs to start on an even register. This means that it's important to get
+# these types right!
 #
-# This file is processed by a python script named gensyscalls.py, run via
-# genrules in Android.bp.
 
 # Calls that have historical 16-bit variants camping on the best names (CONFIG_UID16).
 getuid:getuid32()   lp32
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index aa4f1cb..d371b72 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -27,6 +27,7 @@
 # ARM assembler templates for each syscall stub
 #
 
+# ARM assembler template for a syscall stub needing 4 or fewer registers
 arm_call_default = syscall_stub_header + """\
     mov     ip, r7
     .cfi_register r7, ip
@@ -41,6 +42,7 @@
 END(%(func)s)
 """
 
+# ARM assembler template for a syscall stub needing more than 4 registers
 arm_call_long = syscall_stub_header + """\
     mov     ip, sp
     stmfd   sp!, {r4, r5, r6, r7}
@@ -165,13 +167,13 @@
 
     # Second, check that there is no pointer type here
     if param.find("*") >= 0:
-            return False
+        return False
 
     # Ok
     return True
 
 
-def count_arm_param_registers(params):
+def count_param_registers_arm32(params):
     """This function is used to count the number of register used
        to pass parameters when invoking an ARM system call.
        This is because the ARM EABI mandates that 64-bit quantities
@@ -196,7 +198,7 @@
     return count
 
 
-def count_generic_param_registers(params):
+def count_param_registers_x86(params):
     count = 0
     for param in params:
         if param_uses_64bits(param):
@@ -206,13 +208,6 @@
     return count
 
 
-def count_generic_param_registers64(params):
-    count = 0
-    for param in params:
-        count += 1
-    return count
-
-
 # This lets us support regular system calls like __NR_write and also weird
 # ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
 def make__NR_name(name):
@@ -231,7 +226,7 @@
 
 
 def arm_genstub(syscall):
-    num_regs = count_arm_param_registers(syscall["params"])
+    num_regs = count_param_registers_arm32(syscall["params"])
     if num_regs > 4:
         return arm_call_long % syscall
     return arm_call_default % syscall
@@ -248,7 +243,7 @@
 def x86_genstub(syscall):
     result     = syscall_stub_header % syscall
 
-    numparams = count_generic_param_registers(syscall["params"])
+    numparams = count_param_registers_x86(syscall["params"])
     stack_bias = numparams*4 + 8
     offset = 0
     mov_result = ""
@@ -316,7 +311,7 @@
 
 def x86_64_genstub(syscall):
     result = syscall_stub_header % syscall
-    num_regs = count_generic_param_registers64(syscall["params"])
+    num_regs = len(syscall["params"])
     if (num_regs > 3):
         # rcx is used as 4th argument. Kernel wants it at r10.
         result += "    movq    %rcx, %r10\n"