blob: 5e4ddc59ee5553bf1b0e28a8a7c35d80b561b827 [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 = """
Elliott Hughes986f9062014-02-18 16:42:36 -080051 .globl %(alias)s
52 .equ %(alias)s, %(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#
57# ARM assembler templates for each syscall stub
58#
59
60arm_eabi_call_default = syscall_stub_header + """\
61 mov ip, r7
62 ldr r7, =%(__NR_name)s
63 swi #0
64 mov r7, ip
65 cmn r0, #(MAX_ERRNO + 1)
66 bxls lr
67 neg r0, r0
68 b __set_errno
69END(%(func)s)
70"""
71
72arm_eabi_call_long = syscall_stub_header + """\
73 mov ip, sp
Elliott Hughes0437f3f2013-10-07 23:53:13 -070074 stmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080075 .cfi_def_cfa_offset 16
76 .cfi_rel_offset r4, 0
77 .cfi_rel_offset r5, 4
78 .cfi_rel_offset r6, 8
79 .cfi_rel_offset r7, 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -070080 ldmfd ip, {r4, r5, r6}
81 ldr r7, =%(__NR_name)s
82 swi #0
83 ldmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080084 .cfi_def_cfa_offset 0
Elliott Hughes0437f3f2013-10-07 23:53:13 -070085 cmn r0, #(MAX_ERRNO + 1)
86 bxls lr
87 neg r0, r0
88 b __set_errno
89END(%(func)s)
90"""
91
92
93#
Colin Crossd1973ca2014-01-21 19:50:58 -080094# Arm64 assembler templates for each syscall stub
95#
96
97arm64_call = syscall_stub_header + """\
98 stp x29, x30, [sp, #-16]!
Christopher Ferrisdf22a122014-05-21 16:00:13 -070099 .cfi_def_cfa_offset 16
100 .cfi_rel_offset x29, 0
101 .cfi_rel_offset x30, 8
Colin Crossd1973ca2014-01-21 19:50:58 -0800102 mov x29, sp
Colin Crossd1973ca2014-01-21 19:50:58 -0800103
104 mov x8, %(__NR_name)s
105 svc #0
106
Colin Crossd1973ca2014-01-21 19:50:58 -0800107 ldp x29, x30, [sp], #16
Christopher Ferrisdf22a122014-05-21 16:00:13 -0700108 .cfi_def_cfa_offset 0
109 .cfi_restore x29
110 .cfi_restore x30
Colin Crossd1973ca2014-01-21 19:50:58 -0800111
112 cmn x0, #(MAX_ERRNO + 1)
113 cneg x0, x0, hi
114 b.hi __set_errno
115
116 ret
117END(%(func)s)
118"""
119
120
121#
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700122# MIPS assembler templates for each syscall stub
123#
124
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800125mips_call = syscall_stub_header + """\
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700126 .set noreorder
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800127 .cpload t9
128 li v0, %(__NR_name)s
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700129 syscall
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800130 bnez a3, 1f
131 move a0, v0
132 j ra
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700133 nop
1341:
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800135 la t9,__set_errno
136 j t9
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700137 nop
138 .set reorder
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800139END(%(func)s)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700140"""
141
142
Elliott Hughescd6780b2013-02-07 14:07:00 -0800143#
Chris Dearman50432122014-02-05 16:59:23 -0800144# MIPS64 assembler templates for each syscall stub
145#
146
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800147mips64_call = syscall_stub_header + """\
Chris Dearman50432122014-02-05 16:59:23 -0800148 .set push
149 .set noreorder
150 li v0, %(__NR_name)s
151 syscall
152 bnez a3, 1f
153 move a0, v0
154 j ra
155 nop
1561:
157 move t0, ra
158 bal 2f
159 nop
1602:
161 .cpsetup ra, t1, 2b
162 LA t9,__set_errno
163 .cpreturn
164 j t9
165 move ra, t0
166 .set pop
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800167END(%(func)s)
Chris Dearman50432122014-02-05 16:59:23 -0800168"""
169
170
171#
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700172# x86 assembler templates for each syscall stub
173#
174
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800175x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700176
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700177x86_call = """\
178 movl $%(__NR_name)s, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700179 int $0x80
Elliott Hughes9aceab52013-03-12 14:57:30 -0700180 cmpl $-MAX_ERRNO, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700181 jb 1f
182 negl %%eax
183 pushl %%eax
184 call __set_errno
185 addl $4, %%esp
186 orl $-1, %%eax
1871:
188"""
189
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700190x86_return = """\
191 ret
192END(%(func)s)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700193"""
194
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700195
Elliott Hughescd6780b2013-02-07 14:07:00 -0800196#
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400197# x86_64 assembler templates for each syscall stub
198#
199
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700200x86_64_call = """\
201 movl $%(__NR_name)s, %%eax
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400202 syscall
203 cmpq $-MAX_ERRNO, %%rax
204 jb 1f
205 negl %%eax
206 movl %%eax, %%edi
207 call __set_errno
208 orq $-1, %%rax
2091:
210 ret
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700211END(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400212"""
213
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800214
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100215def param_uses_64bits(param):
216 """Returns True iff a syscall parameter description corresponds
217 to a 64-bit type."""
218 param = param.strip()
219 # First, check that the param type begins with one of the known
220 # 64-bit types.
221 if not ( \
222 param.startswith("int64_t") or param.startswith("uint64_t") or \
223 param.startswith("loff_t") or param.startswith("off64_t") or \
224 param.startswith("long long") or param.startswith("unsigned long long") or
225 param.startswith("signed long long") ):
226 return False
227
228 # Second, check that there is no pointer type here
229 if param.find("*") >= 0:
230 return False
231
232 # Ok
233 return True
234
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700235
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100236def count_arm_param_registers(params):
237 """This function is used to count the number of register used
Elliott Hughescd6780b2013-02-07 14:07:00 -0800238 to pass parameters when invoking an ARM system call.
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100239 This is because the ARM EABI mandates that 64-bit quantities
240 must be passed in an even+odd register pair. So, for example,
241 something like:
242
243 foo(int fd, off64_t pos)
244
245 would actually need 4 registers:
246 r0 -> int
247 r1 -> unused
248 r2-r3 -> pos
249 """
250 count = 0
251 for param in params:
252 if param_uses_64bits(param):
253 if (count & 1) != 0:
254 count += 1
255 count += 2
256 else:
257 count += 1
258 return count
259
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700260
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100261def count_generic_param_registers(params):
262 count = 0
263 for param in params:
264 if param_uses_64bits(param):
265 count += 2
266 else:
267 count += 1
268 return count
269
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700270
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400271def count_generic_param_registers64(params):
272 count = 0
273 for param in params:
274 count += 1
275 return count
276
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700277
Elliott Hughescda62092013-03-22 13:50:44 -0700278# This lets us support regular system calls like __NR_write and also weird
279# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
280def make__NR_name(name):
281 if name.startswith("__"):
282 return name
283 else:
284 return "__NR_%s" % (name)
285
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700286
Elliott Hughesfff6e272013-10-24 17:03:20 -0700287def add_footer(pointer_length, stub, syscall):
288 # Add any aliases for this syscall.
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700289 aliases = syscall["aliases"]
290 for alias in aliases:
291 stub += function_alias % { "func" : syscall["func"], "alias" : alias }
Elliott Hughesfff6e272013-10-24 17:03:20 -0700292
293 # Use hidden visibility for any functions beginning with underscores.
Elliott Hughesfff6e272013-10-24 17:03:20 -0700294 if pointer_length == 64 and syscall["func"].startswith("__"):
Elliott Hughesd465eb42014-02-19 18:59:19 -0800295 stub += '.hidden ' + syscall["func"] + '\n'
Elliott Hughesfff6e272013-10-24 17:03:20 -0700296
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700297 return stub
298
299
300def arm_eabi_genstub(syscall):
301 num_regs = count_arm_param_registers(syscall["params"])
302 if num_regs > 4:
303 return arm_eabi_call_long % syscall
304 return arm_eabi_call_default % syscall
305
306
Colin Crossd1973ca2014-01-21 19:50:58 -0800307def arm64_genstub(syscall):
308 return arm64_call % syscall
309
310
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700311def mips_genstub(syscall):
312 return mips_call % syscall
313
314
Chris Dearman50432122014-02-05 16:59:23 -0800315def mips64_genstub(syscall):
316 return mips64_call % syscall
317
318
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700319def x86_genstub(syscall):
320 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700321
322 numparams = count_generic_param_registers(syscall["params"])
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800323 stack_bias = numparams*4 + 4
324 offset = 0
325 mov_result = ""
Christopher Ferris15b91e92014-05-29 18:17:09 -0700326 first_push = True
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800327 for register in x86_registers[:numparams]:
328 result += " pushl %%%s\n" % register
Christopher Ferris15b91e92014-05-29 18:17:09 -0700329 if first_push:
330 result += " .cfi_def_cfa_offset 8\n"
331 result += " .cfi_rel_offset %s, 0\n" % register
332 first_push = False
333 else:
334 result += " .cfi_adjust_cfa_offset 4\n"
335 result += " .cfi_rel_offset %s, 0\n" % register
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800336 mov_result += " mov %d(%%esp), %%%s\n" % (stack_bias+offset, register)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800337 offset += 4
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700338
Christopher Ferris15b91e92014-05-29 18:17:09 -0700339 result += mov_result
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700340 result += x86_call % syscall
341
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800342 for register in reversed(x86_registers[:numparams]):
343 result += " popl %%%s\n" % register
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700344
345 result += x86_return % syscall
346 return result
347
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100348
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700349def x86_genstub_socketcall(syscall):
350 # %ebx <--- Argument 1 - The call id of the needed vectored
351 # syscall (socket, bind, recv, etc)
352 # %ecx <--- Argument 2 - Pointer to the rest of the arguments
353 # from the original function called (socket())
354
355 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700356
357 # save the regs we need
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800358 result += " pushl %ebx\n"
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800359 result += " .cfi_def_cfa_offset 8\n"
360 result += " .cfi_rel_offset ebx, 0\n"
Christopher Ferris15b91e92014-05-29 18:17:09 -0700361 result += " pushl %ecx\n"
362 result += " .cfi_adjust_cfa_offset 4\n"
363 result += " .cfi_rel_offset ecx, 0\n"
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800364 stack_bias = 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700365
366 # set the call id (%ebx)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800367 result += " mov $%d, %%ebx\n" % syscall["socketcall_id"]
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700368
369 # set the pointer to the rest of the args into %ecx
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800370 result += " mov %esp, %ecx\n"
371 result += " addl $%d, %%ecx\n" % (stack_bias)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700372
373 # now do the syscall code itself
374 result += x86_call % syscall
375
376 # now restore the saved regs
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800377 result += " popl %ecx\n"
378 result += " popl %ebx\n"
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700379
380 # epilog
381 result += x86_return % syscall
382 return result
383
384
385def x86_64_genstub(syscall):
386 result = syscall_stub_header % syscall
387 num_regs = count_generic_param_registers64(syscall["params"])
388 if (num_regs > 3):
389 # rcx is used as 4th argument. Kernel wants it at r10.
390 result += " movq %rcx, %r10\n"
391
392 result += x86_64_call % syscall
393 return result
394
395
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700396class State:
397 def __init__(self):
398 self.old_stubs = []
399 self.new_stubs = []
400 self.other_files = []
401 self.syscalls = []
402
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400403
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700404 def process_file(self, input):
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700405 parser = SysCallsTxtParser()
406 parser.parse_file(input)
407 self.syscalls = parser.syscalls
408 parser = None
409
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700410 for syscall in self.syscalls:
411 syscall["__NR_name"] = make__NR_name(syscall["name"])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700412
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700413 if syscall.has_key("arm"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700414 syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700415
Colin Crossd1973ca2014-01-21 19:50:58 -0800416 if syscall.has_key("arm64"):
417 syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall)
418
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700419 if syscall.has_key("x86"):
420 if syscall["socketcall_id"] >= 0:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700421 syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800422 else:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700423 syscall["asm-x86"] = add_footer(32, x86_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700424 elif syscall["socketcall_id"] >= 0:
Elliott Hughesd6121652013-09-25 22:43:36 -0700425 E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800426 return
Elliott Hughescd6780b2013-02-07 14:07:00 -0800427
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700428 if syscall.has_key("mips"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700429 syscall["asm-mips"] = add_footer(32, mips_genstub(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800430
Chris Dearman50432122014-02-05 16:59:23 -0800431 if syscall.has_key("mips64"):
432 syscall["asm-mips64"] = add_footer(64, mips64_genstub(syscall), syscall)
433
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700434 if syscall.has_key("x86_64"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700435 syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700436
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700437 # Scan a Linux kernel asm/unistd.h file containing __NR_* constants
438 # and write out equivalent SYS_* constants for glibc source compatibility.
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700439 def scan_linux_unistd_h(self, fp, path):
440 pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
441 syscalls = set() # MIPS defines everything three times; work around that.
442 for line in open(path):
443 m = re.search(pattern, line)
444 if m:
445 syscalls.add(m.group(1))
446 for syscall in sorted(syscalls):
Elliott Hughescda62092013-03-22 13:50:44 -0700447 fp.write("#define SYS_%s %s\n" % (syscall, make__NR_name(syscall)))
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700448
449
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700450 def gen_glibc_syscalls_h(self):
Elliott Hughescda62092013-03-22 13:50:44 -0700451 # TODO: generate a separate file for each architecture, like glibc's bits/syscall.h.
Elliott Hughes9724ce32013-03-21 19:43:54 -0700452 glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700453 D("generating " + glibc_syscalls_h_path)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700454 glibc_fp = create_file(glibc_syscalls_h_path)
Elliott Hughes103ccde2013-10-16 14:27:59 -0700455 glibc_fp.write("/* %s */\n" % warning)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700456 glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
457 glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
458
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100459 glibc_fp.write("#if defined(__aarch64__)\n")
460 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-generic/unistd.h")
461 glibc_fp.write("#elif defined(__arm__)\n")
Elliott Hughes887e1142014-01-02 12:05:50 -0800462 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-arm/asm/unistd.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700463 glibc_fp.write("#elif defined(__mips__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800464 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-mips/asm/unistd.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700465 glibc_fp.write("#elif defined(__i386__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800466 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 +0400467 glibc_fp.write("#elif defined(__x86_64__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800468 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 -0700469 glibc_fp.write("#endif\n")
470
471 glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
472 glibc_fp.close()
473 self.other_files.append(glibc_syscalls_h_path)
474
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700475
Elliott Hughesd6121652013-09-25 22:43:36 -0700476 # Write each syscall stub.
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700477 def gen_syscall_stubs(self):
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700478 for syscall in self.syscalls:
Elliott Hughesd6121652013-09-25 22:43:36 -0700479 for arch in all_arches:
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700480 if syscall.has_key("asm-%s" % arch):
481 filename = "arch-%s/syscalls/%s.S" % (arch, syscall["func"])
Elliott Hughesd6121652013-09-25 22:43:36 -0700482 D2(">>> generating " + filename)
483 fp = create_file(filename)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700484 fp.write(syscall["asm-%s" % arch])
Elliott Hughesd6121652013-09-25 22:43:36 -0700485 fp.close()
486 self.new_stubs.append(filename)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700487
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700488
Elliott Hughesd6121652013-09-25 22:43:36 -0700489 def regenerate(self):
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400490 D("scanning for existing architecture-specific stub files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700491
Elliott Hughes18bc9752013-06-17 10:26:10 -0700492 bionic_libc_root_len = len(bionic_libc_root)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700493
Elliott Hughesd6121652013-09-25 22:43:36 -0700494 for arch in all_arches:
Elliott Hughes18bc9752013-06-17 10:26:10 -0700495 arch_path = bionic_libc_root + "arch-" + arch
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400496 D("scanning " + arch_path)
497 files = glob.glob(arch_path + "/syscalls/*.S")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700498 for f in files:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400499 self.old_stubs.append(f[bionic_libc_root_len:])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700500
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400501 D("found %d stub files" % len(self.old_stubs))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700502
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400503 if not os.path.exists(bionic_temp):
504 D("creating %s..." % bionic_temp)
505 make_dir(bionic_temp)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700506
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400507 D("re-generating stubs and support files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700508
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700509 self.gen_glibc_syscalls_h()
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700510 self.gen_syscall_stubs()
511
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400512 D("comparing files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700513 adds = []
514 edits = []
515
516 for stub in self.new_stubs + self.other_files:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400517 if not os.path.exists(bionic_libc_root + stub):
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200518 # new file, git add it
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400519 D("new file: " + stub)
520 adds.append(bionic_libc_root + stub)
521 shutil.copyfile(bionic_temp + stub, bionic_libc_root + stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700522
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400523 elif not filecmp.cmp(bionic_temp + stub, bionic_libc_root + stub):
524 D("changed file: " + stub)
525 edits.append(stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700526
527 deletes = []
528 for stub in self.old_stubs:
529 if not stub in self.new_stubs:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400530 D("deleted file: " + stub)
531 deletes.append(bionic_libc_root + stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700532
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400533 if not DRY_RUN:
534 if adds:
535 commands.getoutput("git add " + " ".join(adds))
536 if deletes:
537 commands.getoutput("git rm " + " ".join(deletes))
538 if edits:
539 for file in edits:
540 shutil.copyfile(bionic_temp + file, bionic_libc_root + file)
541 commands.getoutput("git add " + " ".join((bionic_libc_root + file) for file in edits))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700542
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400543 commands.getoutput("git add %s%s" % (bionic_libc_root,"SYSCALLS.TXT"))
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200544
545 if (not adds) and (not deletes) and (not edits):
546 D("no changes detected!")
547 else:
548 D("ready to go!!")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700549
550D_setlevel(1)
551
552state = State()
Elliott Hughes18bc9752013-06-17 10:26:10 -0700553state.process_file(bionic_libc_root+"SYSCALLS.TXT")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700554state.regenerate()