blob: 7b1afbbf4a6ad78604510c89e410b62b01031620 [file] [log] [blame]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001#!/usr/bin/python
Pavel Chupinf12a18b2012-12-12 13:11:48 +04002
3# This tool is used to generate the assembler system call stubs,
4# the header files listing all available system calls, and the
5# makefiles used to build all the stubs.
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07006
Elliott Hughes103ccde2013-10-16 14:27:59 -07007import commands
8import filecmp
9import glob
10import os.path
11import re
12import shutil
13import stat
14import sys
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070015
16from bionic_utils import *
17
Elliott Hughes18bc9752013-06-17 10:26:10 -070018bionic_libc_root = os.environ["ANDROID_BUILD_TOP"] + "/bionic/libc/"
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070019
20# temp directory where we store all intermediate files
21bionic_temp = "/tmp/bionic_gensyscalls/"
22
Elliott Hughes103ccde2013-10-16 14:27:59 -070023warning = "Generated by gensyscalls.py. Do not edit."
24
Pavel Chupinf12a18b2012-12-12 13:11:48 +040025DRY_RUN = False
26
27def make_dir(path):
Raghu Gandham1fa0d842012-01-27 17:51:42 -080028 path = os.path.abspath(path)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070029 if not os.path.exists(path):
30 parent = os.path.dirname(path)
31 if parent:
32 make_dir(parent)
33 os.mkdir(path)
34
Elliott Hughes0437f3f2013-10-07 23:53:13 -070035
Pavel Chupinf12a18b2012-12-12 13:11:48 +040036def create_file(relpath):
37 dir = os.path.dirname(bionic_temp + relpath)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070038 make_dir(dir)
Pavel Chupinf12a18b2012-12-12 13:11:48 +040039 return open(bionic_temp + relpath, "w")
40
41
Elliott Hughes103ccde2013-10-16 14:27:59 -070042syscall_stub_header = "/* " + warning + " */\n" + \
43"""
Elliott Hughesed744842013-11-07 10:31:05 -080044#include <private/bionic_asm.h>
Pavel Chupinf12a18b2012-12-12 13:11:48 +040045
Elliott Hughes0437f3f2013-10-07 23:53:13 -070046ENTRY(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +040047"""
48
Elliott Hughes0437f3f2013-10-07 23:53:13 -070049
H.J. Lu6fe4e872013-10-04 10:03:17 -070050function_alias = """
51 .globl _C_LABEL(%(alias)s)
Elliott Hughes0437f3f2013-10-07 23:53:13 -070052 .equ _C_LABEL(%(alias)s), _C_LABEL(%(func)s)
H.J. Lu6fe4e872013-10-04 10:03:17 -070053"""
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070054
Elliott Hughes0437f3f2013-10-07 23:53:13 -070055
56#
Serban Constantinescufeaa89a2013-10-07 16:49:09 +010057# AArch64 assembler templates for each syscall stub
58#
59
60aarch64_call = syscall_stub_header + """\
61 stp x29, x30, [sp, #-16]!
62 mov x29, sp
63 str x8, [sp, #-16]!
64
65 mov x8, %(__NR_name)s
66 svc #0
67
68 ldr x8, [sp], #16
69 ldp x29, x30, [sp], #16
70
71 cmn x0, #(MAX_ERRNO + 1)
72 cneg x0, x0, hi
73 b.hi __set_errno
74
75 ret
76END(%(func)s)
77"""
78
79#
Elliott Hughes0437f3f2013-10-07 23:53:13 -070080# ARM assembler templates for each syscall stub
81#
82
83arm_eabi_call_default = syscall_stub_header + """\
84 mov ip, r7
85 ldr r7, =%(__NR_name)s
86 swi #0
87 mov r7, ip
88 cmn r0, #(MAX_ERRNO + 1)
89 bxls lr
90 neg r0, r0
91 b __set_errno
92END(%(func)s)
93"""
94
95arm_eabi_call_long = syscall_stub_header + """\
96 mov ip, sp
Elliott Hughes0437f3f2013-10-07 23:53:13 -070097 stmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080098 .cfi_def_cfa_offset 16
99 .cfi_rel_offset r4, 0
100 .cfi_rel_offset r5, 4
101 .cfi_rel_offset r6, 8
102 .cfi_rel_offset r7, 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700103 ldmfd ip, {r4, r5, r6}
104 ldr r7, =%(__NR_name)s
105 swi #0
106 ldmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -0800107 .cfi_def_cfa_offset 0
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700108 cmn r0, #(MAX_ERRNO + 1)
109 bxls lr
110 neg r0, r0
111 b __set_errno
112END(%(func)s)
113"""
114
115
116#
117# MIPS assembler templates for each syscall stub
118#
119
Elliott Hughes103ccde2013-10-16 14:27:59 -0700120mips_call = "/* " + warning + " */\n" + \
121"""
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700122#include <asm/unistd.h>
123 .text
124 .globl %(func)s
125 .align 4
126 .ent %(func)s
127
128%(func)s:
129 .set noreorder
130 .cpload $t9
131 li $v0, %(__NR_name)s
132 syscall
133 bnez $a3, 1f
134 move $a0, $v0
135 j $ra
136 nop
1371:
138 la $t9,__set_errno
139 j $t9
140 nop
141 .set reorder
142 .end %(func)s
143"""
144
145
Elliott Hughescd6780b2013-02-07 14:07:00 -0800146#
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700147# x86 assembler templates for each syscall stub
148#
149
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800150x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700151
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700152x86_call = """\
153 movl $%(__NR_name)s, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700154 int $0x80
Elliott Hughes9aceab52013-03-12 14:57:30 -0700155 cmpl $-MAX_ERRNO, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700156 jb 1f
157 negl %%eax
158 pushl %%eax
159 call __set_errno
160 addl $4, %%esp
161 orl $-1, %%eax
1621:
163"""
164
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700165x86_return = """\
166 ret
167END(%(func)s)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700168"""
169
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700170
Elliott Hughescd6780b2013-02-07 14:07:00 -0800171#
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400172# x86_64 assembler templates for each syscall stub
173#
174
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700175x86_64_call = """\
176 movl $%(__NR_name)s, %%eax
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400177 syscall
178 cmpq $-MAX_ERRNO, %%rax
179 jb 1f
180 negl %%eax
181 movl %%eax, %%edi
182 call __set_errno
183 orq $-1, %%rax
1841:
185 ret
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700186END(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400187"""
188
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800189
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100190def param_uses_64bits(param):
191 """Returns True iff a syscall parameter description corresponds
192 to a 64-bit type."""
193 param = param.strip()
194 # First, check that the param type begins with one of the known
195 # 64-bit types.
196 if not ( \
197 param.startswith("int64_t") or param.startswith("uint64_t") or \
198 param.startswith("loff_t") or param.startswith("off64_t") or \
199 param.startswith("long long") or param.startswith("unsigned long long") or
200 param.startswith("signed long long") ):
201 return False
202
203 # Second, check that there is no pointer type here
204 if param.find("*") >= 0:
205 return False
206
207 # Ok
208 return True
209
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700210
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100211def count_arm_param_registers(params):
212 """This function is used to count the number of register used
Elliott Hughescd6780b2013-02-07 14:07:00 -0800213 to pass parameters when invoking an ARM system call.
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100214 This is because the ARM EABI mandates that 64-bit quantities
215 must be passed in an even+odd register pair. So, for example,
216 something like:
217
218 foo(int fd, off64_t pos)
219
220 would actually need 4 registers:
221 r0 -> int
222 r1 -> unused
223 r2-r3 -> pos
224 """
225 count = 0
226 for param in params:
227 if param_uses_64bits(param):
228 if (count & 1) != 0:
229 count += 1
230 count += 2
231 else:
232 count += 1
233 return count
234
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700235
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100236def count_generic_param_registers(params):
237 count = 0
238 for param in params:
239 if param_uses_64bits(param):
240 count += 2
241 else:
242 count += 1
243 return count
244
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700245
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400246def count_generic_param_registers64(params):
247 count = 0
248 for param in params:
249 count += 1
250 return count
251
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700252
Elliott Hughescda62092013-03-22 13:50:44 -0700253# This lets us support regular system calls like __NR_write and also weird
254# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
255def make__NR_name(name):
256 if name.startswith("__"):
257 return name
258 else:
259 return "__NR_%s" % (name)
260
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700261
Elliott Hughesfff6e272013-10-24 17:03:20 -0700262def add_footer(pointer_length, stub, syscall):
263 # Add any aliases for this syscall.
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700264 aliases = syscall["aliases"]
265 for alias in aliases:
266 stub += function_alias % { "func" : syscall["func"], "alias" : alias }
Elliott Hughesfff6e272013-10-24 17:03:20 -0700267
268 # Use hidden visibility for any functions beginning with underscores.
Elliott Hughesfff6e272013-10-24 17:03:20 -0700269 if pointer_length == 64 and syscall["func"].startswith("__"):
270 stub += '.hidden _C_LABEL(' + syscall["func"] + ')\n'
271
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700272 return stub
273
274
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100275def aarch64_genstub(syscall):
276 return aarch64_call % syscall
277
278
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700279def arm_eabi_genstub(syscall):
280 num_regs = count_arm_param_registers(syscall["params"])
281 if num_regs > 4:
282 return arm_eabi_call_long % syscall
283 return arm_eabi_call_default % syscall
284
285
286def mips_genstub(syscall):
287 return mips_call % syscall
288
289
290def x86_genstub(syscall):
291 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700292
293 numparams = count_generic_param_registers(syscall["params"])
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800294 stack_bias = numparams*4 + 4
295 offset = 0
296 mov_result = ""
297 cfi_result = " .cfi_def_cfa_offset %d\n" % (numparams*4)
298 for register in x86_registers[:numparams]:
299 result += " pushl %%%s\n" % register
300 mov_result += " mov %d(%%esp), %%%s\n" % (stack_bias+offset, register)
301 cfi_result += " .cfi_rel_offset %s, %d\n" % (register, offset)
302 offset += 4
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700303
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800304 if numparams:
305 result += cfi_result
306 result += mov_result
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700307
308 result += x86_call % syscall
309
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800310 for register in reversed(x86_registers[:numparams]):
311 result += " popl %%%s\n" % register
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700312
313 result += x86_return % syscall
314 return result
315
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100316
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700317def x86_genstub_socketcall(syscall):
318 # %ebx <--- Argument 1 - The call id of the needed vectored
319 # syscall (socket, bind, recv, etc)
320 # %ecx <--- Argument 2 - Pointer to the rest of the arguments
321 # from the original function called (socket())
322
323 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700324
325 # save the regs we need
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800326 result += " pushl %ebx\n"
327 result += " pushl %ecx\n"
328 result += " .cfi_def_cfa_offset 8\n"
329 result += " .cfi_rel_offset ebx, 0\n"
330 result += " .cfi_rel_offset ecx, 4\n"
331 stack_bias = 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700332
333 # set the call id (%ebx)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800334 result += " mov $%d, %%ebx\n" % syscall["socketcall_id"]
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700335
336 # set the pointer to the rest of the args into %ecx
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800337 result += " mov %esp, %ecx\n"
338 result += " addl $%d, %%ecx\n" % (stack_bias)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700339
340 # now do the syscall code itself
341 result += x86_call % syscall
342
343 # now restore the saved regs
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800344 result += " popl %ecx\n"
345 result += " popl %ebx\n"
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700346
347 # epilog
348 result += x86_return % syscall
349 return result
350
351
352def x86_64_genstub(syscall):
353 result = syscall_stub_header % syscall
354 num_regs = count_generic_param_registers64(syscall["params"])
355 if (num_regs > 3):
356 # rcx is used as 4th argument. Kernel wants it at r10.
357 result += " movq %rcx, %r10\n"
358
359 result += x86_64_call % syscall
360 return result
361
362
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700363class State:
364 def __init__(self):
365 self.old_stubs = []
366 self.new_stubs = []
367 self.other_files = []
368 self.syscalls = []
369
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400370
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700371 def process_file(self, input):
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700372 parser = SysCallsTxtParser()
373 parser.parse_file(input)
374 self.syscalls = parser.syscalls
375 parser = None
376
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700377 for syscall in self.syscalls:
378 syscall["__NR_name"] = make__NR_name(syscall["name"])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700379
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100380 if syscall.has_key("aarch64"):
381 syscall["asm-aarch64"] = add_footer(64, aarch64_genstub(syscall), syscall)
382
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700383 if syscall.has_key("arm"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700384 syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700385
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700386 if syscall.has_key("x86"):
387 if syscall["socketcall_id"] >= 0:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700388 syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800389 else:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700390 syscall["asm-x86"] = add_footer(32, x86_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700391 elif syscall["socketcall_id"] >= 0:
Elliott Hughesd6121652013-09-25 22:43:36 -0700392 E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800393 return
Elliott Hughescd6780b2013-02-07 14:07:00 -0800394
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700395 if syscall.has_key("mips"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700396 syscall["asm-mips"] = add_footer(32, mips_genstub(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800397
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700398 if syscall.has_key("x86_64"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700399 syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700400
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700401 # Scan a Linux kernel asm/unistd.h file containing __NR_* constants
402 # and write out equivalent SYS_* constants for glibc source compatibility.
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700403 def scan_linux_unistd_h(self, fp, path):
404 pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
405 syscalls = set() # MIPS defines everything three times; work around that.
406 for line in open(path):
407 m = re.search(pattern, line)
408 if m:
409 syscalls.add(m.group(1))
410 for syscall in sorted(syscalls):
Elliott Hughescda62092013-03-22 13:50:44 -0700411 fp.write("#define SYS_%s %s\n" % (syscall, make__NR_name(syscall)))
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700412
413
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700414 def gen_glibc_syscalls_h(self):
Elliott Hughescda62092013-03-22 13:50:44 -0700415 # TODO: generate a separate file for each architecture, like glibc's bits/syscall.h.
Elliott Hughes9724ce32013-03-21 19:43:54 -0700416 glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700417 D("generating " + glibc_syscalls_h_path)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700418 glibc_fp = create_file(glibc_syscalls_h_path)
Elliott Hughes103ccde2013-10-16 14:27:59 -0700419 glibc_fp.write("/* %s */\n" % warning)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700420 glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
421 glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
422
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100423 glibc_fp.write("#if defined(__aarch64__)\n")
424 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-generic/unistd.h")
425 glibc_fp.write("#elif defined(__arm__)\n")
Elliott Hughes887e1142014-01-02 12:05:50 -0800426 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-arm/asm/unistd.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700427 glibc_fp.write("#elif defined(__mips__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800428 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-mips/asm/unistd.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700429 glibc_fp.write("#elif defined(__i386__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800430 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-x86/asm/unistd_32.h")
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400431 glibc_fp.write("#elif defined(__x86_64__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800432 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-x86/asm/unistd_64.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700433 glibc_fp.write("#endif\n")
434
435 glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
436 glibc_fp.close()
437 self.other_files.append(glibc_syscalls_h_path)
438
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700439
Elliott Hughesd6121652013-09-25 22:43:36 -0700440 # Write the contents of syscalls.mk.
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800441 def gen_arch_syscalls_mk(self, arch):
442 path = "arch-%s/syscalls.mk" % arch
Elliott Hughesd6121652013-09-25 22:43:36 -0700443 D("generating " + path)
444 fp = create_file(path)
Elliott Hughes103ccde2013-10-16 14:27:59 -0700445 fp.write("# %s\n" % warning)
Elliott Hughesd6121652013-09-25 22:43:36 -0700446 fp.write("syscall_src :=\n")
Elliott Hughes103ccde2013-10-16 14:27:59 -0700447 for syscall in sorted(self.syscalls, key=lambda syscall: syscall["func"]):
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700448 if syscall.has_key("asm-%s" % arch):
449 fp.write("syscall_src += arch-%s/syscalls/%s.S\n" % (arch, syscall["func"]))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700450 fp.close()
Elliott Hughesd6121652013-09-25 22:43:36 -0700451 self.other_files.append(path)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700452
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800453
Elliott Hughesd6121652013-09-25 22:43:36 -0700454 # Write each syscall stub.
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700455 def gen_syscall_stubs(self):
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700456 for syscall in self.syscalls:
Elliott Hughesd6121652013-09-25 22:43:36 -0700457 for arch in all_arches:
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700458 if syscall.has_key("asm-%s" % arch):
459 filename = "arch-%s/syscalls/%s.S" % (arch, syscall["func"])
Elliott Hughesd6121652013-09-25 22:43:36 -0700460 D2(">>> generating " + filename)
461 fp = create_file(filename)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700462 fp.write(syscall["asm-%s" % arch])
Elliott Hughesd6121652013-09-25 22:43:36 -0700463 fp.close()
464 self.new_stubs.append(filename)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700465
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700466
Elliott Hughesd6121652013-09-25 22:43:36 -0700467 def regenerate(self):
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400468 D("scanning for existing architecture-specific stub files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700469
Elliott Hughes18bc9752013-06-17 10:26:10 -0700470 bionic_libc_root_len = len(bionic_libc_root)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700471
Elliott Hughesd6121652013-09-25 22:43:36 -0700472 for arch in all_arches:
Elliott Hughes18bc9752013-06-17 10:26:10 -0700473 arch_path = bionic_libc_root + "arch-" + arch
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400474 D("scanning " + arch_path)
475 files = glob.glob(arch_path + "/syscalls/*.S")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700476 for f in files:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400477 self.old_stubs.append(f[bionic_libc_root_len:])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700478
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400479 D("found %d stub files" % len(self.old_stubs))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700480
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400481 if not os.path.exists(bionic_temp):
482 D("creating %s..." % bionic_temp)
483 make_dir(bionic_temp)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700484
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400485 D("re-generating stubs and support files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700486
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700487 self.gen_glibc_syscalls_h()
Elliott Hughesd6121652013-09-25 22:43:36 -0700488 for arch in all_arches:
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800489 self.gen_arch_syscalls_mk(arch)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700490 self.gen_syscall_stubs()
491
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400492 D("comparing files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700493 adds = []
494 edits = []
495
496 for stub in self.new_stubs + self.other_files:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400497 if not os.path.exists(bionic_libc_root + stub):
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200498 # new file, git add it
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400499 D("new file: " + stub)
500 adds.append(bionic_libc_root + stub)
501 shutil.copyfile(bionic_temp + stub, bionic_libc_root + stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700502
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400503 elif not filecmp.cmp(bionic_temp + stub, bionic_libc_root + stub):
504 D("changed file: " + stub)
505 edits.append(stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700506
507 deletes = []
508 for stub in self.old_stubs:
509 if not stub in self.new_stubs:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400510 D("deleted file: " + stub)
511 deletes.append(bionic_libc_root + stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700512
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400513 if not DRY_RUN:
514 if adds:
515 commands.getoutput("git add " + " ".join(adds))
516 if deletes:
517 commands.getoutput("git rm " + " ".join(deletes))
518 if edits:
519 for file in edits:
520 shutil.copyfile(bionic_temp + file, bionic_libc_root + file)
521 commands.getoutput("git add " + " ".join((bionic_libc_root + file) for file in edits))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700522
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400523 commands.getoutput("git add %s%s" % (bionic_libc_root,"SYSCALLS.TXT"))
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200524
525 if (not adds) and (not deletes) and (not edits):
526 D("no changes detected!")
527 else:
528 D("ready to go!!")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700529
530D_setlevel(1)
531
532state = State()
Elliott Hughes18bc9752013-06-17 10:26:10 -0700533state.process_file(bionic_libc_root+"SYSCALLS.TXT")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700534state.regenerate()