blob: 26cf3a573a18093bf215a3628ea70558ec805ee3 [file] [log] [blame]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001#!/usr/bin/python
2#
Raghu Gandham1fa0d842012-01-27 17:51:42 -08003# this tool is used to generate the syscall assembler templates
4# to be placed into arch-{arm,x86,mips}/syscalls, as well as the content
5# of arch-{arm,x86,mips}/linux/_syscalls.h
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07006#
7
The Android Open Source Project4e468ed2008-12-17 18:03:48 -08008import sys, os.path, glob, re, commands, filecmp, shutil
Raghu Gandham1fa0d842012-01-27 17:51:42 -08009import getpass
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070010
11from bionic_utils import *
12
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070013# get the root Bionic directory, simply this script's dirname
14#
15bionic_root = find_bionic_root()
16if not bionic_root:
17 print "could not find the Bionic root directory. aborting"
18 sys.exit(1)
19
20if bionic_root[-1] != '/':
21 bionic_root += "/"
22
23print "bionic_root is %s" % bionic_root
24
25# temp directory where we store all intermediate files
26bionic_temp = "/tmp/bionic_gensyscalls/"
27
28# all architectures, update as you see fit
Elliott Hughescd6780b2013-02-07 14:07:00 -080029all_archs = [ "arm", "mips", "x86" ]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070030
31def make_dir( path ):
Raghu Gandham1fa0d842012-01-27 17:51:42 -080032 path = os.path.abspath(path)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070033 if not os.path.exists(path):
34 parent = os.path.dirname(path)
35 if parent:
36 make_dir(parent)
37 os.mkdir(path)
38
39def create_file( relpath ):
40 dir = os.path.dirname( bionic_temp + relpath )
41 make_dir(dir)
42 return open( bionic_temp + relpath, "w" )
43
Elliott Hughescd6780b2013-02-07 14:07:00 -080044#
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070045# x86 assembler templates for each syscall stub
46#
47
48x86_header = """/* autogenerated by gensyscalls.py */
Elliott Hughes9aceab52013-03-12 14:57:30 -070049#include <linux/err.h>
Elliott Hughes7582a9c2013-02-06 17:08:15 -080050#include <machine/asm.h>
Elliott Hughes5c2772f2013-03-21 22:15:06 -070051#include <asm/unistd.h>
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070052
Elliott Hughes7582a9c2013-02-06 17:08:15 -080053ENTRY(%(fname)s)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070054"""
55
56x86_registers = [ "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp" ]
57
58x86_call = """ movl $%(idname)s, %%eax
59 int $0x80
Elliott Hughes9aceab52013-03-12 14:57:30 -070060 cmpl $-MAX_ERRNO, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070061 jb 1f
62 negl %%eax
63 pushl %%eax
64 call __set_errno
65 addl $4, %%esp
66 orl $-1, %%eax
671:
68"""
69
70x86_return = """ ret
Elliott Hughes7582a9c2013-02-06 17:08:15 -080071END(%(fname)s)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070072"""
73
Elliott Hughescd6780b2013-02-07 14:07:00 -080074#
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070075# ARM assembler templates for each syscall stub
76#
Elliott Hughescd6780b2013-02-07 14:07:00 -080077
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070078arm_header = """/* autogenerated by gensyscalls.py */
Elliott Hughes9aceab52013-03-12 14:57:30 -070079#include <linux/err.h>
Kenny Rootf540c032011-02-17 10:31:30 -080080#include <machine/asm.h>
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070081#include <sys/linux-syscalls.h>
82
Kenny Rootf540c032011-02-17 10:31:30 -080083ENTRY(%(fname)s)
84"""
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070085
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070086arm_eabi_call_default = arm_header + """\
Matthieu Castetfaa0fdb2013-01-16 14:02:50 +010087 mov ip, r7
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070088 ldr r7, =%(idname)s
89 swi #0
Matthieu Castetfaa0fdb2013-01-16 14:02:50 +010090 mov r7, ip
Elliott Hughes9aceab52013-03-12 14:57:30 -070091 cmn r0, #(MAX_ERRNO + 1)
92 bxls lr
93 neg r0, r0
94 b __set_errno
Elliott Hughescd6780b2013-02-07 14:07:00 -080095END(%(fname)s)
96"""
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070097
98arm_eabi_call_long = arm_header + """\
99 mov ip, sp
100 .save {r4, r5, r6, r7}
101 stmfd sp!, {r4, r5, r6, r7}
102 ldmfd ip, {r4, r5, r6}
103 ldr r7, =%(idname)s
104 swi #0
105 ldmfd sp!, {r4, r5, r6, r7}
Elliott Hughes9aceab52013-03-12 14:57:30 -0700106 cmn r0, #(MAX_ERRNO + 1)
107 bxls lr
108 neg r0, r0
109 b __set_errno
Elliott Hughescd6780b2013-02-07 14:07:00 -0800110END(%(fname)s)
111"""
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700112
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700113#
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800114# mips assembler templates for each syscall stub
115#
Elliott Hughescd6780b2013-02-07 14:07:00 -0800116
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800117mips_call = """/* autogenerated by gensyscalls.py */
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700118#include <asm/unistd.h>
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800119 .text
120 .globl %(fname)s
121 .align 4
122 .ent %(fname)s
123
124%(fname)s:
125 .set noreorder
126 .cpload $t9
127 li $v0, %(idname)s
128 syscall
129 bnez $a3, 1f
130 move $a0, $v0
131 j $ra
132 nop
1331:
134 la $t9,__set_errno
135 j $t9
136 nop
137 .set reorder
138 .end %(fname)s
139"""
140
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100141def param_uses_64bits(param):
142 """Returns True iff a syscall parameter description corresponds
143 to a 64-bit type."""
144 param = param.strip()
145 # First, check that the param type begins with one of the known
146 # 64-bit types.
147 if not ( \
148 param.startswith("int64_t") or param.startswith("uint64_t") or \
149 param.startswith("loff_t") or param.startswith("off64_t") or \
150 param.startswith("long long") or param.startswith("unsigned long long") or
151 param.startswith("signed long long") ):
152 return False
153
154 # Second, check that there is no pointer type here
155 if param.find("*") >= 0:
156 return False
157
158 # Ok
159 return True
160
161def count_arm_param_registers(params):
162 """This function is used to count the number of register used
Elliott Hughescd6780b2013-02-07 14:07:00 -0800163 to pass parameters when invoking an ARM system call.
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100164 This is because the ARM EABI mandates that 64-bit quantities
165 must be passed in an even+odd register pair. So, for example,
166 something like:
167
168 foo(int fd, off64_t pos)
169
170 would actually need 4 registers:
171 r0 -> int
172 r1 -> unused
173 r2-r3 -> pos
174 """
175 count = 0
176 for param in params:
177 if param_uses_64bits(param):
178 if (count & 1) != 0:
179 count += 1
180 count += 2
181 else:
182 count += 1
183 return count
184
185def count_generic_param_registers(params):
186 count = 0
187 for param in params:
188 if param_uses_64bits(param):
189 count += 2
190 else:
191 count += 1
192 return count
193
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700194class State:
195 def __init__(self):
196 self.old_stubs = []
197 self.new_stubs = []
198 self.other_files = []
199 self.syscalls = []
200
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800201 def x86_genstub(self, fname, numparams, idname):
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700202 t = { "fname" : fname,
203 "idname" : idname }
204
205 result = x86_header % t
206 stack_bias = 4
207 for r in range(numparams):
208 result += " pushl " + x86_registers[r] + "\n"
209 stack_bias += 4
210
211 for r in range(numparams):
212 result += " mov %d(%%esp), %s" % (stack_bias+r*4, x86_registers[r]) + "\n"
213
214 result += x86_call % t
215
216 for r in range(numparams):
217 result += " popl " + x86_registers[numparams-r-1] + "\n"
218
Elliott Hughes7582a9c2013-02-06 17:08:15 -0800219 result += x86_return % t
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700220 return result
221
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800222 def x86_genstub_cid(self, fname, numparams, idname, cid):
223 # We'll ignore numparams here because in reality, if there is a
224 # dispatch call (like a socketcall syscall) there are actually
225 # only 2 arguments to the syscall and 2 regs we have to save:
226 # %ebx <--- Argument 1 - The call id of the needed vectored
227 # syscall (socket, bind, recv, etc)
228 # %ecx <--- Argument 2 - Pointer to the rest of the arguments
229 # from the original function called (socket())
230 t = { "fname" : fname,
231 "idname" : idname }
232
233 result = x86_header % t
234 stack_bias = 4
235
236 # save the regs we need
237 result += " pushl %ebx" + "\n"
238 stack_bias += 4
239 result += " pushl %ecx" + "\n"
240 stack_bias += 4
241
242 # set the call id (%ebx)
243 result += " mov $%d, %%ebx" % (cid) + "\n"
244
245 # set the pointer to the rest of the args into %ecx
246 result += " mov %esp, %ecx" + "\n"
247 result += " addl $%d, %%ecx" % (stack_bias) + "\n"
248
249 # now do the syscall code itself
250 result += x86_call % t
251
252 # now restore the saved regs
253 result += " popl %ecx" + "\n"
254 result += " popl %ebx" + "\n"
255
256 # epilog
Elliott Hughes7582a9c2013-02-06 17:08:15 -0800257 result += x86_return % t
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800258 return result
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700259
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700260
261 def arm_eabi_genstub(self,fname, flags, idname):
262 t = { "fname" : fname,
263 "idname" : idname }
264 if flags:
265 numargs = int(flags)
266 if numargs > 4:
267 return arm_eabi_call_long % t
268 return arm_eabi_call_default % t
269
270
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800271 def mips_genstub(self,fname, idname):
272 t = { "fname" : fname,
273 "idname" : idname }
274 return mips_call % t
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700275
276 def process_file(self,input):
277 parser = SysCallsTxtParser()
278 parser.parse_file(input)
279 self.syscalls = parser.syscalls
280 parser = None
281
282 for t in self.syscalls:
283 syscall_func = t["func"]
284 syscall_params = t["params"]
285 syscall_name = t["name"]
286
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800287 if t["common"] >= 0 or t["armid"] >= 0:
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100288 num_regs = count_arm_param_registers(syscall_params)
Elliott Hughescd6780b2013-02-07 14:07:00 -0800289 t["asm-arm"] = self.arm_eabi_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700290
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800291 if t["common"] >= 0 or t["x86id"] >= 0:
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100292 num_regs = count_generic_param_registers(syscall_params)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800293 if t["cid"] >= 0:
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100294 t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, "__NR_"+syscall_name, t["cid"])
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800295 else:
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100296 t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, "__NR_"+syscall_name)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800297 elif t["cid"] >= 0:
298 E("cid for dispatch syscalls is only supported for x86 in "
299 "'%s'" % syscall_name)
300 return
Elliott Hughescd6780b2013-02-07 14:07:00 -0800301
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800302 if t["common"] >= 0 or t["mipsid"] >= 0:
303 t["asm-mips"] = self.mips_genstub(syscall_func,"__NR_"+syscall_name)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800304
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700305
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700306 def gen_NR_syscall(self, linux_fp, name, id):
Elliott Hughes9724ce32013-03-21 19:43:54 -0700307 linux_fp.write("#define __NR_%-25s (__NR_SYSCALL_BASE + %d)\n" % (name,id))
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700308
309
310 def scan_linux_unistd_h(self, fp, path):
311 pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
312 syscalls = set() # MIPS defines everything three times; work around that.
313 for line in open(path):
314 m = re.search(pattern, line)
315 if m:
316 syscalls.add(m.group(1))
317 for syscall in sorted(syscalls):
318 fp.write("#define SYS_%s __NR_%s\n" % (syscall, syscall))
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700319
320
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700321 def gen_linux_syscalls_h(self):
Elliott Hughes9724ce32013-03-21 19:43:54 -0700322 glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
323 glibc_fp = create_file(glibc_syscalls_h_path)
324 glibc_fp.write("/* Auto-generated by gensyscalls.py; do not edit. */\n")
325 glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
326 glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
327
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700328 glibc_fp.write("#if defined(__arm__)\n")
329 self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-arm/asm/unistd.h")
330 glibc_fp.write("#elif defined(__mips__)\n")
331 self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-mips/asm/unistd.h")
332 glibc_fp.write("#elif defined(__i386__)\n")
333 self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-x86/asm/unistd_32.h")
334 glibc_fp.write("#endif\n")
335
336 glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
337 glibc_fp.close()
338 self.other_files.append(glibc_syscalls_h_path)
339
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700340 linux_syscalls_h_path = "include/sys/linux-syscalls.h"
341 D("generating " + linux_syscalls_h_path)
342 fp = create_file(linux_syscalls_h_path)
343 fp.write( "/* Auto-generated by gensyscalls.py; do not edit. */\n" )
Elliott Hughes19285232012-05-09 16:34:11 -0700344 fp.write( "#ifndef _BIONIC_LINUX_SYSCALLS_H_\n" )
345 fp.write( "#define _BIONIC_LINUX_SYSCALLS_H_\n\n" )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800346 fp.write( "#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H && !defined __ASM_MIPS_UNISTD_H\n" )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700347 fp.write( "#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__\n" )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800348 fp.write( " # define __NR_SYSCALL_BASE 0x900000\n" )
349 fp.write( "#elif defined(__mips__)\n" )
350 fp.write( " # define __NR_SYSCALL_BASE 4000\n" )
351 fp.write( "#else\n" )
352 fp.write( " # define __NR_SYSCALL_BASE 0\n" )
353 fp.write( "#endif\n\n" )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700354
355 # first, all common syscalls
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800356 for sc in sorted(self.syscalls,key=lambda x:x["common"]):
357 sc_id = sc["common"]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700358 sc_name = sc["name"]
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800359 if sc_id >= 0:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700360 self.gen_NR_syscall(fp, sc_name, sc_id)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700361
362 # now, all arm-specific syscalls
Elliott Hughes9724ce32013-03-21 19:43:54 -0700363 fp.write("\n#ifdef __arm__\n")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700364 for sc in self.syscalls:
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800365 sc_id = sc["armid"]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700366 sc_name = sc["name"]
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800367 if sc_id >= 0:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700368 self.gen_NR_syscall(fp, sc_name, sc_id)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700369 fp.write("#endif\n")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700370
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800371 gen_syscalls = {}
Elliott Hughes9724ce32013-03-21 19:43:54 -0700372 # all i386-specific syscalls
373 fp.write("\n#ifdef __i386__\n")
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800374 for sc in sorted(self.syscalls,key=lambda x:x["x86id"]):
375 sc_id = sc["x86id"]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700376 sc_name = sc["name"]
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800377 if sc_id >= 0 and sc_name not in gen_syscalls:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700378 self.gen_NR_syscall(fp, sc_name, sc_id)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800379 gen_syscalls[sc_name] = True
Elliott Hughes9724ce32013-03-21 19:43:54 -0700380 fp.write("#endif\n")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700381
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800382 # all mips-specific syscalls
Elliott Hughes9724ce32013-03-21 19:43:54 -0700383 fp.write("\n#ifdef __mips__\n")
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800384 for sc in sorted(self.syscalls,key=lambda x:x["mipsid"]):
385 sc_id = sc["mipsid"]
386 if sc_id >= 0:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700387 self.gen_NR_syscall(fp, sc["name"], sc_id)
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800388 fp.write( "#endif\n" );
389
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700390 fp.write( "\n#endif\n" )
391 fp.write( "\n#endif /* _BIONIC_LINUX_SYSCALLS_H_ */\n" );
392 fp.close()
Elliott Hughes9724ce32013-03-21 19:43:54 -0700393
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700394 self.other_files.append(linux_syscalls_h_path)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700395
396
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700397 # now dump the contents of syscalls.mk
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800398 def gen_arch_syscalls_mk(self, arch):
399 path = "arch-%s/syscalls.mk" % arch
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700400 D( "generating "+path )
401 fp = create_file( path )
402 fp.write( "# auto-generated by gensyscalls.py, do not touch\n" )
403 fp.write( "syscall_src := \n" )
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800404 arch_test = {
Elliott Hughescd6780b2013-02-07 14:07:00 -0800405 "arm": lambda x: x.has_key("asm-arm"),
Shin-ichiro KAWASAKIce0595d2009-09-01 19:03:06 +0900406 "x86": lambda x: x.has_key("asm-x86"),
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800407 "mips": lambda x: x.has_key("asm-mips")
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800408 }
409
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700410 for sc in self.syscalls:
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800411 if arch_test[arch](sc):
412 fp.write("syscall_src += arch-%s/syscalls/%s.S\n" %
413 (arch, sc["func"]))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700414 fp.close()
415 self.other_files.append( path )
416
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800417
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700418 # now generate each syscall stub
419 def gen_syscall_stubs(self):
420 for sc in self.syscalls:
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800421 if sc.has_key("asm-arm") and 'arm' in all_archs:
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700422 fname = "arch-arm/syscalls/%s.S" % sc["func"]
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200423 D2( ">>> generating "+fname )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700424 fp = create_file( fname )
425 fp.write(sc["asm-arm"])
426 fp.close()
427 self.new_stubs.append( fname )
428
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800429 if sc.has_key("asm-x86") and 'x86' in all_archs:
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700430 fname = "arch-x86/syscalls/%s.S" % sc["func"]
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200431 D2( ">>> generating "+fname )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700432 fp = create_file( fname )
433 fp.write(sc["asm-x86"])
434 fp.close()
435 self.new_stubs.append( fname )
436
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800437 if sc.has_key("asm-mips") and 'mips' in all_archs:
438 fname = "arch-mips/syscalls/%s.S" % sc["func"]
439 D2( ">>> generating "+fname )
440 fp = create_file( fname )
441 fp.write(sc["asm-mips"])
442 fp.close()
443 self.new_stubs.append( fname )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700444
445 def regenerate(self):
446 D( "scanning for existing architecture-specific stub files" )
447
448 bionic_root_len = len(bionic_root)
449
450 for arch in all_archs:
451 arch_path = bionic_root + "arch-" + arch
452 D( "scanning " + arch_path )
453 files = glob.glob( arch_path + "/syscalls/*.S" )
454 for f in files:
455 self.old_stubs.append( f[bionic_root_len:] )
456
457 D( "found %d stub files" % len(self.old_stubs) )
458
459 if not os.path.exists( bionic_temp ):
460 D( "creating %s" % bionic_temp )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800461 make_dir( bionic_temp )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700462
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700463 D( "re-generating stubs and support files" )
464
465 self.gen_linux_syscalls_h()
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800466 for arch in all_archs:
467 self.gen_arch_syscalls_mk(arch)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700468 self.gen_syscall_stubs()
469
470 D( "comparing files" )
471 adds = []
472 edits = []
473
474 for stub in self.new_stubs + self.other_files:
475 if not os.path.exists( bionic_root + stub ):
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200476 # new file, git add it
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700477 D( "new file: " + stub)
478 adds.append( bionic_root + stub )
479 shutil.copyfile( bionic_temp + stub, bionic_root + stub )
480
481 elif not filecmp.cmp( bionic_temp + stub, bionic_root + stub ):
482 D( "changed file: " + stub)
483 edits.append( stub )
484
485 deletes = []
486 for stub in self.old_stubs:
487 if not stub in self.new_stubs:
488 D( "deleted file: " + stub)
489 deletes.append( bionic_root + stub )
490
491
492 if adds:
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200493 commands.getoutput("git add " + " ".join(adds))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700494 if deletes:
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200495 commands.getoutput("git rm " + " ".join(deletes))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700496 if edits:
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700497 for file in edits:
498 shutil.copyfile( bionic_temp + file, bionic_root + file )
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200499 commands.getoutput("git add " +
500 " ".join((bionic_root + file) for file in edits))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700501
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200502 commands.getoutput("git add %s%s" % (bionic_root,"SYSCALLS.TXT"))
503
504 if (not adds) and (not deletes) and (not edits):
505 D("no changes detected!")
506 else:
507 D("ready to go!!")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700508
509D_setlevel(1)
510
511state = State()
512state.process_file(bionic_root+"SYSCALLS.TXT")
513state.regenerate()