blob: 2e87e036d5343b1bd3b27c2e1c18cfa3b5da10b3 [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 Hughescda62092013-03-22 13:50:44 -070079#include <asm/unistd.h>
Elliott Hughes9aceab52013-03-12 14:57:30 -070080#include <linux/err.h>
Kenny Rootf540c032011-02-17 10:31:30 -080081#include <machine/asm.h>
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070082
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
Elliott Hughescda62092013-03-22 13:50:44 -0700194# This lets us support regular system calls like __NR_write and also weird
195# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
196def make__NR_name(name):
197 if name.startswith("__"):
198 return name
199 else:
200 return "__NR_%s" % (name)
201
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700202class State:
203 def __init__(self):
204 self.old_stubs = []
205 self.new_stubs = []
206 self.other_files = []
207 self.syscalls = []
208
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800209 def x86_genstub(self, fname, numparams, idname):
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700210 t = { "fname" : fname,
211 "idname" : idname }
212
213 result = x86_header % t
214 stack_bias = 4
215 for r in range(numparams):
216 result += " pushl " + x86_registers[r] + "\n"
217 stack_bias += 4
218
219 for r in range(numparams):
220 result += " mov %d(%%esp), %s" % (stack_bias+r*4, x86_registers[r]) + "\n"
221
222 result += x86_call % t
223
224 for r in range(numparams):
225 result += " popl " + x86_registers[numparams-r-1] + "\n"
226
Elliott Hughes7582a9c2013-02-06 17:08:15 -0800227 result += x86_return % t
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700228 return result
229
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800230 def x86_genstub_cid(self, fname, numparams, idname, cid):
231 # We'll ignore numparams here because in reality, if there is a
232 # dispatch call (like a socketcall syscall) there are actually
233 # only 2 arguments to the syscall and 2 regs we have to save:
234 # %ebx <--- Argument 1 - The call id of the needed vectored
235 # syscall (socket, bind, recv, etc)
236 # %ecx <--- Argument 2 - Pointer to the rest of the arguments
237 # from the original function called (socket())
238 t = { "fname" : fname,
239 "idname" : idname }
240
241 result = x86_header % t
242 stack_bias = 4
243
244 # save the regs we need
245 result += " pushl %ebx" + "\n"
246 stack_bias += 4
247 result += " pushl %ecx" + "\n"
248 stack_bias += 4
249
250 # set the call id (%ebx)
251 result += " mov $%d, %%ebx" % (cid) + "\n"
252
253 # set the pointer to the rest of the args into %ecx
254 result += " mov %esp, %ecx" + "\n"
255 result += " addl $%d, %%ecx" % (stack_bias) + "\n"
256
257 # now do the syscall code itself
258 result += x86_call % t
259
260 # now restore the saved regs
261 result += " popl %ecx" + "\n"
262 result += " popl %ebx" + "\n"
263
264 # epilog
Elliott Hughes7582a9c2013-02-06 17:08:15 -0800265 result += x86_return % t
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800266 return result
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700267
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700268
269 def arm_eabi_genstub(self,fname, flags, idname):
270 t = { "fname" : fname,
271 "idname" : idname }
272 if flags:
273 numargs = int(flags)
274 if numargs > 4:
275 return arm_eabi_call_long % t
276 return arm_eabi_call_default % t
277
278
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800279 def mips_genstub(self,fname, idname):
280 t = { "fname" : fname,
281 "idname" : idname }
282 return mips_call % t
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700283
284 def process_file(self,input):
285 parser = SysCallsTxtParser()
286 parser.parse_file(input)
287 self.syscalls = parser.syscalls
288 parser = None
289
290 for t in self.syscalls:
291 syscall_func = t["func"]
292 syscall_params = t["params"]
293 syscall_name = t["name"]
294
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800295 if t["common"] >= 0 or t["armid"] >= 0:
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100296 num_regs = count_arm_param_registers(syscall_params)
Elliott Hughescda62092013-03-22 13:50:44 -0700297 t["asm-arm"] = self.arm_eabi_genstub(syscall_func, num_regs, make__NR_name(syscall_name))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700298
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800299 if t["common"] >= 0 or t["x86id"] >= 0:
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100300 num_regs = count_generic_param_registers(syscall_params)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800301 if t["cid"] >= 0:
Elliott Hughescda62092013-03-22 13:50:44 -0700302 t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, make__NR_name(syscall_name), t["cid"])
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800303 else:
Elliott Hughescda62092013-03-22 13:50:44 -0700304 t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, make__NR_name(syscall_name))
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800305 elif t["cid"] >= 0:
306 E("cid for dispatch syscalls is only supported for x86 in "
307 "'%s'" % syscall_name)
308 return
Elliott Hughescd6780b2013-02-07 14:07:00 -0800309
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800310 if t["common"] >= 0 or t["mipsid"] >= 0:
Elliott Hughescda62092013-03-22 13:50:44 -0700311 t["asm-mips"] = self.mips_genstub(syscall_func, make__NR_name(syscall_name))
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800312
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700313
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700314 def gen_NR_syscall(self, linux_fp, name, id):
Elliott Hughescda62092013-03-22 13:50:44 -0700315 linux_fp.write("#define %-30s (__NR_SYSCALL_BASE + %d)\n" % (make__NR_name(name),id))
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700316
317
318 def scan_linux_unistd_h(self, fp, path):
319 pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
320 syscalls = set() # MIPS defines everything three times; work around that.
321 for line in open(path):
322 m = re.search(pattern, line)
323 if m:
324 syscalls.add(m.group(1))
325 for syscall in sorted(syscalls):
Elliott Hughescda62092013-03-22 13:50:44 -0700326 fp.write("#define SYS_%s %s\n" % (syscall, make__NR_name(syscall)))
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700327
328
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700329 def gen_linux_syscalls_h(self):
Elliott Hughescda62092013-03-22 13:50:44 -0700330 # TODO: generate a separate file for each architecture, like glibc's bits/syscall.h.
Elliott Hughes9724ce32013-03-21 19:43:54 -0700331 glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
332 glibc_fp = create_file(glibc_syscalls_h_path)
333 glibc_fp.write("/* Auto-generated by gensyscalls.py; do not edit. */\n")
334 glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
335 glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
336
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700337 glibc_fp.write("#if defined(__arm__)\n")
338 self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-arm/asm/unistd.h")
339 glibc_fp.write("#elif defined(__mips__)\n")
340 self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-mips/asm/unistd.h")
341 glibc_fp.write("#elif defined(__i386__)\n")
342 self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-x86/asm/unistd_32.h")
343 glibc_fp.write("#endif\n")
344
345 glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
346 glibc_fp.close()
347 self.other_files.append(glibc_syscalls_h_path)
348
Elliott Hughescda62092013-03-22 13:50:44 -0700349 # TODO: stop generating this. it's useless.
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700350 linux_syscalls_h_path = "include/sys/linux-syscalls.h"
351 D("generating " + linux_syscalls_h_path)
352 fp = create_file(linux_syscalls_h_path)
353 fp.write( "/* Auto-generated by gensyscalls.py; do not edit. */\n" )
Elliott Hughes19285232012-05-09 16:34:11 -0700354 fp.write( "#ifndef _BIONIC_LINUX_SYSCALLS_H_\n" )
355 fp.write( "#define _BIONIC_LINUX_SYSCALLS_H_\n\n" )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800356 fp.write( "#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H && !defined __ASM_MIPS_UNISTD_H\n" )
Elliott Hughescda62092013-03-22 13:50:44 -0700357
358 fp.write( "#if defined(__mips__)\n" )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800359 fp.write( " # define __NR_SYSCALL_BASE 4000\n" )
360 fp.write( "#else\n" )
361 fp.write( " # define __NR_SYSCALL_BASE 0\n" )
362 fp.write( "#endif\n\n" )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700363
364 # first, all common syscalls
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800365 for sc in sorted(self.syscalls,key=lambda x:x["common"]):
366 sc_id = sc["common"]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700367 sc_name = sc["name"]
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800368 if sc_id >= 0:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700369 self.gen_NR_syscall(fp, sc_name, sc_id)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700370
371 # now, all arm-specific syscalls
Elliott Hughes9724ce32013-03-21 19:43:54 -0700372 fp.write("\n#ifdef __arm__\n")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700373 for sc in self.syscalls:
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800374 sc_id = sc["armid"]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700375 sc_name = sc["name"]
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800376 if sc_id >= 0:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700377 self.gen_NR_syscall(fp, sc_name, sc_id)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700378 fp.write("#endif\n")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700379
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800380 gen_syscalls = {}
Elliott Hughes9724ce32013-03-21 19:43:54 -0700381 # all i386-specific syscalls
382 fp.write("\n#ifdef __i386__\n")
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800383 for sc in sorted(self.syscalls,key=lambda x:x["x86id"]):
384 sc_id = sc["x86id"]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700385 sc_name = sc["name"]
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800386 if sc_id >= 0 and sc_name not in gen_syscalls:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700387 self.gen_NR_syscall(fp, sc_name, sc_id)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800388 gen_syscalls[sc_name] = True
Elliott Hughes9724ce32013-03-21 19:43:54 -0700389 fp.write("#endif\n")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700390
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800391 # all mips-specific syscalls
Elliott Hughes9724ce32013-03-21 19:43:54 -0700392 fp.write("\n#ifdef __mips__\n")
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800393 for sc in sorted(self.syscalls,key=lambda x:x["mipsid"]):
394 sc_id = sc["mipsid"]
395 if sc_id >= 0:
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700396 self.gen_NR_syscall(fp, sc["name"], sc_id)
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800397 fp.write( "#endif\n" );
398
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700399 fp.write( "\n#endif\n" )
400 fp.write( "\n#endif /* _BIONIC_LINUX_SYSCALLS_H_ */\n" );
401 fp.close()
Elliott Hughes9724ce32013-03-21 19:43:54 -0700402
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700403 self.other_files.append(linux_syscalls_h_path)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700404
405
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700406 # now dump the contents of syscalls.mk
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800407 def gen_arch_syscalls_mk(self, arch):
408 path = "arch-%s/syscalls.mk" % arch
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700409 D( "generating "+path )
410 fp = create_file( path )
411 fp.write( "# auto-generated by gensyscalls.py, do not touch\n" )
412 fp.write( "syscall_src := \n" )
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800413 arch_test = {
Elliott Hughescd6780b2013-02-07 14:07:00 -0800414 "arm": lambda x: x.has_key("asm-arm"),
Shin-ichiro KAWASAKIce0595d2009-09-01 19:03:06 +0900415 "x86": lambda x: x.has_key("asm-x86"),
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800416 "mips": lambda x: x.has_key("asm-mips")
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800417 }
418
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700419 for sc in self.syscalls:
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800420 if arch_test[arch](sc):
421 fp.write("syscall_src += arch-%s/syscalls/%s.S\n" %
422 (arch, sc["func"]))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700423 fp.close()
424 self.other_files.append( path )
425
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800426
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700427 # now generate each syscall stub
428 def gen_syscall_stubs(self):
429 for sc in self.syscalls:
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800430 if sc.has_key("asm-arm") and 'arm' in all_archs:
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700431 fname = "arch-arm/syscalls/%s.S" % sc["func"]
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200432 D2( ">>> generating "+fname )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700433 fp = create_file( fname )
434 fp.write(sc["asm-arm"])
435 fp.close()
436 self.new_stubs.append( fname )
437
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800438 if sc.has_key("asm-x86") and 'x86' in all_archs:
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700439 fname = "arch-x86/syscalls/%s.S" % sc["func"]
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200440 D2( ">>> generating "+fname )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700441 fp = create_file( fname )
442 fp.write(sc["asm-x86"])
443 fp.close()
444 self.new_stubs.append( fname )
445
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800446 if sc.has_key("asm-mips") and 'mips' in all_archs:
447 fname = "arch-mips/syscalls/%s.S" % sc["func"]
448 D2( ">>> generating "+fname )
449 fp = create_file( fname )
450 fp.write(sc["asm-mips"])
451 fp.close()
452 self.new_stubs.append( fname )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700453
454 def regenerate(self):
455 D( "scanning for existing architecture-specific stub files" )
456
457 bionic_root_len = len(bionic_root)
458
459 for arch in all_archs:
460 arch_path = bionic_root + "arch-" + arch
461 D( "scanning " + arch_path )
462 files = glob.glob( arch_path + "/syscalls/*.S" )
463 for f in files:
464 self.old_stubs.append( f[bionic_root_len:] )
465
466 D( "found %d stub files" % len(self.old_stubs) )
467
468 if not os.path.exists( bionic_temp ):
469 D( "creating %s" % bionic_temp )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800470 make_dir( bionic_temp )
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700471
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700472 D( "re-generating stubs and support files" )
473
474 self.gen_linux_syscalls_h()
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800475 for arch in all_archs:
476 self.gen_arch_syscalls_mk(arch)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700477 self.gen_syscall_stubs()
478
479 D( "comparing files" )
480 adds = []
481 edits = []
482
483 for stub in self.new_stubs + self.other_files:
484 if not os.path.exists( bionic_root + stub ):
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200485 # new file, git add it
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700486 D( "new file: " + stub)
487 adds.append( bionic_root + stub )
488 shutil.copyfile( bionic_temp + stub, bionic_root + stub )
489
490 elif not filecmp.cmp( bionic_temp + stub, bionic_root + stub ):
491 D( "changed file: " + stub)
492 edits.append( stub )
493
494 deletes = []
495 for stub in self.old_stubs:
496 if not stub in self.new_stubs:
497 D( "deleted file: " + stub)
498 deletes.append( bionic_root + stub )
499
500
501 if adds:
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200502 commands.getoutput("git add " + " ".join(adds))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700503 if deletes:
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200504 commands.getoutput("git rm " + " ".join(deletes))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700505 if edits:
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700506 for file in edits:
507 shutil.copyfile( bionic_temp + file, bionic_root + file )
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200508 commands.getoutput("git add " +
509 " ".join((bionic_root + file) for file in edits))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700510
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200511 commands.getoutput("git add %s%s" % (bionic_root,"SYSCALLS.TXT"))
512
513 if (not adds) and (not deletes) and (not edits):
514 D("no changes detected!")
515 else:
516 D("ready to go!!")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700517
518D_setlevel(1)
519
520state = State()
521state.process_file(bionic_root+"SYSCALLS.TXT")
522state.regenerate()