blob: 316e05b03b5e88e8bdfe24a9f35646fbdbc5cb08 [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
Dan Alberte35fd482014-08-08 15:19:20 -070046 .hidden __set_errno
47
Elliott Hughes0437f3f2013-10-07 23:53:13 -070048ENTRY(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +040049"""
50
Elliott Hughes0437f3f2013-10-07 23:53:13 -070051
H.J. Lu6fe4e872013-10-04 10:03:17 -070052function_alias = """
Elliott Hughes986f9062014-02-18 16:42:36 -080053 .globl %(alias)s
54 .equ %(alias)s, %(func)s
H.J. Lu6fe4e872013-10-04 10:03:17 -070055"""
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -070056
Elliott Hughes0437f3f2013-10-07 23:53:13 -070057
58#
59# ARM assembler templates for each syscall stub
60#
61
62arm_eabi_call_default = syscall_stub_header + """\
63 mov ip, r7
64 ldr r7, =%(__NR_name)s
65 swi #0
66 mov r7, ip
67 cmn r0, #(MAX_ERRNO + 1)
68 bxls lr
69 neg r0, r0
70 b __set_errno
71END(%(func)s)
72"""
73
74arm_eabi_call_long = syscall_stub_header + """\
75 mov ip, sp
Elliott Hughes0437f3f2013-10-07 23:53:13 -070076 stmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080077 .cfi_def_cfa_offset 16
78 .cfi_rel_offset r4, 0
79 .cfi_rel_offset r5, 4
80 .cfi_rel_offset r6, 8
81 .cfi_rel_offset r7, 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -070082 ldmfd ip, {r4, r5, r6}
83 ldr r7, =%(__NR_name)s
84 swi #0
85 ldmfd sp!, {r4, r5, r6, r7}
Christopher Ferrised459702013-12-02 17:44:53 -080086 .cfi_def_cfa_offset 0
Elliott Hughes0437f3f2013-10-07 23:53:13 -070087 cmn r0, #(MAX_ERRNO + 1)
88 bxls lr
89 neg r0, r0
90 b __set_errno
91END(%(func)s)
92"""
93
94
95#
Colin Crossd1973ca2014-01-21 19:50:58 -080096# Arm64 assembler templates for each syscall stub
97#
98
99arm64_call = syscall_stub_header + """\
Colin Crossd1973ca2014-01-21 19:50:58 -0800100 mov x8, %(__NR_name)s
101 svc #0
102
Colin Crossd1973ca2014-01-21 19:50:58 -0800103 cmn x0, #(MAX_ERRNO + 1)
104 cneg x0, x0, hi
105 b.hi __set_errno
106
107 ret
108END(%(func)s)
109"""
110
111
112#
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700113# MIPS assembler templates for each syscall stub
114#
115
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800116mips_call = syscall_stub_header + """\
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700117 .set noreorder
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800118 .cpload t9
119 li v0, %(__NR_name)s
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700120 syscall
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800121 bnez a3, 1f
122 move a0, v0
123 j ra
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700124 nop
1251:
Elliott Hugheseae27dc2014-02-19 12:20:00 -0800126 la t9,__set_errno
127 j t9
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700128 nop
129 .set reorder
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800130END(%(func)s)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700131"""
132
133
Elliott Hughescd6780b2013-02-07 14:07:00 -0800134#
Chris Dearman50432122014-02-05 16:59:23 -0800135# MIPS64 assembler templates for each syscall stub
136#
137
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800138mips64_call = syscall_stub_header + """\
Chris Dearman50432122014-02-05 16:59:23 -0800139 .set push
140 .set noreorder
141 li v0, %(__NR_name)s
142 syscall
143 bnez a3, 1f
144 move a0, v0
145 j ra
146 nop
1471:
148 move t0, ra
149 bal 2f
150 nop
1512:
152 .cpsetup ra, t1, 2b
153 LA t9,__set_errno
154 .cpreturn
155 j t9
156 move ra, t0
157 .set pop
Elliott Hughes9abbbdc2014-02-19 14:54:31 -0800158END(%(func)s)
Chris Dearman50432122014-02-05 16:59:23 -0800159"""
160
161
162#
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700163# x86 assembler templates for each syscall stub
164#
165
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800166x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700167
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700168x86_call = """\
169 movl $%(__NR_name)s, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700170 int $0x80
Elliott Hughes9aceab52013-03-12 14:57:30 -0700171 cmpl $-MAX_ERRNO, %%eax
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700172 jb 1f
173 negl %%eax
174 pushl %%eax
175 call __set_errno
176 addl $4, %%esp
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001771:
178"""
179
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700180x86_return = """\
181 ret
182END(%(func)s)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700183"""
184
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700185
Elliott Hughescd6780b2013-02-07 14:07:00 -0800186#
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400187# x86_64 assembler templates for each syscall stub
188#
189
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700190x86_64_call = """\
191 movl $%(__NR_name)s, %%eax
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400192 syscall
193 cmpq $-MAX_ERRNO, %%rax
194 jb 1f
195 negl %%eax
196 movl %%eax, %%edi
197 call __set_errno
Pavel Chupinf12a18b2012-12-12 13:11:48 +04001981:
199 ret
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700200END(%(func)s)
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400201"""
202
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800203
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100204def param_uses_64bits(param):
205 """Returns True iff a syscall parameter description corresponds
206 to a 64-bit type."""
207 param = param.strip()
208 # First, check that the param type begins with one of the known
209 # 64-bit types.
210 if not ( \
211 param.startswith("int64_t") or param.startswith("uint64_t") or \
212 param.startswith("loff_t") or param.startswith("off64_t") or \
213 param.startswith("long long") or param.startswith("unsigned long long") or
214 param.startswith("signed long long") ):
215 return False
216
217 # Second, check that there is no pointer type here
218 if param.find("*") >= 0:
219 return False
220
221 # Ok
222 return True
223
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700224
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100225def count_arm_param_registers(params):
226 """This function is used to count the number of register used
Elliott Hughescd6780b2013-02-07 14:07:00 -0800227 to pass parameters when invoking an ARM system call.
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100228 This is because the ARM EABI mandates that 64-bit quantities
229 must be passed in an even+odd register pair. So, for example,
230 something like:
231
232 foo(int fd, off64_t pos)
233
234 would actually need 4 registers:
235 r0 -> int
236 r1 -> unused
237 r2-r3 -> pos
238 """
239 count = 0
240 for param in params:
241 if param_uses_64bits(param):
242 if (count & 1) != 0:
243 count += 1
244 count += 2
245 else:
246 count += 1
247 return count
248
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700249
David 'Digit' Turner95d751f2010-12-16 16:47:14 +0100250def count_generic_param_registers(params):
251 count = 0
252 for param in params:
253 if param_uses_64bits(param):
254 count += 2
255 else:
256 count += 1
257 return count
258
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700259
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400260def count_generic_param_registers64(params):
261 count = 0
262 for param in params:
263 count += 1
264 return count
265
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700266
Elliott Hughescda62092013-03-22 13:50:44 -0700267# This lets us support regular system calls like __NR_write and also weird
268# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
269def make__NR_name(name):
270 if name.startswith("__"):
271 return name
272 else:
273 return "__NR_%s" % (name)
274
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700275
Elliott Hughesfff6e272013-10-24 17:03:20 -0700276def add_footer(pointer_length, stub, syscall):
277 # Add any aliases for this syscall.
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700278 aliases = syscall["aliases"]
279 for alias in aliases:
280 stub += function_alias % { "func" : syscall["func"], "alias" : alias }
Elliott Hughesfff6e272013-10-24 17:03:20 -0700281
282 # Use hidden visibility for any functions beginning with underscores.
Elliott Hughesfff6e272013-10-24 17:03:20 -0700283 if pointer_length == 64 and syscall["func"].startswith("__"):
Elliott Hughesd465eb42014-02-19 18:59:19 -0800284 stub += '.hidden ' + syscall["func"] + '\n'
Elliott Hughesfff6e272013-10-24 17:03:20 -0700285
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700286 return stub
287
288
289def arm_eabi_genstub(syscall):
290 num_regs = count_arm_param_registers(syscall["params"])
291 if num_regs > 4:
292 return arm_eabi_call_long % syscall
293 return arm_eabi_call_default % syscall
294
295
Colin Crossd1973ca2014-01-21 19:50:58 -0800296def arm64_genstub(syscall):
297 return arm64_call % syscall
298
299
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700300def mips_genstub(syscall):
301 return mips_call % syscall
302
303
Chris Dearman50432122014-02-05 16:59:23 -0800304def mips64_genstub(syscall):
305 return mips64_call % syscall
306
307
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700308def x86_genstub(syscall):
309 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700310
311 numparams = count_generic_param_registers(syscall["params"])
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800312 stack_bias = numparams*4 + 4
313 offset = 0
314 mov_result = ""
Christopher Ferris15b91e92014-05-29 18:17:09 -0700315 first_push = True
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800316 for register in x86_registers[:numparams]:
317 result += " pushl %%%s\n" % register
Christopher Ferris15b91e92014-05-29 18:17:09 -0700318 if first_push:
319 result += " .cfi_def_cfa_offset 8\n"
320 result += " .cfi_rel_offset %s, 0\n" % register
321 first_push = False
322 else:
323 result += " .cfi_adjust_cfa_offset 4\n"
324 result += " .cfi_rel_offset %s, 0\n" % register
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800325 mov_result += " mov %d(%%esp), %%%s\n" % (stack_bias+offset, register)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800326 offset += 4
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700327
Christopher Ferris15b91e92014-05-29 18:17:09 -0700328 result += mov_result
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700329 result += x86_call % syscall
330
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800331 for register in reversed(x86_registers[:numparams]):
332 result += " popl %%%s\n" % register
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700333
334 result += x86_return % syscall
335 return result
336
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100337
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700338def x86_genstub_socketcall(syscall):
339 # %ebx <--- Argument 1 - The call id of the needed vectored
340 # syscall (socket, bind, recv, etc)
341 # %ecx <--- Argument 2 - Pointer to the rest of the arguments
342 # from the original function called (socket())
343
344 result = syscall_stub_header % syscall
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700345
346 # save the regs we need
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800347 result += " pushl %ebx\n"
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800348 result += " .cfi_def_cfa_offset 8\n"
349 result += " .cfi_rel_offset ebx, 0\n"
Christopher Ferris15b91e92014-05-29 18:17:09 -0700350 result += " pushl %ecx\n"
351 result += " .cfi_adjust_cfa_offset 4\n"
352 result += " .cfi_rel_offset ecx, 0\n"
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800353 stack_bias = 12
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700354
355 # set the call id (%ebx)
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800356 result += " mov $%d, %%ebx\n" % syscall["socketcall_id"]
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700357
358 # set the pointer to the rest of the args into %ecx
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800359 result += " mov %esp, %ecx\n"
360 result += " addl $%d, %%ecx\n" % (stack_bias)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700361
362 # now do the syscall code itself
363 result += x86_call % syscall
364
365 # now restore the saved regs
Christopher Ferrise4bc7562014-01-06 16:39:10 -0800366 result += " popl %ecx\n"
367 result += " popl %ebx\n"
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700368
369 # epilog
370 result += x86_return % syscall
371 return result
372
373
374def x86_64_genstub(syscall):
375 result = syscall_stub_header % syscall
376 num_regs = count_generic_param_registers64(syscall["params"])
377 if (num_regs > 3):
378 # rcx is used as 4th argument. Kernel wants it at r10.
379 result += " movq %rcx, %r10\n"
380
381 result += x86_64_call % syscall
382 return result
383
384
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700385class State:
386 def __init__(self):
387 self.old_stubs = []
388 self.new_stubs = []
389 self.other_files = []
390 self.syscalls = []
391
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400392
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700393 def process_file(self, input):
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700394 parser = SysCallsTxtParser()
395 parser.parse_file(input)
396 self.syscalls = parser.syscalls
397 parser = None
398
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700399 for syscall in self.syscalls:
400 syscall["__NR_name"] = make__NR_name(syscall["name"])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700401
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700402 if syscall.has_key("arm"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700403 syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700404
Colin Crossd1973ca2014-01-21 19:50:58 -0800405 if syscall.has_key("arm64"):
406 syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall)
407
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700408 if syscall.has_key("x86"):
409 if syscall["socketcall_id"] >= 0:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700410 syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800411 else:
Elliott Hughesfff6e272013-10-24 17:03:20 -0700412 syscall["asm-x86"] = add_footer(32, x86_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700413 elif syscall["socketcall_id"] >= 0:
Elliott Hughesd6121652013-09-25 22:43:36 -0700414 E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800415 return
Elliott Hughescd6780b2013-02-07 14:07:00 -0800416
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700417 if syscall.has_key("mips"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700418 syscall["asm-mips"] = add_footer(32, mips_genstub(syscall), syscall)
The Android Open Source Project4e468ed2008-12-17 18:03:48 -0800419
Chris Dearman50432122014-02-05 16:59:23 -0800420 if syscall.has_key("mips64"):
421 syscall["asm-mips64"] = add_footer(64, mips64_genstub(syscall), syscall)
422
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700423 if syscall.has_key("x86_64"):
Elliott Hughesfff6e272013-10-24 17:03:20 -0700424 syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700425
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700426 # Scan a Linux kernel asm/unistd.h file containing __NR_* constants
427 # and write out equivalent SYS_* constants for glibc source compatibility.
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700428 def scan_linux_unistd_h(self, fp, path):
429 pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
430 syscalls = set() # MIPS defines everything three times; work around that.
431 for line in open(path):
432 m = re.search(pattern, line)
433 if m:
434 syscalls.add(m.group(1))
435 for syscall in sorted(syscalls):
Elliott Hughescda62092013-03-22 13:50:44 -0700436 fp.write("#define SYS_%s %s\n" % (syscall, make__NR_name(syscall)))
Elliott Hughes8ecf2252013-03-21 18:06:55 -0700437
438
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700439 def gen_glibc_syscalls_h(self):
Elliott Hughescda62092013-03-22 13:50:44 -0700440 # TODO: generate a separate file for each architecture, like glibc's bits/syscall.h.
Elliott Hughes9724ce32013-03-21 19:43:54 -0700441 glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700442 D("generating " + glibc_syscalls_h_path)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700443 glibc_fp = create_file(glibc_syscalls_h_path)
Elliott Hughes103ccde2013-10-16 14:27:59 -0700444 glibc_fp.write("/* %s */\n" % warning)
Elliott Hughes9724ce32013-03-21 19:43:54 -0700445 glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
446 glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
447
Serban Constantinescufeaa89a2013-10-07 16:49:09 +0100448 glibc_fp.write("#if defined(__aarch64__)\n")
449 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-generic/unistd.h")
450 glibc_fp.write("#elif defined(__arm__)\n")
Elliott Hughes887e1142014-01-02 12:05:50 -0800451 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-arm/asm/unistd.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700452 glibc_fp.write("#elif defined(__mips__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800453 self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-mips/asm/unistd.h")
Elliott Hughes5c2772f2013-03-21 22:15:06 -0700454 glibc_fp.write("#elif defined(__i386__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800455 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 +0400456 glibc_fp.write("#elif defined(__x86_64__)\n")
Christopher Ferrised459702013-12-02 17:44:53 -0800457 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 -0700458 glibc_fp.write("#endif\n")
459
460 glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
461 glibc_fp.close()
462 self.other_files.append(glibc_syscalls_h_path)
463
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700464
Elliott Hughesd6121652013-09-25 22:43:36 -0700465 # Write each syscall stub.
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700466 def gen_syscall_stubs(self):
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700467 for syscall in self.syscalls:
Elliott Hughesd6121652013-09-25 22:43:36 -0700468 for arch in all_arches:
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700469 if syscall.has_key("asm-%s" % arch):
470 filename = "arch-%s/syscalls/%s.S" % (arch, syscall["func"])
Elliott Hughesd6121652013-09-25 22:43:36 -0700471 D2(">>> generating " + filename)
472 fp = create_file(filename)
Elliott Hughes0437f3f2013-10-07 23:53:13 -0700473 fp.write(syscall["asm-%s" % arch])
Elliott Hughesd6121652013-09-25 22:43:36 -0700474 fp.close()
475 self.new_stubs.append(filename)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700476
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700477
Elliott Hughesd6121652013-09-25 22:43:36 -0700478 def regenerate(self):
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400479 D("scanning for existing architecture-specific stub files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700480
Elliott Hughes18bc9752013-06-17 10:26:10 -0700481 bionic_libc_root_len = len(bionic_libc_root)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700482
Elliott Hughesd6121652013-09-25 22:43:36 -0700483 for arch in all_arches:
Elliott Hughes18bc9752013-06-17 10:26:10 -0700484 arch_path = bionic_libc_root + "arch-" + arch
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400485 D("scanning " + arch_path)
486 files = glob.glob(arch_path + "/syscalls/*.S")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700487 for f in files:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400488 self.old_stubs.append(f[bionic_libc_root_len:])
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700489
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400490 D("found %d stub files" % len(self.old_stubs))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700491
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400492 if not os.path.exists(bionic_temp):
493 D("creating %s..." % bionic_temp)
494 make_dir(bionic_temp)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700495
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400496 D("re-generating stubs and support files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700497
Elliott Hughes1b91c6c2013-03-22 18:56:24 -0700498 self.gen_glibc_syscalls_h()
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700499 self.gen_syscall_stubs()
500
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400501 D("comparing files...")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700502 adds = []
503 edits = []
504
505 for stub in self.new_stubs + self.other_files:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400506 if not os.path.exists(bionic_libc_root + stub):
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200507 # new file, git add it
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400508 D("new file: " + stub)
509 adds.append(bionic_libc_root + stub)
510 shutil.copyfile(bionic_temp + stub, bionic_libc_root + stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700511
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400512 elif not filecmp.cmp(bionic_temp + stub, bionic_libc_root + stub):
513 D("changed file: " + stub)
514 edits.append(stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700515
516 deletes = []
517 for stub in self.old_stubs:
518 if not stub in self.new_stubs:
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400519 D("deleted file: " + stub)
520 deletes.append(bionic_libc_root + stub)
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700521
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400522 if not DRY_RUN:
523 if adds:
524 commands.getoutput("git add " + " ".join(adds))
525 if deletes:
526 commands.getoutput("git rm " + " ".join(deletes))
527 if edits:
528 for file in edits:
529 shutil.copyfile(bionic_temp + file, bionic_libc_root + file)
530 commands.getoutput("git add " + " ".join((bionic_libc_root + file) for file in edits))
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700531
Pavel Chupinf12a18b2012-12-12 13:11:48 +0400532 commands.getoutput("git add %s%s" % (bionic_libc_root,"SYSCALLS.TXT"))
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200533
534 if (not adds) and (not deletes) and (not edits):
535 D("no changes detected!")
536 else:
537 D("ready to go!!")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700538
539D_setlevel(1)
540
541state = State()
Elliott Hughes18bc9752013-06-17 10:26:10 -0700542state.process_file(bionic_libc_root+"SYSCALLS.TXT")
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -0700543state.regenerate()