blob: 4619ec690cbdb6727aa460ab6ab74e423d7f1563 [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
Christopher Ferris01bd32e2014-08-05 12:19:27 -07007import atexit
Elliott Hughes103ccde2013-10-16 14:27:59 -07008import commands
9import filecmp
10import glob
11import os.path
12import re
13import shutil
14import stat
15import sys
Christopher Ferris01bd32e2014-08-05 12:19:27 -070016import tempfile
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070017
18from bionic_utils import *
19
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070020# temp directory where we store all intermediate files
Christopher Ferris01bd32e2014-08-05 12:19:27 -070021bionic_temp = tempfile.mkdtemp(prefix="bionic_gensyscalls");
22# Make sure the directory is deleted when the script exits.
23atexit.register(shutil.rmtree, bionic_temp)
24
25bionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070026
Elliott Hughes103ccde2013-10-16 14:27:59 -070027warning = "Generated by gensyscalls.py. Do not edit."
28
Pavel Chupinf12a18b2012-12-12 13:11:48 +040029DRY_RUN = False
30
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
Elliott Hughes0437f3f2013-10-07 23:53:13 -070039
Pavel Chupinf12a18b2012-12-12 13:11:48 +040040def create_file(relpath):
Christopher Ferris01bd32e2014-08-05 12:19:27 -070041 full_path = os.path.join(bionic_temp, relpath)
42 dir = os.path.dirname(full_path)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070043 make_dir(dir)
Christopher Ferris01bd32e2014-08-05 12:19:27 -070044 return open(full_path, "w")
Pavel Chupinf12a18b2012-12-12 13:11:48 +040045
46
Elliott Hughes103ccde2013-10-16 14:27:59 -070047syscall_stub_header = "/* " + warning + " */\n" + \
48"""
Elliott Hughesed744842013-11-07 10:31:05 -080049#include <private/bionic_asm.h>
Pavel Chupinf12a18b2012-12-12 13:11:48 +040050
Dan Albertbc9f9f22014-08-08 15:19:20 -070051 .hidden __set_errno
52
Elliott Hughes0437f3f2013-10-07 23:53:13 -070053ENTRY(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +040054"""
55
Elliott Hughes0437f3f2013-10-07 23:53:13 -070056
H.J. Lu6fe4e872013-10-04 10:03:17 -070057function_alias = """
Elliott Hughes986f9062014-02-18 16:42:36 -080058 .globl %(alias)s
59 .equ %(alias)s, %(func)s
H.J. Lu6fe4e872013-10-04 10:03:17 -070060"""
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070061
Elliott Hughes0437f3f2013-10-07 23:53:13 -070062
63#
64# ARM assembler templates for each syscall stub
65#
66
67arm_eabi_call_default = syscall_stub_header + """\
68 mov ip, r7
69 ldr r7, =%(__NR_name)s
70 swi #0
71 mov r7, ip
72 cmn r0, #(MAX_ERRNO + 1)
73 bxls lr
74 neg r0, r0
75 b __set_errno
76END(%(func)s)
77"""
78
79arm_eabi_call_long = syscall_stub_header + """\
80 mov ip, sp
Elliott Hughes0437f3f2013-10-07 23:53:13 -070081 stmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080082 .cfi_def_cfa_offset 16
83 .cfi_rel_offset r4, 0
84 .cfi_rel_offset r5, 4
85 .cfi_rel_offset r6, 8
86 .cfi_rel_offset r7, 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -070087 ldmfd ip, {r4, r5, r6}
88 ldr r7, =%(__NR_name)s
89 swi #0
90 ldmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080091 .cfi_def_cfa_offset 0
Elliott Hughes0437f3f2013-10-07 23:53:13 -070092 cmn r0, #(MAX_ERRNO + 1)
93 bxls lr
94 neg r0, r0
95 b __set_errno
96END(%(func)s)
97"""
98
99
100#
Colin Crossd1973ca2014-01-21 19:50:58 -0800101# Arm64 assembler templates for each syscall stub
102#
103
104arm64_call = syscall_stub_header + """\
Colin Crossd1973ca2014-01-21 19:50:58 -0800105 mov x8, %(__NR_name)s
106 svc #0
107
Colin Crossd1973ca2014-01-21 19:50:58 -0800108 cmn x0, #(MAX_ERRNO + 1)
109 cneg x0, x0, hi
110 b.hi __set_errno
111
112 ret
113END(%(func)s)
114"""
115
116
117#
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700118# MIPS assembler templates for each syscall stub
119#
120
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800121mips_call = syscall_stub_header + """\
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700122 .set noreorder
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800123 .cpload t9
124 li v0, %(__NR_name)s
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700125 syscall
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800126 bnez a3, 1f
127 move a0, v0
128 j ra
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700129 nop
1301:
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800131 la t9,__set_errno
132 j t9
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700133 nop
134 .set reorder
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800135END(%(func)s)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700136"""
137
138
Elliott Hughescd6780b2013-02-07 14:07:00 -0800139#
Chris Dearman50432122014-02-05 16:59:23 -0800140# MIPS64 assembler templates for each syscall stub
141#
142
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800143mips64_call = syscall_stub_header + """\
Chris Dearman50432122014-02-05 16:59:23 -0800144 .set push
145 .set noreorder
146 li v0, %(__NR_name)s
147 syscall
148 bnez a3, 1f
149 move a0, v0
150 j ra
151 nop
1521:
153 move t0, ra
154 bal 2f
155 nop
1562:
157 .cpsetup ra, t1, 2b
158 LA t9,__set_errno
159 .cpreturn
160 j t9
161 move ra, t0
162 .set pop
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800163END(%(func)s)
Chris Dearman50432122014-02-05 16:59:23 -0800164"""
165
166
167#
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700168# x86 assembler templates for each syscall stub
169#
170
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800171x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700172
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700173x86_call = """\
174 movl $%(__NR_name)s, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700175 int $0x80
Elliott Hughes9aceab52013-03-12 14:57:30 -0700176 cmpl $-MAX_ERRNO, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700177 jb 1f
178 negl %%eax
179 pushl %%eax
Dan Albert3726f9c2014-08-08 15:15:29 -0700180 call __set_errno
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700181 addl $4, %%esp
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001821:
183"""
184
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700185x86_return = """\
186 ret
187END(%(func)s)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700188"""
189
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700190
Elliott Hughescd6780b2013-02-07 14:07:00 -0800191#
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400192# x86_64 assembler templates for each syscall stub
193#
194
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700195x86_64_call = """\
196 movl $%(__NR_name)s, %%eax
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400197 syscall
198 cmpq $-MAX_ERRNO, %%rax
199 jb 1f
200 negl %%eax
201 movl %%eax, %%edi
Dan Albert3726f9c2014-08-08 15:15:29 -0700202 call __set_errno
Pavel Chupinf12a18b2012-12-12 13:11:48 +04002031:
204 ret
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700205END(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400206"""
207
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800208
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100209def param_uses_64bits(param):
210 """Returns True iff a syscall parameter description corresponds
211 to a 64-bit type."""
212 param = param.strip()
213 # First, check that the param type begins with one of the known
214 # 64-bit types.
215 if not ( \
216 param.startswith("int64_t") or param.startswith("uint64_t") or \
217 param.startswith("loff_t") or param.startswith("off64_t") or \
218 param.startswith("long long") or param.startswith("unsigned long long") or
219 param.startswith("signed long long") ):
220 return False
221
222 # Second, check that there is no pointer type here
223 if param.find("*") >= 0:
224 return False
225
226 # Ok
227 return True
228
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700229
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100230def count_arm_param_registers(params):
231 """This function is used to count the number of register used
Elliott Hughescd6780b2013-02-07 14:07:00 -0800232 to pass parameters when invoking an ARM system call.
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100233 This is because the ARM EABI mandates that 64-bit quantities
234 must be passed in an even+odd register pair. So, for example,
235 something like:
236
237 foo(int fd, off64_t pos)
238
239 would actually need 4 registers:
240 r0 -> int
241 r1 -> unused
242 r2-r3 -> pos
243 """
244 count = 0
245 for param in params:
246 if param_uses_64bits(param):
247 if (count & 1) != 0:
248 count += 1
249 count += 2
250 else:
251 count += 1
252 return count
253
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700254
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100255def count_generic_param_registers(params):
256 count = 0
257 for param in params:
258 if param_uses_64bits(param):
259 count += 2
260 else:
261 count += 1
262 return count
263
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700264
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400265def count_generic_param_registers64(params):
266 count = 0
267 for param in params:
268 count += 1
269 return count
270
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700271
Elliott Hughescda62092013-03-22 13:50:44 -0700272# This lets us support regular system calls like __NR_write and also weird
273# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
274def make__NR_name(name):
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700275 if name.startswith("__ARM_NR_"):
Elliott Hughescda62092013-03-22 13:50:44 -0700276 return name
277 else:
278 return "__NR_%s" % (name)
279
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700280
Elliott Hughesfff6e272013-10-24 17:03:20 -0700281def add_footer(pointer_length, stub, syscall):
282 # Add any aliases for this syscall.
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700283 aliases = syscall["aliases"]
284 for alias in aliases:
285 stub += function_alias % { "func" : syscall["func"], "alias" : alias }
Elliott Hughesfff6e272013-10-24 17:03:20 -0700286
287 # Use hidden visibility for any functions beginning with underscores.
Elliott Hughesfff6e272013-10-24 17:03:20 -0700288 if pointer_length == 64 and syscall["func"].startswith("__"):
Elliott Hughesd465eb42014-02-19 18:59:19 -0800289 stub += '.hidden ' + syscall["func"] + '\n'
Elliott Hughesfff6e272013-10-24 17:03:20 -0700290
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700291 return stub
292
293
294def arm_eabi_genstub(syscall):
295 num_regs = count_arm_param_registers(syscall["params"])
296 if num_regs > 4:
297 return arm_eabi_call_long % syscall
298 return arm_eabi_call_default % syscall
299
300
Colin Crossd1973ca2014-01-21 19:50:58 -0800301def arm64_genstub(syscall):
302 return arm64_call % syscall
303
304
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700305def mips_genstub(syscall):
306 return mips_call % syscall
307
308
Chris Dearman50432122014-02-05 16:59:23 -0800309def mips64_genstub(syscall):
310 return mips64_call % syscall
311
312
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700313def x86_genstub(syscall):
314 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700315
316 numparams = count_generic_param_registers(syscall["params"])
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800317 stack_bias = numparams*4 + 4
318 offset = 0
319 mov_result = ""
Christopher Ferris15b91e92014-05-29 18:17:09 -0700320 first_push = True
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800321 for register in x86_registers[:numparams]:
322 result += " pushl %%%s\n" % register
Christopher Ferris15b91e92014-05-29 18:17:09 -0700323 if first_push:
324 result += " .cfi_def_cfa_offset 8\n"
325 result += " .cfi_rel_offset %s, 0\n" % register
326 first_push = False
327 else:
328 result += " .cfi_adjust_cfa_offset 4\n"
329 result += " .cfi_rel_offset %s, 0\n" % register
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800330 mov_result += " mov %d(%%esp), %%%s\n" % (stack_bias+offset, register)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800331 offset += 4
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700332
Christopher Ferris15b91e92014-05-29 18:17:09 -0700333 result += mov_result
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700334 result += x86_call % syscall
335
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800336 for register in reversed(x86_registers[:numparams]):
337 result += " popl %%%s\n" % register
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700338
339 result += x86_return % syscall
340 return result
341
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100342
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700343def x86_genstub_socketcall(syscall):
344 # %ebx <--- Argument 1 - The call id of the needed vectored
345 # syscall (socket, bind, recv, etc)
346 # %ecx <--- Argument 2 - Pointer to the rest of the arguments
347 # from the original function called (socket())
348
349 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700350
351 # save the regs we need
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800352 result += " pushl %ebx\n"
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800353 result += " .cfi_def_cfa_offset 8\n"
354 result += " .cfi_rel_offset ebx, 0\n"
Christopher Ferris15b91e92014-05-29 18:17:09 -0700355 result += " pushl %ecx\n"
356 result += " .cfi_adjust_cfa_offset 4\n"
357 result += " .cfi_rel_offset ecx, 0\n"
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800358 stack_bias = 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700359
360 # set the call id (%ebx)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800361 result += " mov $%d, %%ebx\n" % syscall["socketcall_id"]
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700362
363 # set the pointer to the rest of the args into %ecx
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800364 result += " mov %esp, %ecx\n"
365 result += " addl $%d, %%ecx\n" % (stack_bias)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700366
367 # now do the syscall code itself
368 result += x86_call % syscall
369
370 # now restore the saved regs
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800371 result += " popl %ecx\n"
372 result += " popl %ebx\n"
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700373
374 # epilog
375 result += x86_return % syscall
376 return result
377
378
379def x86_64_genstub(syscall):
380 result = syscall_stub_header % syscall
381 num_regs = count_generic_param_registers64(syscall["params"])
382 if (num_regs > 3):
383 # rcx is used as 4th argument. Kernel wants it at r10.
384 result += " movq %rcx, %r10\n"
385
386 result += x86_64_call % syscall
387 return result
388
389
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700390class State:
391 def __init__(self):
392 self.old_stubs = []
393 self.new_stubs = []
394 self.other_files = []
395 self.syscalls = []
396
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400397
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700398 def process_file(self, input):
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700399 parser = SysCallsTxtParser()
400 parser.parse_file(input)
401 self.syscalls = parser.syscalls
402 parser = None
403
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700404 for syscall in self.syscalls:
405 syscall["__NR_name"] = make__NR_name(syscall["name"])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700406
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700407 if syscall.has_key("arm"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700408 syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700409
Colin Crossd1973ca2014-01-21 19:50:58 -0800410 if syscall.has_key("arm64"):
411 syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall)
412
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700413 if syscall.has_key("x86"):
414 if syscall["socketcall_id"] >= 0:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700415 syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800416 else:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700417 syscall["asm-x86"] = add_footer(32, x86_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700418 elif syscall["socketcall_id"] >= 0:
Elliott Hughesd6121652013-09-25 22:43:36 -0700419 E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800420 return
Elliott Hughescd6780b2013-02-07 14:07:00 -0800421
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700422 if syscall.has_key("mips"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700423 syscall["asm-mips"] = add_footer(32, mips_genstub(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800424
Chris Dearman50432122014-02-05 16:59:23 -0800425 if syscall.has_key("mips64"):
426 syscall["asm-mips64"] = add_footer(64, mips64_genstub(syscall), syscall)
427
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700428 if syscall.has_key("x86_64"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700429 syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700430
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700431 # Scan a Linux kernel asm/unistd.h file containing __NR_* constants
432 # and write out equivalent SYS_* constants for glibc source compatibility.
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700433 def scan_linux_unistd_h(self, fp, path):
434 pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
435 syscalls = set() # MIPS defines everything three times; work around that.
436 for line in open(path):
437 m = re.search(pattern, line)
438 if m:
439 syscalls.add(m.group(1))
440 for syscall in sorted(syscalls):
Elliott Hughescda62092013-03-22 13:50:44 -0700441 fp.write("#define SYS_%s %s\n" % (syscall, make__NR_name(syscall)))
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700442
443
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700444 def gen_glibc_syscalls_h(self):
Elliott Hughescda62092013-03-22 13:50:44 -0700445 # TODO: generate a separate file for each architecture, like glibc's bits/syscall.h.
Elliott Hughes9724ce32013-03-21 19:43:54 -0700446 glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700447 D("generating " + glibc_syscalls_h_path)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700448 glibc_fp = create_file(glibc_syscalls_h_path)
Elliott Hughes103ccde2013-10-16 14:27:59 -0700449 glibc_fp.write("/* %s */\n" % warning)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700450 glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
451 glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
452
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100453 glibc_fp.write("#if defined(__aarch64__)\n")
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700454 self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-generic/unistd.h"))
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100455 glibc_fp.write("#elif defined(__arm__)\n")
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700456 self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-arm/asm/unistd.h"))
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700457 glibc_fp.write("#elif defined(__mips__)\n")
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700458 self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-mips/asm/unistd.h"))
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700459 glibc_fp.write("#elif defined(__i386__)\n")
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700460 self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-x86/asm/unistd_32.h"))
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400461 glibc_fp.write("#elif defined(__x86_64__)\n")
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700462 self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-x86/asm/unistd_64.h"))
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700463 glibc_fp.write("#endif\n")
464
465 glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
466 glibc_fp.close()
467 self.other_files.append(glibc_syscalls_h_path)
468
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700469
Elliott Hughesd6121652013-09-25 22:43:36 -0700470 # Write each syscall stub.
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700471 def gen_syscall_stubs(self):
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700472 for syscall in self.syscalls:
Elliott Hughesd6121652013-09-25 22:43:36 -0700473 for arch in all_arches:
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700474 if syscall.has_key("asm-%s" % arch):
475 filename = "arch-%s/syscalls/%s.S" % (arch, syscall["func"])
Elliott Hughesd6121652013-09-25 22:43:36 -0700476 D2(">>> generating " + filename)
477 fp = create_file(filename)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700478 fp.write(syscall["asm-%s" % arch])
Elliott Hughesd6121652013-09-25 22:43:36 -0700479 fp.close()
480 self.new_stubs.append(filename)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700481
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700482
Elliott Hughesd6121652013-09-25 22:43:36 -0700483 def regenerate(self):
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400484 D("scanning for existing architecture-specific stub files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700485
Elliott Hughesd6121652013-09-25 22:43:36 -0700486 for arch in all_arches:
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700487 arch_dir = "arch-" + arch
488 D("scanning " + os.path.join(bionic_libc_root, arch_dir))
489 rel_path = os.path.join(arch_dir, "syscalls")
490 for file in os.listdir(os.path.join(bionic_libc_root, rel_path)):
491 if file.endswith(".S"):
492 self.old_stubs.append(os.path.join(rel_path, file))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700493
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400494 D("found %d stub files" % len(self.old_stubs))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700495
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400496 if not os.path.exists(bionic_temp):
497 D("creating %s..." % bionic_temp)
498 make_dir(bionic_temp)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700499
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400500 D("re-generating stubs and support files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700501
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700502 self.gen_glibc_syscalls_h()
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700503 self.gen_syscall_stubs()
504
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400505 D("comparing files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700506 adds = []
507 edits = []
508
509 for stub in self.new_stubs + self.other_files:
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700510 tmp_file = os.path.join(bionic_temp, stub)
511 libc_file = os.path.join(bionic_libc_root, stub)
512 if not os.path.exists(libc_file):
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200513 # new file, git add it
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400514 D("new file: " + stub)
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700515 adds.append(libc_file)
516 shutil.copyfile(tmp_file, libc_file)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700517
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700518 elif not filecmp.cmp(tmp_file, libc_file):
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400519 D("changed file: " + stub)
520 edits.append(stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700521
522 deletes = []
523 for stub in self.old_stubs:
524 if not stub in self.new_stubs:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400525 D("deleted file: " + stub)
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700526 deletes.append(os.path.join(bionic_libc_root, stub))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700527
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400528 if not DRY_RUN:
529 if adds:
530 commands.getoutput("git add " + " ".join(adds))
531 if deletes:
532 commands.getoutput("git rm " + " ".join(deletes))
533 if edits:
534 for file in edits:
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700535 shutil.copyfile(os.path.join(bionic_temp, file),
536 os.path.join(bionic_libc_root, file))
537 commands.getoutput("git add " + " ".join((os.path.join(bionic_libc_root, file)) for file in edits))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700538
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700539 commands.getoutput("git add %s" % (os.path.join(bionic_libc_root, "SYSCALLS.TXT")))
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200540
541 if (not adds) and (not deletes) and (not edits):
542 D("no changes detected!")
543 else:
544 D("ready to go!!")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700545
546D_setlevel(1)
547
548state = State()
Christopher Ferris01bd32e2014-08-05 12:19:27 -0700549state.process_file(os.path.join(bionic_libc_root, "SYSCALLS.TXT"))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700550state.regenerate()