1a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#!/usr/bin/python
2a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#
31fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham# this tool is used to generate the syscall assembler templates
41fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham# to be placed into arch-{arm,x86,mips}/syscalls, as well as the content
51fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham# of arch-{arm,x86,mips}/linux/_syscalls.h
6a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#
7a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
84e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Projectimport sys, os.path, glob, re, commands, filecmp, shutil
91fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamimport getpass
10a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
11a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectfrom bionic_utils import *
12a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
13a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# set this to 1 if you want to generate thumb stubs
14a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectgen_thumb_stubs = 0
15a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
16a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# set this to 1 if you want to generate ARM EABI stubs
17a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectgen_eabi_stubs = 1
18a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
19a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# get the root Bionic directory, simply this script's dirname
20a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#
21a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectbionic_root = find_bionic_root()
22a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectif not bionic_root:
23a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    print "could not find the Bionic root directory. aborting"
24a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    sys.exit(1)
25a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
26a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectif bionic_root[-1] != '/':
27a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bionic_root += "/"
28a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
29a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectprint "bionic_root is %s" % bionic_root
30a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
31a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# temp directory where we store all intermediate files
32a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectbionic_temp = "/tmp/bionic_gensyscalls/"
33a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
34a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# all architectures, update as you see fit
351fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamall_archs = [ "arm", "x86", "mips" ]
36a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
37a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectdef make_dir( path ):
381fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    path = os.path.abspath(path)
39a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    if not os.path.exists(path):
40a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        parent = os.path.dirname(path)
41a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if parent:
42a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            make_dir(parent)
43a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        os.mkdir(path)
44a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
45a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectdef create_file( relpath ):
46a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    dir = os.path.dirname( bionic_temp + relpath )
47a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    make_dir(dir)
48a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    return open( bionic_temp + relpath, "w" )
49a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
50a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# x86 assembler templates for each syscall stub
51a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#
52a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
53a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectx86_header = """/* autogenerated by gensyscalls.py */
54a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#include <sys/linux-syscalls.h>
55a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
56a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .text
57a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .type %(fname)s, @function
58a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .globl %(fname)s
59a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .align 4
60a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
61a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project%(fname)s:
62a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
63a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
64a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectx86_registers = [ "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp" ]
65a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
66a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectx86_call = """    movl    $%(idname)s, %%eax
67a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    int     $0x80
68a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    cmpl    $-129, %%eax
69a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    jb      1f
70a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    negl    %%eax
71a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    pushl   %%eax
72a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    call    __set_errno
73a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    addl    $4, %%esp
74a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    orl     $-1, %%eax
75a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project1:
76a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
77a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
78a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectx86_return = """    ret
79a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
80a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
81a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# ARM assembler templates for each syscall stub
82a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#
83a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectarm_header = """/* autogenerated by gensyscalls.py */
84f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Root#include <machine/asm.h>
85a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#include <sys/linux-syscalls.h>
86a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
87f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny RootENTRY(%(fname)s)
88f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Root"""
89a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
90f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Rootarm_footer = """\
91f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny RootEND(%(fname)s)
92a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
93a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
94a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectarm_call_default = arm_header + """\
95a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    swi   #%(idname)s
96a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    movs    r0, r0
97a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bxpl    lr
98a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    b       __set_syscall_errno
99f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Root""" + arm_footer
100a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
101a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectarm_call_long = arm_header + """\
102a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .save   {r4, r5, lr}
103a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    stmfd   sp!, {r4, r5, lr}
104a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr     r4, [sp, #12]
105a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr     r5, [sp, #16]
106a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    swi     # %(idname)s
107a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldmfd   sp!, {r4, r5, lr}
108a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    movs    r0, r0
109a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bxpl    lr
110a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    b       __set_syscall_errno
111f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Root""" + arm_footer
112a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
113a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectarm_eabi_call_default = arm_header + """\
114a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .save   {r4, r7}
115a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    stmfd   sp!, {r4, r7}
116a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr     r7, =%(idname)s
117a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    swi     #0
118a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldmfd   sp!, {r4, r7}
119a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    movs    r0, r0
120a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bxpl    lr
121a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    b       __set_syscall_errno
122f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Root""" + arm_footer
123a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
124a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectarm_eabi_call_long = arm_header + """\
125a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    mov     ip, sp
126a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .save   {r4, r5, r6, r7}
127a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    stmfd   sp!, {r4, r5, r6, r7}
128a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldmfd   ip, {r4, r5, r6}
129a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr     r7, =%(idname)s
130a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    swi     #0
131a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldmfd   sp!, {r4, r5, r6, r7}
132a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    movs    r0, r0
133a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bxpl    lr
134a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    b       __set_syscall_errno
135f540c03bff8bb15f1954df275629fd32dc87aaf5Kenny Root""" + arm_footer
136a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
137a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project# ARM thumb assembler templates for each syscall stub
138a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#
139a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectthumb_header = """/* autogenerated by gensyscalls.py */
140a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .text
141a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .type %(fname)s, #function
142a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .globl %(fname)s
143a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .align 4
144a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .thumb_func
145a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .fnstart
146a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
147a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#define  __thumb__
148a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#include <sys/linux-syscalls.h>
149a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
150a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
151a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project%(fname)s:
152a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
153a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
154a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectthumb_call_default = thumb_header + """\
155a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .save   {r7,lr}
156a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    push    {r7,lr}
157a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr     r7, =%(idname)s
158a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    swi     #0
159a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    tst     r0, r0
160a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bmi     1f
161a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    pop     {r7,pc}
162a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project1:
163a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    neg     r0, r0
164a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr     r1, =__set_errno
165a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    blx     r1
166a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    pop     {r7,pc}
167a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .fnend
168a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
169a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
170a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectthumb_call_long = thumb_header + """\
171a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .save  {r4,r5,r7,lr}
172a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    push   {r4,r5,r7,lr}
173a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr    r4, [sp,#16]
174a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr    r5, [sp,#20]
175a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr    r7, =%(idname)s
176a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    swi    #0
177a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    tst    r0, r0
178a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    bmi    1f
179a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    pop    {r4,r5,r7,pc}
180a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project1:
181a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    neg    r0, r0
182a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    ldr    r1, =__set_errno
183a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    blx    r1
184a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    pop    {r4,r5,r7,pc}
185a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    .fnend
186a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project"""
187a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
1881fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham# mips assembler templates for each syscall stub
1891fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham#
1901fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhammips_call = """/* autogenerated by gensyscalls.py */
1911fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham#include <sys/linux-syscalls.h>
1921fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .text
1931fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .globl %(fname)s
1941fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .align 4
1951fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .ent %(fname)s
1961fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham
1971fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham%(fname)s:
1981fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .set noreorder
1991fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .cpload $t9
2001fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    li $v0, %(idname)s
2011fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    syscall
2021fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    bnez $a3, 1f
2031fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    move $a0, $v0
2041fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    j $ra
2051fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    nop
2061fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham1:
2071fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    la $t9,__set_errno
2081fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    j $t9
2091fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    nop
2101fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .set reorder
2111fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    .end %(fname)s
2121fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham"""
2131fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham
21495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turnerdef param_uses_64bits(param):
21595d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    """Returns True iff a syscall parameter description corresponds
21695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       to a 64-bit type."""
21795d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    param = param.strip()
21895d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    # First, check that the param type begins with one of the known
21995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    # 64-bit types.
22095d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    if not ( \
22195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       param.startswith("int64_t") or param.startswith("uint64_t") or \
22295d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       param.startswith("loff_t") or param.startswith("off64_t") or \
22395d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       param.startswith("long long") or param.startswith("unsigned long long") or
22495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       param.startswith("signed long long") ):
22595d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner           return False
22695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
22795d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    # Second, check that there is no pointer type here
22895d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    if param.find("*") >= 0:
22995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner            return False
23095d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
23195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    # Ok
23295d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    return True
23395d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
23495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turnerdef count_arm_param_registers(params):
23595d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    """This function is used to count the number of register used
23695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       to pass parameters when invoking a thumb or ARM system call.
23795d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       This is because the ARM EABI mandates that 64-bit quantities
23895d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       must be passed in an even+odd register pair. So, for example,
23995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       something like:
24095d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
24195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner             foo(int fd, off64_t pos)
24295d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
24395d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner       would actually need 4 registers:
24495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner             r0 -> int
24595d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner             r1 -> unused
24695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner             r2-r3 -> pos
24795d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner   """
24895d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    count = 0
24995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    for param in params:
25095d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner        if param_uses_64bits(param):
25195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner            if (count & 1) != 0:
25295d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                count += 1
25395d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner            count += 2
25495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner        else:
25595d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner            count += 1
25695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    return count
25795d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
25895d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turnerdef count_generic_param_registers(params):
25995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    count = 0
26095d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    for param in params:
26195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner        if param_uses_64bits(param):
26295d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner            count += 2
26395d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner        else:
26495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner            count += 1
26595d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner    return count
26695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner
267a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectclass State:
268a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def __init__(self):
269a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.old_stubs = []
270a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.new_stubs = []
271a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.other_files = []
272a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.syscalls = []
273a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
2744e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project    def x86_genstub(self, fname, numparams, idname):
275a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        t = { "fname"  : fname,
276a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project              "idname" : idname }
277a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
278a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        result     = x86_header % t
279a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        stack_bias = 4
280a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for r in range(numparams):
281a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            result     += "    pushl   " + x86_registers[r] + "\n"
282a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            stack_bias += 4
283a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
284a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for r in range(numparams):
285a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            result += "    mov     %d(%%esp), %s" % (stack_bias+r*4, x86_registers[r]) + "\n"
286a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
287a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        result += x86_call % t
288a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
289a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for r in range(numparams):
290a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            result += "    popl    " + x86_registers[numparams-r-1] + "\n"
291a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
292a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        result += x86_return
293a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        return result
294a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
2954e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project    def x86_genstub_cid(self, fname, numparams, idname, cid):
2964e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # We'll ignore numparams here because in reality, if there is a
2974e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # dispatch call (like a socketcall syscall) there are actually
2984e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # only 2 arguments to the syscall and 2 regs we have to save:
2994e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        #   %ebx <--- Argument 1 - The call id of the needed vectored
3004e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        #                          syscall (socket, bind, recv, etc)
3014e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        #   %ecx <--- Argument 2 - Pointer to the rest of the arguments
3024e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        #                          from the original function called (socket())
3034e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        t = { "fname"  : fname,
3044e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project              "idname" : idname }
3054e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3064e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result = x86_header % t
3074e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        stack_bias = 4
3084e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3094e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # save the regs we need
3104e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    pushl   %ebx" + "\n"
3114e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        stack_bias += 4
3124e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    pushl   %ecx" + "\n"
3134e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        stack_bias += 4
3144e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3154e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # set the call id (%ebx)
3164e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    mov     $%d, %%ebx" % (cid) + "\n"
3174e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3184e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # set the pointer to the rest of the args into %ecx
3194e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    mov     %esp, %ecx" + "\n"
3204e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    addl    $%d, %%ecx" % (stack_bias) + "\n"
3214e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3224e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # now do the syscall code itself
3234e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += x86_call % t
3244e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3254e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # now restore the saved regs
3264e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    popl    %ecx" + "\n"
3274e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += "    popl    %ebx" + "\n"
3284e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
3294e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        # epilog
3304e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        result += x86_return
3314e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        return result
332a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
333a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def arm_genstub(self,fname, flags, idname):
334a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        t = { "fname"  : fname,
335a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project              "idname" : idname }
336a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if flags:
337a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            numargs = int(flags)
338a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            if numargs > 4:
339a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                return arm_call_long % t
340a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        return arm_call_default % t
341a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
342a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
343a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def arm_eabi_genstub(self,fname, flags, idname):
344a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        t = { "fname"  : fname,
345a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project              "idname" : idname }
346a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if flags:
347a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            numargs = int(flags)
348a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            if numargs > 4:
349a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                return arm_eabi_call_long % t
350a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        return arm_eabi_call_default % t
351a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
352a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
353a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def thumb_genstub(self,fname, flags, idname):
354a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        t = { "fname"  : fname,
355a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project              "idname" : idname }
356a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if flags:
357a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            numargs = int(flags)
358a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            if numargs > 4:
359a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                return thumb_call_long % t
360a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        return thumb_call_default % t
361a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
3621fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    def mips_genstub(self,fname, idname):
3631fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        t = { "fname"  : fname,
3641fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham              "idname" : idname }
3651fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        return mips_call % t
366a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
367a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def process_file(self,input):
368a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        parser = SysCallsTxtParser()
369a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        parser.parse_file(input)
370a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.syscalls = parser.syscalls
371a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        parser = None
372a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
373a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for t in self.syscalls:
374a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            syscall_func   = t["func"]
375a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            syscall_params = t["params"]
376a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            syscall_name   = t["name"]
377a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
3781fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if t["common"] >= 0 or t["armid"] >= 0:
37995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                num_regs = count_arm_param_registers(syscall_params)
380a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                if gen_thumb_stubs:
38195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                    t["asm-thumb"] = self.thumb_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
382a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                else:
383a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                    if gen_eabi_stubs:
38495d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                        t["asm-arm"]   = self.arm_eabi_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
385a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                    else:
38695d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                        t["asm-arm"]   = self.arm_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
387a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
3881fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if t["common"] >= 0 or t["x86id"] >= 0:
38995d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                num_regs = count_generic_param_registers(syscall_params)
3904e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                if t["cid"] >= 0:
39195d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, "__NR_"+syscall_name, t["cid"])
3924e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                else:
39395d751feacdb58d3fbc36f3f21a895a3ec2f065bDavid 'Digit' Turner                    t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, "__NR_"+syscall_name)
3944e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            elif t["cid"] >= 0:
3954e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                E("cid for dispatch syscalls is only supported for x86 in "
3964e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                  "'%s'" % syscall_name)
3974e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                return
3981fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if t["common"] >= 0 or t["mipsid"] >= 0:
3991fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                t["asm-mips"] = self.mips_genstub(syscall_func,"__NR_"+syscall_name)
4004e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
401a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
402a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def gen_NR_syscall(self,fp,name,id):
403a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "#define __NR_%-25s    (__NR_SYSCALL_BASE + %d)\n" % (name,id) )
404a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
4051fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham    # now dump the content of linux-syscalls.h
406a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def gen_linux_syscalls_h(self):
407a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        path = "include/sys/linux-syscalls.h"
408a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        D( "generating "+path )
409a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp = create_file( path )
410a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "/* auto-generated by gensyscalls.py, do not touch */\n" )
4111928523c870f7acd7f34870f4bb4ab9c6215bf7aElliott Hughes        fp.write( "#ifndef _BIONIC_LINUX_SYSCALLS_H_\n" )
4121928523c870f7acd7f34870f4bb4ab9c6215bf7aElliott Hughes        fp.write( "#define _BIONIC_LINUX_SYSCALLS_H_\n\n" )
4131fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H && !defined __ASM_MIPS_UNISTD_H\n" )
414a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__\n" )
4151fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "  #  define __NR_SYSCALL_BASE 0x900000\n" )
4161fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "#elif defined(__mips__)\n" )
4171fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "  #  define __NR_SYSCALL_BASE 4000\n" )
4181fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "#else\n" )
4191fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "  #  define __NR_SYSCALL_BASE 0\n" )
4201fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "#endif\n\n" )
421a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
422a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        # first, all common syscalls
4231fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        for sc in sorted(self.syscalls,key=lambda x:x["common"]):
4241fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            sc_id  = sc["common"]
425a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            sc_name = sc["name"]
4261fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if sc_id >= 0:
427a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                self.gen_NR_syscall( fp, sc_name, sc_id )
428a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
429a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        # now, all arm-specific syscalls
430a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "\n#ifdef __arm__\n" );
431a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for sc in self.syscalls:
4321fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            sc_id  = sc["armid"]
433a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            sc_name = sc["name"]
4341fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if sc_id >= 0:
435a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                self.gen_NR_syscall( fp, sc_name, sc_id )
436a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "#endif\n" );
437a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
4384e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        gen_syscalls = {}
439a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        # finally, all i386-specific syscalls
440a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "\n#ifdef __i386__\n" );
4411fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        for sc in sorted(self.syscalls,key=lambda x:x["x86id"]):
4421fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            sc_id  = sc["x86id"]
443a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            sc_name = sc["name"]
4441fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if sc_id >= 0 and sc_name not in gen_syscalls:
4451fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                self.gen_NR_syscall( fp, sc_name, sc_id )
4464e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                gen_syscalls[sc_name] = True
447a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "#endif\n" );
448a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
4491fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        # all mips-specific syscalls
4501fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "\n#ifdef __mips__\n" );
4511fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        for sc in sorted(self.syscalls,key=lambda x:x["mipsid"]):
4521fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            sc_id = sc["mipsid"]
4531fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if sc_id >= 0:
4541fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                self.gen_NR_syscall( fp, sc["name"], sc_id )
4551fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham        fp.write( "#endif\n" );
4561fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham
457a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "\n#endif\n" )
458a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "\n#endif /* _BIONIC_LINUX_SYSCALLS_H_ */\n" );
459a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.close()
460a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.other_files.append( path )
461a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
462a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
463a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    # now dump the contents of syscalls.mk
4644e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project    def gen_arch_syscalls_mk(self, arch):
4654e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        path = "arch-%s/syscalls.mk" % arch
466a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        D( "generating "+path )
467a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp = create_file( path )
468a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "# auto-generated by gensyscalls.py, do not touch\n" )
469a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.write( "syscall_src := \n" )
4704e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        arch_test = {
4714e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            "arm": lambda x: x.has_key("asm-arm") or x.has_key("asm-thumb"),
472ce0595d01de9103d40b83b35e0d6ac8b123aa24cShin-ichiro KAWASAKI            "x86": lambda x: x.has_key("asm-x86"),
4731fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            "mips": lambda x: x.has_key("asm-mips")
4744e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        }
4754e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project
476a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for sc in self.syscalls:
4774e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            if arch_test[arch](sc):
4784e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                fp.write("syscall_src += arch-%s/syscalls/%s.S\n" %
4794e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project                         (arch, sc["func"]))
480a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        fp.close()
481a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.other_files.append( path )
482a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
4831fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham
484a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    # now generate each syscall stub
485a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def gen_syscall_stubs(self):
486a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for sc in self.syscalls:
4874e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            if sc.has_key("asm-arm") and 'arm' in all_archs:
488a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fname = "arch-arm/syscalls/%s.S" % sc["func"]
489fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner                D2( ">>> generating "+fname )
490a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp = create_file( fname )
491a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp.write(sc["asm-arm"])
492a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp.close()
493a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                self.new_stubs.append( fname )
494a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
4954e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            if sc.has_key("asm-thumb") and 'arm' in all_archs:
496a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fname = "arch-arm/syscalls/%s.S" % sc["func"]
497fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner                D2( ">>> generating "+fname )
498a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp = create_file( fname )
499a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp.write(sc["asm-thumb"])
500a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp.close()
501a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                self.new_stubs.append( fname )
502a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
5034e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            if sc.has_key("asm-x86") and 'x86' in all_archs:
504a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fname = "arch-x86/syscalls/%s.S" % sc["func"]
505fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner                D2( ">>> generating "+fname )
506a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp = create_file( fname )
507a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp.write(sc["asm-x86"])
508a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                fp.close()
509a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                self.new_stubs.append( fname )
510a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
5111fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            if sc.has_key("asm-mips") and 'mips' in all_archs:
5121fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                fname = "arch-mips/syscalls/%s.S" % sc["func"]
5131fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                D2( ">>> generating "+fname )
5141fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                fp = create_file( fname )
5151fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                fp.write(sc["asm-mips"])
5161fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                fp.close()
5171fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham                self.new_stubs.append( fname )
518a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
519a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project    def  regenerate(self):
520a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        D( "scanning for existing architecture-specific stub files" )
521a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
522a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        bionic_root_len = len(bionic_root)
523a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
524a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for arch in all_archs:
525a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            arch_path = bionic_root + "arch-" + arch
526a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            D( "scanning " + arch_path )
527a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            files = glob.glob( arch_path + "/syscalls/*.S" )
528a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            for f in files:
529a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                self.old_stubs.append( f[bionic_root_len:] )
530a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
531a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        D( "found %d stub files" % len(self.old_stubs) )
532a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
533a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if not os.path.exists( bionic_temp ):
534a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            D( "creating %s" % bionic_temp )
5351fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham            make_dir( bionic_temp )
536a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
537a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#        D( "p4 editing source files" )
538a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#        for arch in all_archs:
539a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#            commands.getoutput( "p4 edit " + arch + "/syscalls/*.S " )
540a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#            commands.getoutput( "p4 edit " + arch + "/syscalls.mk" )
541a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project#        commands.getoutput( "p4 edit " + bionic_root + "include/sys/linux-syscalls.h" )
542a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
543a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        D( "re-generating stubs and support files" )
544a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
545a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.gen_linux_syscalls_h()
5464e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project        for arch in all_archs:
5474e468ed2eb86a2406e14f1eca82072ee501d05fdThe Android Open Source Project            self.gen_arch_syscalls_mk(arch)
548a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        self.gen_syscall_stubs()
549a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
550a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        D( "comparing files" )
551a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        adds    = []
552a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        edits   = []
553a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
554a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for stub in self.new_stubs + self.other_files:
555a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            if not os.path.exists( bionic_root + stub ):
556fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner                # new file, git add it
557a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                D( "new file:     " + stub)
558a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                adds.append( bionic_root + stub )
559a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                shutil.copyfile( bionic_temp + stub, bionic_root + stub )
560a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
561a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            elif not filecmp.cmp( bionic_temp + stub, bionic_root + stub ):
562a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                D( "changed file: " + stub)
563a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                edits.append( stub )
564a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
565a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        deletes = []
566a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        for stub in self.old_stubs:
567a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            if not stub in self.new_stubs:
568a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                D( "deleted file: " + stub)
569a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                deletes.append( bionic_root + stub )
570a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
571a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
572a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if adds:
573fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner            commands.getoutput("git add " + " ".join(adds))
574a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if deletes:
575fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner            commands.getoutput("git rm " + " ".join(deletes))
576a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project        if edits:
577a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project            for file in edits:
578a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project                shutil.copyfile( bionic_temp + file, bionic_root + file )
579fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner            commands.getoutput("git add " +
580fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner                               " ".join((bionic_root + file) for file in edits))
581a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
582fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner        commands.getoutput("git add %s%s" % (bionic_root,"SYSCALLS.TXT"))
583fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner
584fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner        if (not adds) and (not deletes) and (not edits):
585fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner            D("no changes detected!")
586fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner        else:
587fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner            D("ready to go!!")
588a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
589a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source ProjectD_setlevel(1)
590a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Project
591a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectstate = State()
592a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectstate.process_file(bionic_root+"SYSCALLS.TXT")
593a27d2baa0c1a2ec70f47ea9199b1dd6762c8a34The Android Open Source Projectstate.regenerate()
594