gensyscalls.py revision 70b1668a76d3b719ae690903ea790fda964a5458
17ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout#!/usr/bin/python
27ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout#
37ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# this tool is used to generate the syscall assmbler templates
47ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# to be placed into arch-x86/syscalls, as well as the content
57ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# of arch-x86/linux/_syscalls.h
67ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout#
77ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
87ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport sys, os.path, glob, re, commands, filecmp, shutil
97ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutfrom bionic_utils import *
117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# set this to 1 if you want to generate thumb stubs
137ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutgen_thumb_stubs = 0
147ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# set this to 1 if you want to generate ARM EABI stubs
167709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutgen_eabi_stubs = 1
177709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
18372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout# get the root Bionic directory, simply this script's dirname
19d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout#
20d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutbionic_root = find_bionic_root()
21d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutif not bionic_root:
22cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout    print "could not find the Bionic root directory. aborting"
236b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    sys.exit(1)
24d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
25d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutif bionic_root[-1] != '/':
267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    bionic_root += "/"
27372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
28372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutprint "bionic_root is %s" % bionic_root
29d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# temp directory where we store all intermediate files
31d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutbionic_temp = "/tmp/bionic_gensyscalls/"
32d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
336b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout# all architectures, update as you see fit
34d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutall_archs = [ "arm", "x86" ]
357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
366dca725412977bb56b933bdec120e31909233cdbCraig Stoutdef make_dir( path ):
377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    if not os.path.exists(path):
386b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        parent = os.path.dirname(path)
39372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if parent:
40372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            make_dir(parent)
417709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        os.mkdir(path)
42372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
437709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutdef create_file( relpath ):
447709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    dir = os.path.dirname( bionic_temp + relpath )
457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    make_dir(dir)
462d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    return open( bionic_temp + relpath, "w" )
477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout# x86 assembler templates for each syscall stub
497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout#
506dca725412977bb56b933bdec120e31909233cdbCraig Stout
516dca725412977bb56b933bdec120e31909233cdbCraig Stoutx86_header = """/* autogenerated by gensyscalls.py */
527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout#include <sys/linux-syscalls.h>
537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    .text
557709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    .type %(fname)s, @function
567709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    .globl %(fname)s
577709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    .align 4
587709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
597709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout%(fname)s:
607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout"""
617709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
627709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutx86_registers = [ "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp" ]
637709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
647709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutx86_call = """    movl    $%(idname)s, %%eax
657709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    int     $0x80
667709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    cmpl    $-129, %%eax
677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    jb      1f
687709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    negl    %%eax
697709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    pushl   %%eax
70372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    call    __set_errno
71372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    addl    $4, %%esp
72372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    orl     $-1, %%eax
73372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout1:
74372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout"""
75372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
76372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutx86_return = """    ret
77eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout"""
78eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
79eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout# ARM assembler templates for each syscall stub
80eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout#
81eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stoutarm_header = """/* autogenerated by gensyscalls.py */
82eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout#include <machine/asm.h>
83eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout#include <sys/linux-syscalls.h>
84eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
85eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig StoutENTRY(%(fname)s)
86eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout"""
87372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
88372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutarm_footer = """\
89d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig StoutEND(%(fname)s)
90372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout"""
91372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
92372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutarm_call_default = arm_header + """\
93372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    swi   #%(idname)s
94372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    movs    r0, r0
95372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    bxpl    lr
96372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    b       __set_syscall_errno
97372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout""" + arm_footer
987ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
99d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stoutarm_call_long = arm_header + """\
1007709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    .save   {r4, r5, lr}
1017709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    stmfd   sp!, {r4, r5, lr}
1027709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    ldr     r4, [sp, #12]
1037709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    ldr     r5, [sp, #16]
104372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    swi     # %(idname)s
1056b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    ldmfd   sp!, {r4, r5, lr}
1066b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    movs    r0, r0
107372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    bxpl    lr
108eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout    b       __set_syscall_errno
109372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout""" + arm_footer
110372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
111d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutarm_eabi_call_default = arm_header + """\
112d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    .save   {r4, r7}
113d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    stmfd   sp!, {r4, r7}
1146b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    ldr     r7, =%(idname)s
115d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    swi     #0
116d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    ldmfd   sp!, {r4, r7}
117aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    movs    r0, r0
118d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    bxpl    lr
119372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    b       __set_syscall_errno
120372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout""" + arm_footer
121372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
122372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutarm_eabi_call_long = arm_header + """\
123372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    mov     ip, sp
124d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    .save   {r4, r5, r6, r7}
125372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    stmfd   sp!, {r4, r5, r6, r7}
126372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldmfd   ip, {r4, r5, r6}
127372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr     r7, =%(idname)s
128372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    swi     #0
129372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldmfd   sp!, {r4, r5, r6, r7}
130372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    movs    r0, r0
131372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    bxpl    lr
132372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    b       __set_syscall_errno
133372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout""" + arm_footer
134d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
135d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout# ARM thumb assembler templates for each syscall stub
136d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout#
137372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutthumb_header = """/* autogenerated by gensyscalls.py */
138372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .text
139372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .type %(fname)s, #function
140372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .globl %(fname)s
141d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    .align 4
1421e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    .thumb_func
1431e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    .fnstart
1441e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout
145aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout#define  __thumb__
1461e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout#include <sys/linux-syscalls.h>
147d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
148d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
149d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout%(fname)s:
150372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout"""
151372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
152372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutthumb_call_default = thumb_header + """\
153372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .save   {r7,lr}
154372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    push    {r7,lr}
155372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr     r7, =%(idname)s
156372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    swi     #0
157372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    tst     r0, r0
158372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    bmi     1f
159372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    pop     {r7,pc}
160372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout1:
161372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    neg     r0, r0
162372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr     r1, =__set_errno
163372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    blx     r1
164372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    pop     {r7,pc}
165372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .fnend
166372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout"""
167cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
168372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutthumb_call_long = thumb_header + """\
169372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .save  {r4,r5,r7,lr}
170372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    push   {r4,r5,r7,lr}
171372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr    r4, [sp,#16]
172372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr    r5, [sp,#20]
173372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr    r7, =%(idname)s
174cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout    swi    #0
175372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    tst    r0, r0
176372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    bmi    1f
177372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    pop    {r4,r5,r7,pc}
178372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout1:
179372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    neg    r0, r0
180372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    ldr    r1, =__set_errno
181cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout    blx    r1
182372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    pop    {r4,r5,r7,pc}
183372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    .fnend
184372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout"""
185d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
186d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutdef param_uses_64bits(param):
1871e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    """Returns True iff a syscall parameter description corresponds
1881e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout       to a 64-bit type."""
1891e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    param = param.strip()
190d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    # First, check that the param type begins with one of the known
191d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    # 64-bit types.
192d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    if not ( \
193aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout       param.startswith("int64_t") or param.startswith("uint64_t") or \
194aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout       param.startswith("loff_t") or param.startswith("off64_t") or \
195aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout       param.startswith("long long") or param.startswith("unsigned long long") or
196aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout       param.startswith("signed long long") ):
197aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout           return False
198aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
199aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    # Second, check that there is no pointer type here
200aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    if param.find("*") >= 0:
2011e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            return False
202aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
203aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    # Ok
204aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    return True
205aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
206aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stoutdef count_arm_param_registers(params):
207aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    """This function is used to count the number of register used
208d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout       to pass parameters when invoking a thumb or ARM system call.
209d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout       This is because the ARM EABI mandates that 64-bit quantities
210d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout       must be passed in an even+odd register pair. So, for example,
211372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout       something like:
212372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
213372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout             foo(int fd, off64_t pos)
214372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
215372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout       would actually need 4 registers:
216372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout             r0 -> int
217372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout             r1 -> unused
218372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout             r2-r3 -> pos
219372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout   """
220372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    count = 0
221372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    for param in params:
222372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if param_uses_64bits(param):
223372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (count & 1) != 0:
224372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                count += 1
225372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            count += 2
226372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        else:
227372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            count += 1
228372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    return count
229372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
230372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutdef count_generic_param_registers(params):
231372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    count = 0
232372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    for param in params:
233372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if param_uses_64bits(param):
234372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            count += 2
235372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        else:
236372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            count += 1
237372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    return count
238372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
239372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutclass State:
240372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    def __init__(self):
241372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        self.old_stubs = []
242372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        self.new_stubs = []
243372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        self.other_files = []
244372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        self.syscalls = []
245372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
246372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    def x86_genstub(self, fname, numparams, idname):
247372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        t = { "fname"  : fname,
248372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout              "idname" : idname }
249372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
250372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        result     = x86_header % t
251372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        stack_bias = 4
252372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        for r in range(numparams):
253372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            result     += "    pushl   " + x86_registers[r] + "\n"
254372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            stack_bias += 4
255372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
256372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        for r in range(numparams):
257372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            result += "    mov     %d(%%esp), %s" % (stack_bias+r*4, x86_registers[r]) + "\n"
258eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
259eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        result += x86_call % t
260eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
261eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        for r in range(numparams):
262eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout            result += "    popl    " + x86_registers[numparams-r-1] + "\n"
263eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
264eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        result += x86_return
265eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        return result
266eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
2672dfed05c8ab53ca7c28424c9c03b1a87b9b7ca0dCraig Stout    def x86_genstub_cid(self, fname, numparams, idname, cid):
268eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        # We'll ignore numparams here because in reality, if there is a
269eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        # dispatch call (like a socketcall syscall) there are actually
270eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        # only 2 arguments to the syscall and 2 regs we have to save:
271eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        #   %ebx <--- Argument 1 - The call id of the needed vectored
272372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        #                          syscall (socket, bind, recv, etc)
273372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        #   %ecx <--- Argument 2 - Pointer to the rest of the arguments
274372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        #                          from the original function called (socket())
275372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        t = { "fname"  : fname,
276372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout              "idname" : idname }
277372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
278372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        result = x86_header % t
279372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        stack_bias = 4
280372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
281372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        # save the regs we need
282372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        result += "    pushl   %ebx" + "\n"
283372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        stack_bias += 4
284372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        result += "    pushl   %ecx" + "\n"
285372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        stack_bias += 4
286372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
287372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        # set the call id (%ebx)
288372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        result += "    mov     $%d, %%ebx" % (cid) + "\n"
289cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
290cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        # set the pointer to the rest of the args into %ecx
291cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        result += "    mov     %esp, %ecx" + "\n"
292cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        result += "    addl    $%d, %%ecx" % (stack_bias) + "\n"
293cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
294cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        # now do the syscall code itself
295cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        result += x86_call % t
296cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
297cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        # now restore the saved regs
298d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        result += "    popl    %ecx" + "\n"
299cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        result += "    popl    %ebx" + "\n"
300cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
301cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        # epilog
302cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        result += x86_return
303cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        return result
304cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
305cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout    def arm_genstub(self,fname, flags, idname):
306cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        t = { "fname"  : fname,
307cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout              "idname" : idname }
308cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        if flags:
309cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout            numargs = int(flags)
310cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout            if numargs > 4:
311eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout                return arm_call_long % t
312eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        return arm_call_default % t
313eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
314eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
315372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    def arm_eabi_genstub(self,fname, flags, idname):
316372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        t = { "fname"  : fname,
317372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout              "idname" : idname }
318372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if flags:
319372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            numargs = int(flags)
320372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if numargs > 4:
321372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                return arm_eabi_call_long % t
322d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        return arm_eabi_call_default % t
323372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
324372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
325372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    def thumb_genstub(self,fname, flags, idname):
326372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        t = { "fname"  : fname,
327372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout              "idname" : idname }
328372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if flags:
329372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            numargs = int(flags)
330372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if numargs > 4:
3311e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                return thumb_call_long % t
3321e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        return thumb_call_default % t
3331e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout
3341e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout
335372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    def superh_genstub(self, fname, flags, idname):
336372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        numargs = int(flags)
337d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        t = { "fname"  : fname,
338d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout              "idname" : idname,
339d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout              "numargs" : numargs }
340d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        superh_call = superh_header
341d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if flags:
342d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if numargs == 5:
343d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                superh_call += superh_5args_header
344d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if numargs == 6:
345d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                superh_call += superh_6args_header
346d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if numargs == 7:
347d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                superh_call += superh_7args_header
348d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        superh_call += superh_call_default
349d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        return superh_call % t
350d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
351d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
352d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    def process_file(self,input):
353d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        parser = SysCallsTxtParser()
354d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        parser.parse_file(input)
355d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        self.syscalls = parser.syscalls
356d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        parser = None
357d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
358d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        for t in self.syscalls:
359d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            syscall_func   = t["func"]
360d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            syscall_params = t["params"]
361d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            syscall_name   = t["name"]
362d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
3632d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            if t["id"] >= 0:
3642d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                num_regs = count_arm_param_registers(syscall_params)
3652d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                if gen_thumb_stubs:
3662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    t["asm-thumb"] = self.thumb_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
3672d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                else:
3682d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    if gen_eabi_stubs:
3692d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                        t["asm-arm"]   = self.arm_eabi_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
3702d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    else:
3712d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                        t["asm-arm"]   = self.arm_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
3722d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
3732d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            if t["id2"] >= 0:
374d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                num_regs = count_generic_param_registers(syscall_params)
3752d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                if t["cid"] >= 0:
376d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, "__NR_"+syscall_name, t["cid"])
3772d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                else:
3782d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, "__NR_"+syscall_name)
3792d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            elif t["cid"] >= 0:
3802d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                E("cid for dispatch syscalls is only supported for x86 in "
3811e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                  "'%s'" % syscall_name)
3822d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                return
3832d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
3842d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
3852d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    def gen_NR_syscall(self,fp,name,id):
3862d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp.write( "#define __NR_%-25s    (__NR_SYSCALL_BASE + %d)\n" % (name,id) )
3872d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
3882d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    # now dump the content of linux/_syscalls.h
389d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    def gen_linux_syscalls_h(self):
390d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        path = "include/sys/linux-syscalls.h"
3912d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        D( "generating "+path )
3922d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp = create_file( path )
393d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "/* auto-generated by gensyscalls.py, do not touch */\n" )
394d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "#ifndef _BIONIC_LINUX_SYSCALLS_H_\n\n" )
395d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H\n" )
396d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__\n" )
397d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "  #  define __NR_SYSCALL_BASE  0x900000\n" )
398d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "  #else\n" )
3992d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp.write( "  #  define  __NR_SYSCALL_BASE  0\n" )
4002d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp.write( "  #endif\n\n" )
401d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
402d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        # first, all common syscalls
403d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        for sc in self.syscalls:
404d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            sc_id  = sc["id"]
4052d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            sc_id2 = sc["id2"]
4062d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            sc_name = sc["name"]
407d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if sc_id == sc_id2 and sc_id >= 0:
408d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                self.gen_NR_syscall( fp, sc_name, sc_id )
409d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
410d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        # now, all arm-specific syscalls
4112d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp.write( "\n#ifdef __arm__\n" );
412d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        for sc in self.syscalls:
4132d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            sc_id  = sc["id"]
4141e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            sc_id2 = sc["id2"]
4151e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            sc_name = sc["name"]
4161e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            if sc_id != sc_id2 and sc_id >= 0:
417d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                self.gen_NR_syscall( fp, sc_name, sc_id )
418d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "#endif\n" );
419d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
4202d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        gen_syscalls = {}
4212d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        # finally, all i386-specific syscalls
4222d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp.write( "\n#ifdef __i386__\n" );
4232d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        for sc in self.syscalls:
4242d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            sc_id  = sc["id"]
4252d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            sc_id2 = sc["id2"]
4262d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            sc_name = sc["name"]
4272d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            if sc_id != sc_id2 and sc_id2 >= 0 and sc_name not in gen_syscalls:
4282d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                self.gen_NR_syscall( fp, sc_name, sc_id2 )
4292d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                gen_syscalls[sc_name] = True
4302d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp.write( "#endif\n" );
431d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
432d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "\n#endif\n" )
4336b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.write( "\n#endif /* _BIONIC_LINUX_SYSCALLS_H_ */\n" );
434d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.close()
435d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        self.other_files.append( path )
436d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
437d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
438d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    # now dump the content of linux/_syscalls.h
439d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    def gen_linux_unistd_h(self):
440d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        path = "include/sys/linux-unistd.h"
4412d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        D( "generating "+path )
4422d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        fp = create_file( path )
443d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "/* auto-generated by gensyscalls.py, do not touch */\n" )
444d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "#ifndef _BIONIC_LINUX_UNISTD_H_\n\n" );
445d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        fp.write( "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n" )
446d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
4472d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        for sc in self.syscalls:
4482d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            fp.write( sc["decl"]+"\n" )
4496b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
4506b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.write( "#ifdef __cplusplus\n}\n#endif\n" )
4516b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.write( "\n#endif /* _BIONIC_LINUX_UNISTD_H_ */\n" );
4526b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.close()
4536b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        self.other_files.append( path )
4546b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
4556b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    # now dump the contents of syscalls.mk
4566b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    def gen_arch_syscalls_mk(self, arch):
4576b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        path = "arch-%s/syscalls.mk" % arch
4586b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        D( "generating "+path )
4596b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp = create_file( path )
4606b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.write( "# auto-generated by gensyscalls.py, do not touch\n" )
4616b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.write( "syscall_src := \n" )
4626b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        arch_test = {
4636b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            "arm": lambda x: x.has_key("asm-arm") or x.has_key("asm-thumb"),
4646b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            "x86": lambda x: x.has_key("asm-x86"),
4658f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout        }
4668f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout
4678f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout        for sc in self.syscalls:
4686b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if arch_test[arch](sc):
4696b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                fp.write("syscall_src += arch-%s/syscalls/%s.S\n" %
4706b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                         (arch, sc["func"]))
4716b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        fp.close()
4726b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        self.other_files.append( path )
4736b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
4746b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    # now generate each syscall stub
4756b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    def gen_syscall_stubs(self):
4766b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        for sc in self.syscalls:
4776b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if sc.has_key("asm-arm") and 'arm' in all_archs:
4786b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                fname = "arch-arm/syscalls/%s.S" % sc["func"]
4796b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                D2( ">>> generating "+fname )
480d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                fp = create_file( fname )
481d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                fp.write(sc["asm-arm"])
482372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                fp.close()
483372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                self.new_stubs.append( fname )
484372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
485372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if sc.has_key("asm-thumb") and 'arm' in all_archs:
486372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                fname = "arch-arm/syscalls/%s.S" % sc["func"]
487372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                D2( ">>> generating "+fname )
488d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                fp = create_file( fname )
489d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                fp.write(sc["asm-thumb"])
490d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                fp.close()
491d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                self.new_stubs.append( fname )
492d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
493372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if sc.has_key("asm-x86") and 'x86' in all_archs:
494372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                fname = "arch-x86/syscalls/%s.S" % sc["func"]
495372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                D2( ">>> generating "+fname )
4966b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                fp = create_file( fname )
4976b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                fp.write(sc["asm-x86"])
498d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                fp.close()
499d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                self.new_stubs.append( fname )
500d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
501d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
502d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    def  regenerate(self):
503d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        D( "scanning for existing architecture-specific stub files" )
5046b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
505d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        bionic_root_len = len(bionic_root)
506d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
507d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        for arch in all_archs:
508d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            arch_path = bionic_root + "arch-" + arch
5096b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            D( "scanning " + arch_path )
510d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            files = glob.glob( arch_path + "/syscalls/*.S" )
511d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            for f in files:
512d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                self.old_stubs.append( f[bionic_root_len:] )
513d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
514d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        D( "found %d stub files" % len(self.old_stubs) )
515d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
5166b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        if not os.path.exists( bionic_temp ):
517d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            D( "creating %s" % bionic_temp )
518d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            os.mkdir( bionic_temp )
519d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
520d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout#        D( "p4 editing source files" )
5216b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout#        for arch in all_archs:
522d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout#            commands.getoutput( "p4 edit " + arch + "/syscalls/*.S " )
523d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout#            commands.getoutput( "p4 edit " + arch + "/syscalls.mk" )
524d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout#        commands.getoutput( "p4 edit " + bionic_root + "include/sys/linux-syscalls.h" )
525d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
526d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        D( "re-generating stubs and support files" )
5276b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
528d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        self.gen_linux_syscalls_h()
529d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        for arch in all_archs:
5306b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            self.gen_arch_syscalls_mk(arch)
531d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        self.gen_linux_unistd_h()
532d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        self.gen_syscall_stubs()
533d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
534372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        D( "comparing files" )
535372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        adds    = []
5367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        edits   = []
5377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
5387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        for stub in self.new_stubs + self.other_files:
5397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if not os.path.exists( bionic_root + stub ):
5407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                # new file, git add it
5417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                D( "new file:     " + stub)
5426dca725412977bb56b933bdec120e31909233cdbCraig Stout                adds.append( bionic_root + stub )
5436dca725412977bb56b933bdec120e31909233cdbCraig Stout                shutil.copyfile( bionic_temp + stub, bionic_root + stub )
5446dca725412977bb56b933bdec120e31909233cdbCraig Stout
5457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            elif not filecmp.cmp( bionic_temp + stub, bionic_root + stub ):
5466dca725412977bb56b933bdec120e31909233cdbCraig Stout                D( "changed file: " + stub)
5476dca725412977bb56b933bdec120e31909233cdbCraig Stout                edits.append( stub )
5486dca725412977bb56b933bdec120e31909233cdbCraig Stout
5497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        deletes = []
5507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        for stub in self.old_stubs:
5517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if not stub in self.new_stubs:
5527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                D( "deleted file: " + stub)
553d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                deletes.append( bionic_root + stub )
5547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
5557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
556d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if adds:
557d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            commands.getoutput("git add " + " ".join(adds))
558d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if deletes:
559d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            commands.getoutput("git rm " + " ".join(deletes))
560d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if edits:
561d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            for file in edits:
5627ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                shutil.copyfile( bionic_temp + file, bionic_root + file )
563d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            commands.getoutput("git add " +
564d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                               " ".join((bionic_root + file) for file in edits))
5657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
5667ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        commands.getoutput("git add %s%s" % (bionic_root,"SYSCALLS.TXT"))
5677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
5687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (not adds) and (not deletes) and (not edits):
5697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            D("no changes detected!")
570d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        else:
571d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            D("ready to go!!")
572d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
573d20507e0f5ac7ad021f42ca87c294787246f0591Craig StoutD_setlevel(1)
574d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
5757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutstate = State()
5767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutstate.process_file(bionic_root+"SYSCALLS.TXT")
5777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutstate.regenerate()
5787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout