1*8d67ca89SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*8d67ca89SAndroid Build Coastguard Worker 3*8d67ca89SAndroid Build Coastguard Worker# This tool is used to generate the assembler system call stubs, 4*8d67ca89SAndroid Build Coastguard Worker# the header files listing all available system calls, and the 5*8d67ca89SAndroid Build Coastguard Worker# makefiles used to build all the stubs. 6*8d67ca89SAndroid Build Coastguard Worker 7*8d67ca89SAndroid Build Coastguard Workerimport atexit 8*8d67ca89SAndroid Build Coastguard Workerimport filecmp 9*8d67ca89SAndroid Build Coastguard Workerimport glob 10*8d67ca89SAndroid Build Coastguard Workerimport re 11*8d67ca89SAndroid Build Coastguard Workerimport shutil 12*8d67ca89SAndroid Build Coastguard Workerimport stat 13*8d67ca89SAndroid Build Coastguard Workerimport string 14*8d67ca89SAndroid Build Coastguard Workerimport sys 15*8d67ca89SAndroid Build Coastguard Workerimport tempfile 16*8d67ca89SAndroid Build Coastguard Worker 17*8d67ca89SAndroid Build Coastguard Worker 18*8d67ca89SAndroid Build Coastguard WorkerSupportedArchitectures = [ "arm", "arm64", "riscv64", "x86", "x86_64" ] 19*8d67ca89SAndroid Build Coastguard Worker 20*8d67ca89SAndroid Build Coastguard Workersyscall_stub_header = \ 21*8d67ca89SAndroid Build Coastguard Worker""" 22*8d67ca89SAndroid Build Coastguard WorkerENTRY(%(func)s) 23*8d67ca89SAndroid Build Coastguard Worker""" 24*8d67ca89SAndroid Build Coastguard Worker 25*8d67ca89SAndroid Build Coastguard Worker 26*8d67ca89SAndroid Build Coastguard Worker# 27*8d67ca89SAndroid Build Coastguard Worker# ARM assembler templates for each syscall stub 28*8d67ca89SAndroid Build Coastguard Worker# 29*8d67ca89SAndroid Build Coastguard Worker 30*8d67ca89SAndroid Build Coastguard Workerarm_call_default = syscall_stub_header + """\ 31*8d67ca89SAndroid Build Coastguard Worker mov ip, r7 32*8d67ca89SAndroid Build Coastguard Worker .cfi_register r7, ip 33*8d67ca89SAndroid Build Coastguard Worker ldr r7, =%(__NR_name)s 34*8d67ca89SAndroid Build Coastguard Worker swi #0 35*8d67ca89SAndroid Build Coastguard Worker mov r7, ip 36*8d67ca89SAndroid Build Coastguard Worker .cfi_restore r7 37*8d67ca89SAndroid Build Coastguard Worker cmn r0, #(MAX_ERRNO + 1) 38*8d67ca89SAndroid Build Coastguard Worker bxls lr 39*8d67ca89SAndroid Build Coastguard Worker neg r0, r0 40*8d67ca89SAndroid Build Coastguard Worker b __set_errno_internal 41*8d67ca89SAndroid Build Coastguard WorkerEND(%(func)s) 42*8d67ca89SAndroid Build Coastguard Worker""" 43*8d67ca89SAndroid Build Coastguard Worker 44*8d67ca89SAndroid Build Coastguard Workerarm_call_long = syscall_stub_header + """\ 45*8d67ca89SAndroid Build Coastguard Worker mov ip, sp 46*8d67ca89SAndroid Build Coastguard Worker stmfd sp!, {r4, r5, r6, r7} 47*8d67ca89SAndroid Build Coastguard Worker .cfi_def_cfa_offset 16 48*8d67ca89SAndroid Build Coastguard Worker .cfi_rel_offset r4, 0 49*8d67ca89SAndroid Build Coastguard Worker .cfi_rel_offset r5, 4 50*8d67ca89SAndroid Build Coastguard Worker .cfi_rel_offset r6, 8 51*8d67ca89SAndroid Build Coastguard Worker .cfi_rel_offset r7, 12 52*8d67ca89SAndroid Build Coastguard Worker ldmfd ip, {r4, r5, r6} 53*8d67ca89SAndroid Build Coastguard Worker ldr r7, =%(__NR_name)s 54*8d67ca89SAndroid Build Coastguard Worker swi #0 55*8d67ca89SAndroid Build Coastguard Worker ldmfd sp!, {r4, r5, r6, r7} 56*8d67ca89SAndroid Build Coastguard Worker .cfi_def_cfa_offset 0 57*8d67ca89SAndroid Build Coastguard Worker cmn r0, #(MAX_ERRNO + 1) 58*8d67ca89SAndroid Build Coastguard Worker bxls lr 59*8d67ca89SAndroid Build Coastguard Worker neg r0, r0 60*8d67ca89SAndroid Build Coastguard Worker b __set_errno_internal 61*8d67ca89SAndroid Build Coastguard WorkerEND(%(func)s) 62*8d67ca89SAndroid Build Coastguard Worker""" 63*8d67ca89SAndroid Build Coastguard Worker 64*8d67ca89SAndroid Build Coastguard Worker 65*8d67ca89SAndroid Build Coastguard Worker# 66*8d67ca89SAndroid Build Coastguard Worker# Arm64 assembler template for each syscall stub 67*8d67ca89SAndroid Build Coastguard Worker# 68*8d67ca89SAndroid Build Coastguard Worker 69*8d67ca89SAndroid Build Coastguard Workerarm64_call = syscall_stub_header + """\ 70*8d67ca89SAndroid Build Coastguard Worker mov x8, %(__NR_name)s 71*8d67ca89SAndroid Build Coastguard Worker svc #0 72*8d67ca89SAndroid Build Coastguard Worker 73*8d67ca89SAndroid Build Coastguard Worker cmn x0, #(MAX_ERRNO + 1) 74*8d67ca89SAndroid Build Coastguard Worker cneg x0, x0, hi 75*8d67ca89SAndroid Build Coastguard Worker b.hi __set_errno_internal 76*8d67ca89SAndroid Build Coastguard Worker 77*8d67ca89SAndroid Build Coastguard Worker ret 78*8d67ca89SAndroid Build Coastguard WorkerEND(%(func)s) 79*8d67ca89SAndroid Build Coastguard Worker""" 80*8d67ca89SAndroid Build Coastguard Worker 81*8d67ca89SAndroid Build Coastguard Worker 82*8d67ca89SAndroid Build Coastguard Worker# 83*8d67ca89SAndroid Build Coastguard Worker# RISC-V64 assembler templates for each syscall stub 84*8d67ca89SAndroid Build Coastguard Worker# 85*8d67ca89SAndroid Build Coastguard Worker 86*8d67ca89SAndroid Build Coastguard Workerriscv64_call = syscall_stub_header + """\ 87*8d67ca89SAndroid Build Coastguard Worker li a7, %(__NR_name)s 88*8d67ca89SAndroid Build Coastguard Worker ecall 89*8d67ca89SAndroid Build Coastguard Worker 90*8d67ca89SAndroid Build Coastguard Worker li a7, -MAX_ERRNO 91*8d67ca89SAndroid Build Coastguard Worker bgeu a0, a7, 1f 92*8d67ca89SAndroid Build Coastguard Worker 93*8d67ca89SAndroid Build Coastguard Worker ret 94*8d67ca89SAndroid Build Coastguard Worker1: 95*8d67ca89SAndroid Build Coastguard Worker neg a0, a0 96*8d67ca89SAndroid Build Coastguard Worker tail __set_errno_internal 97*8d67ca89SAndroid Build Coastguard WorkerEND(%(func)s) 98*8d67ca89SAndroid Build Coastguard Worker""" 99*8d67ca89SAndroid Build Coastguard Worker 100*8d67ca89SAndroid Build Coastguard Worker# 101*8d67ca89SAndroid Build Coastguard Worker# x86 assembler templates for each syscall stub 102*8d67ca89SAndroid Build Coastguard Worker# 103*8d67ca89SAndroid Build Coastguard Worker 104*8d67ca89SAndroid Build Coastguard Workerx86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ] 105*8d67ca89SAndroid Build Coastguard Worker 106*8d67ca89SAndroid Build Coastguard Workerx86_call_prepare = """\ 107*8d67ca89SAndroid Build Coastguard Worker 108*8d67ca89SAndroid Build Coastguard Worker call __kernel_syscall 109*8d67ca89SAndroid Build Coastguard Worker pushl %eax 110*8d67ca89SAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 111*8d67ca89SAndroid Build Coastguard Worker .cfi_rel_offset eax, 0 112*8d67ca89SAndroid Build Coastguard Worker 113*8d67ca89SAndroid Build Coastguard Worker""" 114*8d67ca89SAndroid Build Coastguard Worker 115*8d67ca89SAndroid Build Coastguard Workerx86_call = """\ 116*8d67ca89SAndroid Build Coastguard Worker movl $%(__NR_name)s, %%eax 117*8d67ca89SAndroid Build Coastguard Worker call *(%%esp) 118*8d67ca89SAndroid Build Coastguard Worker addl $4, %%esp 119*8d67ca89SAndroid Build Coastguard Worker 120*8d67ca89SAndroid Build Coastguard Worker cmpl $-MAX_ERRNO, %%eax 121*8d67ca89SAndroid Build Coastguard Worker jb 1f 122*8d67ca89SAndroid Build Coastguard Worker negl %%eax 123*8d67ca89SAndroid Build Coastguard Worker pushl %%eax 124*8d67ca89SAndroid Build Coastguard Worker call __set_errno_internal 125*8d67ca89SAndroid Build Coastguard Worker addl $4, %%esp 126*8d67ca89SAndroid Build Coastguard Worker1: 127*8d67ca89SAndroid Build Coastguard Worker""" 128*8d67ca89SAndroid Build Coastguard Worker 129*8d67ca89SAndroid Build Coastguard Workerx86_return = """\ 130*8d67ca89SAndroid Build Coastguard Worker ret 131*8d67ca89SAndroid Build Coastguard WorkerEND(%(func)s) 132*8d67ca89SAndroid Build Coastguard Worker""" 133*8d67ca89SAndroid Build Coastguard Worker 134*8d67ca89SAndroid Build Coastguard Worker 135*8d67ca89SAndroid Build Coastguard Worker# 136*8d67ca89SAndroid Build Coastguard Worker# x86_64 assembler template for each syscall stub 137*8d67ca89SAndroid Build Coastguard Worker# 138*8d67ca89SAndroid Build Coastguard Worker 139*8d67ca89SAndroid Build Coastguard Workerx86_64_call = """\ 140*8d67ca89SAndroid Build Coastguard Worker movl $%(__NR_name)s, %%eax 141*8d67ca89SAndroid Build Coastguard Worker syscall 142*8d67ca89SAndroid Build Coastguard Worker cmpq $-MAX_ERRNO, %%rax 143*8d67ca89SAndroid Build Coastguard Worker jb 1f 144*8d67ca89SAndroid Build Coastguard Worker negl %%eax 145*8d67ca89SAndroid Build Coastguard Worker movl %%eax, %%edi 146*8d67ca89SAndroid Build Coastguard Worker call __set_errno_internal 147*8d67ca89SAndroid Build Coastguard Worker1: 148*8d67ca89SAndroid Build Coastguard Worker ret 149*8d67ca89SAndroid Build Coastguard WorkerEND(%(func)s) 150*8d67ca89SAndroid Build Coastguard Worker""" 151*8d67ca89SAndroid Build Coastguard Worker 152*8d67ca89SAndroid Build Coastguard Worker 153*8d67ca89SAndroid Build Coastguard Workerdef param_uses_64bits(param): 154*8d67ca89SAndroid Build Coastguard Worker """Returns True iff a syscall parameter description corresponds 155*8d67ca89SAndroid Build Coastguard Worker to a 64-bit type.""" 156*8d67ca89SAndroid Build Coastguard Worker param = param.strip() 157*8d67ca89SAndroid Build Coastguard Worker # First, check that the param type begins with one of the known 158*8d67ca89SAndroid Build Coastguard Worker # 64-bit types. 159*8d67ca89SAndroid Build Coastguard Worker if not ( \ 160*8d67ca89SAndroid Build Coastguard Worker param.startswith("int64_t") or param.startswith("uint64_t") or \ 161*8d67ca89SAndroid Build Coastguard Worker param.startswith("loff_t") or param.startswith("off64_t") or \ 162*8d67ca89SAndroid Build Coastguard Worker param.startswith("long long") or param.startswith("unsigned long long") or 163*8d67ca89SAndroid Build Coastguard Worker param.startswith("signed long long") ): 164*8d67ca89SAndroid Build Coastguard Worker return False 165*8d67ca89SAndroid Build Coastguard Worker 166*8d67ca89SAndroid Build Coastguard Worker # Second, check that there is no pointer type here 167*8d67ca89SAndroid Build Coastguard Worker if param.find("*") >= 0: 168*8d67ca89SAndroid Build Coastguard Worker return False 169*8d67ca89SAndroid Build Coastguard Worker 170*8d67ca89SAndroid Build Coastguard Worker # Ok 171*8d67ca89SAndroid Build Coastguard Worker return True 172*8d67ca89SAndroid Build Coastguard Worker 173*8d67ca89SAndroid Build Coastguard Worker 174*8d67ca89SAndroid Build Coastguard Workerdef count_arm_param_registers(params): 175*8d67ca89SAndroid Build Coastguard Worker """This function is used to count the number of register used 176*8d67ca89SAndroid Build Coastguard Worker to pass parameters when invoking an ARM system call. 177*8d67ca89SAndroid Build Coastguard Worker This is because the ARM EABI mandates that 64-bit quantities 178*8d67ca89SAndroid Build Coastguard Worker must be passed in an even+odd register pair. So, for example, 179*8d67ca89SAndroid Build Coastguard Worker something like: 180*8d67ca89SAndroid Build Coastguard Worker 181*8d67ca89SAndroid Build Coastguard Worker foo(int fd, off64_t pos) 182*8d67ca89SAndroid Build Coastguard Worker 183*8d67ca89SAndroid Build Coastguard Worker would actually need 4 registers: 184*8d67ca89SAndroid Build Coastguard Worker r0 -> int 185*8d67ca89SAndroid Build Coastguard Worker r1 -> unused 186*8d67ca89SAndroid Build Coastguard Worker r2-r3 -> pos 187*8d67ca89SAndroid Build Coastguard Worker """ 188*8d67ca89SAndroid Build Coastguard Worker count = 0 189*8d67ca89SAndroid Build Coastguard Worker for param in params: 190*8d67ca89SAndroid Build Coastguard Worker if param_uses_64bits(param): 191*8d67ca89SAndroid Build Coastguard Worker if (count & 1) != 0: 192*8d67ca89SAndroid Build Coastguard Worker count += 1 193*8d67ca89SAndroid Build Coastguard Worker count += 2 194*8d67ca89SAndroid Build Coastguard Worker else: 195*8d67ca89SAndroid Build Coastguard Worker count += 1 196*8d67ca89SAndroid Build Coastguard Worker return count 197*8d67ca89SAndroid Build Coastguard Worker 198*8d67ca89SAndroid Build Coastguard Worker 199*8d67ca89SAndroid Build Coastguard Workerdef count_generic_param_registers(params): 200*8d67ca89SAndroid Build Coastguard Worker count = 0 201*8d67ca89SAndroid Build Coastguard Worker for param in params: 202*8d67ca89SAndroid Build Coastguard Worker if param_uses_64bits(param): 203*8d67ca89SAndroid Build Coastguard Worker count += 2 204*8d67ca89SAndroid Build Coastguard Worker else: 205*8d67ca89SAndroid Build Coastguard Worker count += 1 206*8d67ca89SAndroid Build Coastguard Worker return count 207*8d67ca89SAndroid Build Coastguard Worker 208*8d67ca89SAndroid Build Coastguard Worker 209*8d67ca89SAndroid Build Coastguard Workerdef count_generic_param_registers64(params): 210*8d67ca89SAndroid Build Coastguard Worker count = 0 211*8d67ca89SAndroid Build Coastguard Worker for param in params: 212*8d67ca89SAndroid Build Coastguard Worker count += 1 213*8d67ca89SAndroid Build Coastguard Worker return count 214*8d67ca89SAndroid Build Coastguard Worker 215*8d67ca89SAndroid Build Coastguard Worker 216*8d67ca89SAndroid Build Coastguard Worker# This lets us support regular system calls like __NR_write and also weird 217*8d67ca89SAndroid Build Coastguard Worker# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start. 218*8d67ca89SAndroid Build Coastguard Workerdef make__NR_name(name): 219*8d67ca89SAndroid Build Coastguard Worker if name.startswith("__ARM_NR_"): 220*8d67ca89SAndroid Build Coastguard Worker return name 221*8d67ca89SAndroid Build Coastguard Worker else: 222*8d67ca89SAndroid Build Coastguard Worker return "__NR_%s" % (name) 223*8d67ca89SAndroid Build Coastguard Worker 224*8d67ca89SAndroid Build Coastguard Worker 225*8d67ca89SAndroid Build Coastguard Workerdef add_footer(pointer_length, stub, syscall): 226*8d67ca89SAndroid Build Coastguard Worker # Add any aliases for this syscall. 227*8d67ca89SAndroid Build Coastguard Worker aliases = syscall["aliases"] 228*8d67ca89SAndroid Build Coastguard Worker for alias in aliases: 229*8d67ca89SAndroid Build Coastguard Worker stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"]) 230*8d67ca89SAndroid Build Coastguard Worker return stub 231*8d67ca89SAndroid Build Coastguard Worker 232*8d67ca89SAndroid Build Coastguard Worker 233*8d67ca89SAndroid Build Coastguard Workerdef arm_genstub(syscall): 234*8d67ca89SAndroid Build Coastguard Worker num_regs = count_arm_param_registers(syscall["params"]) 235*8d67ca89SAndroid Build Coastguard Worker if num_regs > 4: 236*8d67ca89SAndroid Build Coastguard Worker return arm_call_long % syscall 237*8d67ca89SAndroid Build Coastguard Worker return arm_call_default % syscall 238*8d67ca89SAndroid Build Coastguard Worker 239*8d67ca89SAndroid Build Coastguard Worker 240*8d67ca89SAndroid Build Coastguard Workerdef arm64_genstub(syscall): 241*8d67ca89SAndroid Build Coastguard Worker return arm64_call % syscall 242*8d67ca89SAndroid Build Coastguard Worker 243*8d67ca89SAndroid Build Coastguard Worker 244*8d67ca89SAndroid Build Coastguard Workerdef riscv64_genstub(syscall): 245*8d67ca89SAndroid Build Coastguard Worker return riscv64_call % syscall 246*8d67ca89SAndroid Build Coastguard Worker 247*8d67ca89SAndroid Build Coastguard Worker 248*8d67ca89SAndroid Build Coastguard Workerdef x86_genstub(syscall): 249*8d67ca89SAndroid Build Coastguard Worker result = syscall_stub_header % syscall 250*8d67ca89SAndroid Build Coastguard Worker 251*8d67ca89SAndroid Build Coastguard Worker numparams = count_generic_param_registers(syscall["params"]) 252*8d67ca89SAndroid Build Coastguard Worker stack_bias = numparams*4 + 8 253*8d67ca89SAndroid Build Coastguard Worker offset = 0 254*8d67ca89SAndroid Build Coastguard Worker mov_result = "" 255*8d67ca89SAndroid Build Coastguard Worker first_push = True 256*8d67ca89SAndroid Build Coastguard Worker for register in x86_registers[:numparams]: 257*8d67ca89SAndroid Build Coastguard Worker result += " pushl %%%s\n" % register 258*8d67ca89SAndroid Build Coastguard Worker if first_push: 259*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_def_cfa_offset 8\n" 260*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_rel_offset %s, 0\n" % register 261*8d67ca89SAndroid Build Coastguard Worker first_push = False 262*8d67ca89SAndroid Build Coastguard Worker else: 263*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_adjust_cfa_offset 4\n" 264*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_rel_offset %s, 0\n" % register 265*8d67ca89SAndroid Build Coastguard Worker mov_result += " mov %d(%%esp), %%%s\n" % (stack_bias+offset, register) 266*8d67ca89SAndroid Build Coastguard Worker offset += 4 267*8d67ca89SAndroid Build Coastguard Worker 268*8d67ca89SAndroid Build Coastguard Worker result += x86_call_prepare 269*8d67ca89SAndroid Build Coastguard Worker result += mov_result 270*8d67ca89SAndroid Build Coastguard Worker result += x86_call % syscall 271*8d67ca89SAndroid Build Coastguard Worker 272*8d67ca89SAndroid Build Coastguard Worker for register in reversed(x86_registers[:numparams]): 273*8d67ca89SAndroid Build Coastguard Worker result += " popl %%%s\n" % register 274*8d67ca89SAndroid Build Coastguard Worker 275*8d67ca89SAndroid Build Coastguard Worker result += x86_return % syscall 276*8d67ca89SAndroid Build Coastguard Worker return result 277*8d67ca89SAndroid Build Coastguard Worker 278*8d67ca89SAndroid Build Coastguard Worker 279*8d67ca89SAndroid Build Coastguard Workerdef x86_genstub_socketcall(syscall): 280*8d67ca89SAndroid Build Coastguard Worker # %ebx <--- Argument 1 - The call id of the needed vectored 281*8d67ca89SAndroid Build Coastguard Worker # syscall (socket, bind, recv, etc) 282*8d67ca89SAndroid Build Coastguard Worker # %ecx <--- Argument 2 - Pointer to the rest of the arguments 283*8d67ca89SAndroid Build Coastguard Worker # from the original function called (socket()) 284*8d67ca89SAndroid Build Coastguard Worker 285*8d67ca89SAndroid Build Coastguard Worker result = syscall_stub_header % syscall 286*8d67ca89SAndroid Build Coastguard Worker 287*8d67ca89SAndroid Build Coastguard Worker # save the regs we need 288*8d67ca89SAndroid Build Coastguard Worker result += " pushl %ebx\n" 289*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_def_cfa_offset 8\n" 290*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_rel_offset ebx, 0\n" 291*8d67ca89SAndroid Build Coastguard Worker result += " pushl %ecx\n" 292*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_adjust_cfa_offset 4\n" 293*8d67ca89SAndroid Build Coastguard Worker result += " .cfi_rel_offset ecx, 0\n" 294*8d67ca89SAndroid Build Coastguard Worker stack_bias = 16 295*8d67ca89SAndroid Build Coastguard Worker 296*8d67ca89SAndroid Build Coastguard Worker result += x86_call_prepare 297*8d67ca89SAndroid Build Coastguard Worker 298*8d67ca89SAndroid Build Coastguard Worker # set the call id (%ebx) 299*8d67ca89SAndroid Build Coastguard Worker result += " mov $%d, %%ebx\n" % syscall["socketcall_id"] 300*8d67ca89SAndroid Build Coastguard Worker 301*8d67ca89SAndroid Build Coastguard Worker # set the pointer to the rest of the args into %ecx 302*8d67ca89SAndroid Build Coastguard Worker result += " mov %esp, %ecx\n" 303*8d67ca89SAndroid Build Coastguard Worker result += " addl $%d, %%ecx\n" % (stack_bias) 304*8d67ca89SAndroid Build Coastguard Worker 305*8d67ca89SAndroid Build Coastguard Worker # now do the syscall code itself 306*8d67ca89SAndroid Build Coastguard Worker result += x86_call % syscall 307*8d67ca89SAndroid Build Coastguard Worker 308*8d67ca89SAndroid Build Coastguard Worker # now restore the saved regs 309*8d67ca89SAndroid Build Coastguard Worker result += " popl %ecx\n" 310*8d67ca89SAndroid Build Coastguard Worker result += " popl %ebx\n" 311*8d67ca89SAndroid Build Coastguard Worker 312*8d67ca89SAndroid Build Coastguard Worker # epilog 313*8d67ca89SAndroid Build Coastguard Worker result += x86_return % syscall 314*8d67ca89SAndroid Build Coastguard Worker return result 315*8d67ca89SAndroid Build Coastguard Worker 316*8d67ca89SAndroid Build Coastguard Worker 317*8d67ca89SAndroid Build Coastguard Workerdef x86_64_genstub(syscall): 318*8d67ca89SAndroid Build Coastguard Worker result = syscall_stub_header % syscall 319*8d67ca89SAndroid Build Coastguard Worker num_regs = count_generic_param_registers64(syscall["params"]) 320*8d67ca89SAndroid Build Coastguard Worker if (num_regs > 3): 321*8d67ca89SAndroid Build Coastguard Worker # rcx is used as 4th argument. Kernel wants it at r10. 322*8d67ca89SAndroid Build Coastguard Worker result += " movq %rcx, %r10\n" 323*8d67ca89SAndroid Build Coastguard Worker 324*8d67ca89SAndroid Build Coastguard Worker result += x86_64_call % syscall 325*8d67ca89SAndroid Build Coastguard Worker return result 326*8d67ca89SAndroid Build Coastguard Worker 327*8d67ca89SAndroid Build Coastguard Worker 328*8d67ca89SAndroid Build Coastguard Workerclass SysCallsTxtParser: 329*8d67ca89SAndroid Build Coastguard Worker def __init__(self): 330*8d67ca89SAndroid Build Coastguard Worker self.syscalls = [] 331*8d67ca89SAndroid Build Coastguard Worker self.lineno = 0 332*8d67ca89SAndroid Build Coastguard Worker self.errors = False 333*8d67ca89SAndroid Build Coastguard Worker 334*8d67ca89SAndroid Build Coastguard Worker def E(self, msg): 335*8d67ca89SAndroid Build Coastguard Worker print("%d: %s" % (self.lineno, msg)) 336*8d67ca89SAndroid Build Coastguard Worker self.errors = True 337*8d67ca89SAndroid Build Coastguard Worker 338*8d67ca89SAndroid Build Coastguard Worker def parse_line(self, line): 339*8d67ca89SAndroid Build Coastguard Worker """ parse a syscall spec line. 340*8d67ca89SAndroid Build Coastguard Worker 341*8d67ca89SAndroid Build Coastguard Worker line processing, format is 342*8d67ca89SAndroid Build Coastguard Worker return type func_name[|alias_list][:syscall_name[:socketcall_id]] ( [paramlist] ) architecture_list 343*8d67ca89SAndroid Build Coastguard Worker """ 344*8d67ca89SAndroid Build Coastguard Worker pos_lparen = line.find('(') 345*8d67ca89SAndroid Build Coastguard Worker E = self.E 346*8d67ca89SAndroid Build Coastguard Worker if pos_lparen < 0: 347*8d67ca89SAndroid Build Coastguard Worker E("missing left parenthesis in '%s'" % line) 348*8d67ca89SAndroid Build Coastguard Worker return 349*8d67ca89SAndroid Build Coastguard Worker 350*8d67ca89SAndroid Build Coastguard Worker pos_rparen = line.rfind(')') 351*8d67ca89SAndroid Build Coastguard Worker if pos_rparen < 0 or pos_rparen <= pos_lparen: 352*8d67ca89SAndroid Build Coastguard Worker E("missing or misplaced right parenthesis in '%s'" % line) 353*8d67ca89SAndroid Build Coastguard Worker return 354*8d67ca89SAndroid Build Coastguard Worker 355*8d67ca89SAndroid Build Coastguard Worker return_type = line[:pos_lparen].strip().split() 356*8d67ca89SAndroid Build Coastguard Worker if len(return_type) < 2: 357*8d67ca89SAndroid Build Coastguard Worker E("missing return type in '%s'" % line) 358*8d67ca89SAndroid Build Coastguard Worker return 359*8d67ca89SAndroid Build Coastguard Worker 360*8d67ca89SAndroid Build Coastguard Worker syscall_func = return_type[-1] 361*8d67ca89SAndroid Build Coastguard Worker return_type = ' '.join(return_type[:-1]) 362*8d67ca89SAndroid Build Coastguard Worker socketcall_id = -1 363*8d67ca89SAndroid Build Coastguard Worker 364*8d67ca89SAndroid Build Coastguard Worker pos_colon = syscall_func.find(':') 365*8d67ca89SAndroid Build Coastguard Worker if pos_colon < 0: 366*8d67ca89SAndroid Build Coastguard Worker syscall_name = syscall_func 367*8d67ca89SAndroid Build Coastguard Worker else: 368*8d67ca89SAndroid Build Coastguard Worker if pos_colon == 0 or pos_colon+1 >= len(syscall_func): 369*8d67ca89SAndroid Build Coastguard Worker E("misplaced colon in '%s'" % line) 370*8d67ca89SAndroid Build Coastguard Worker return 371*8d67ca89SAndroid Build Coastguard Worker 372*8d67ca89SAndroid Build Coastguard Worker # now find if there is a socketcall_id for a dispatch-type syscall 373*8d67ca89SAndroid Build Coastguard Worker # after the optional 2nd colon 374*8d67ca89SAndroid Build Coastguard Worker pos_colon2 = syscall_func.find(':', pos_colon + 1) 375*8d67ca89SAndroid Build Coastguard Worker if pos_colon2 < 0: 376*8d67ca89SAndroid Build Coastguard Worker syscall_name = syscall_func[pos_colon+1:] 377*8d67ca89SAndroid Build Coastguard Worker syscall_func = syscall_func[:pos_colon] 378*8d67ca89SAndroid Build Coastguard Worker else: 379*8d67ca89SAndroid Build Coastguard Worker if pos_colon2+1 >= len(syscall_func): 380*8d67ca89SAndroid Build Coastguard Worker E("misplaced colon2 in '%s'" % line) 381*8d67ca89SAndroid Build Coastguard Worker return 382*8d67ca89SAndroid Build Coastguard Worker syscall_name = syscall_func[(pos_colon+1):pos_colon2] 383*8d67ca89SAndroid Build Coastguard Worker socketcall_id = int(syscall_func[pos_colon2+1:]) 384*8d67ca89SAndroid Build Coastguard Worker syscall_func = syscall_func[:pos_colon] 385*8d67ca89SAndroid Build Coastguard Worker 386*8d67ca89SAndroid Build Coastguard Worker alias_delim = syscall_func.find('|') 387*8d67ca89SAndroid Build Coastguard Worker if alias_delim > 0: 388*8d67ca89SAndroid Build Coastguard Worker alias_list = syscall_func[alias_delim+1:].strip() 389*8d67ca89SAndroid Build Coastguard Worker syscall_func = syscall_func[:alias_delim] 390*8d67ca89SAndroid Build Coastguard Worker alias_delim = syscall_name.find('|') 391*8d67ca89SAndroid Build Coastguard Worker if alias_delim > 0: 392*8d67ca89SAndroid Build Coastguard Worker syscall_name = syscall_name[:alias_delim] 393*8d67ca89SAndroid Build Coastguard Worker syscall_aliases = alias_list.split(',') 394*8d67ca89SAndroid Build Coastguard Worker else: 395*8d67ca89SAndroid Build Coastguard Worker syscall_aliases = [] 396*8d67ca89SAndroid Build Coastguard Worker 397*8d67ca89SAndroid Build Coastguard Worker if pos_rparen > pos_lparen+1: 398*8d67ca89SAndroid Build Coastguard Worker syscall_params = line[pos_lparen+1:pos_rparen].split(',') 399*8d67ca89SAndroid Build Coastguard Worker params = ','.join(syscall_params) 400*8d67ca89SAndroid Build Coastguard Worker else: 401*8d67ca89SAndroid Build Coastguard Worker syscall_params = [] 402*8d67ca89SAndroid Build Coastguard Worker params = "void" 403*8d67ca89SAndroid Build Coastguard Worker 404*8d67ca89SAndroid Build Coastguard Worker t = { 405*8d67ca89SAndroid Build Coastguard Worker "name" : syscall_name, 406*8d67ca89SAndroid Build Coastguard Worker "func" : syscall_func, 407*8d67ca89SAndroid Build Coastguard Worker "aliases" : syscall_aliases, 408*8d67ca89SAndroid Build Coastguard Worker "params" : syscall_params, 409*8d67ca89SAndroid Build Coastguard Worker "decl" : "%-15s %s (%s);" % (return_type, syscall_func, params), 410*8d67ca89SAndroid Build Coastguard Worker "socketcall_id" : socketcall_id 411*8d67ca89SAndroid Build Coastguard Worker } 412*8d67ca89SAndroid Build Coastguard Worker 413*8d67ca89SAndroid Build Coastguard Worker # Parse the architecture list. 414*8d67ca89SAndroid Build Coastguard Worker arch_list = line[pos_rparen+1:].strip() 415*8d67ca89SAndroid Build Coastguard Worker if arch_list == "all": 416*8d67ca89SAndroid Build Coastguard Worker for arch in SupportedArchitectures: 417*8d67ca89SAndroid Build Coastguard Worker t[arch] = True 418*8d67ca89SAndroid Build Coastguard Worker else: 419*8d67ca89SAndroid Build Coastguard Worker for arch in arch_list.split(','): 420*8d67ca89SAndroid Build Coastguard Worker if arch == "lp32": 421*8d67ca89SAndroid Build Coastguard Worker for arch in SupportedArchitectures: 422*8d67ca89SAndroid Build Coastguard Worker if "64" not in arch: 423*8d67ca89SAndroid Build Coastguard Worker t[arch] = True 424*8d67ca89SAndroid Build Coastguard Worker elif arch == "lp64": 425*8d67ca89SAndroid Build Coastguard Worker for arch in SupportedArchitectures: 426*8d67ca89SAndroid Build Coastguard Worker if "64" in arch: 427*8d67ca89SAndroid Build Coastguard Worker t[arch] = True 428*8d67ca89SAndroid Build Coastguard Worker elif arch in SupportedArchitectures: 429*8d67ca89SAndroid Build Coastguard Worker t[arch] = True 430*8d67ca89SAndroid Build Coastguard Worker else: 431*8d67ca89SAndroid Build Coastguard Worker E("invalid syscall architecture '%s' in '%s'" % (arch, line)) 432*8d67ca89SAndroid Build Coastguard Worker return 433*8d67ca89SAndroid Build Coastguard Worker 434*8d67ca89SAndroid Build Coastguard Worker self.syscalls.append(t) 435*8d67ca89SAndroid Build Coastguard Worker 436*8d67ca89SAndroid Build Coastguard Worker def parse_open_file(self, fp): 437*8d67ca89SAndroid Build Coastguard Worker for line in fp: 438*8d67ca89SAndroid Build Coastguard Worker self.lineno += 1 439*8d67ca89SAndroid Build Coastguard Worker line = line.strip() 440*8d67ca89SAndroid Build Coastguard Worker if not line: continue 441*8d67ca89SAndroid Build Coastguard Worker if line[0] == '#': continue 442*8d67ca89SAndroid Build Coastguard Worker self.parse_line(line) 443*8d67ca89SAndroid Build Coastguard Worker if self.errors: 444*8d67ca89SAndroid Build Coastguard Worker sys.exit(1) 445*8d67ca89SAndroid Build Coastguard Worker 446*8d67ca89SAndroid Build Coastguard Worker def parse_file(self, file_path): 447*8d67ca89SAndroid Build Coastguard Worker with open(file_path) as fp: 448*8d67ca89SAndroid Build Coastguard Worker self.parse_open_file(fp) 449*8d67ca89SAndroid Build Coastguard Worker 450*8d67ca89SAndroid Build Coastguard Worker 451*8d67ca89SAndroid Build Coastguard Workerdef main(arch, syscall_file): 452*8d67ca89SAndroid Build Coastguard Worker parser = SysCallsTxtParser() 453*8d67ca89SAndroid Build Coastguard Worker parser.parse_file(syscall_file) 454*8d67ca89SAndroid Build Coastguard Worker 455*8d67ca89SAndroid Build Coastguard Worker for syscall in parser.syscalls: 456*8d67ca89SAndroid Build Coastguard Worker syscall["__NR_name"] = make__NR_name(syscall["name"]) 457*8d67ca89SAndroid Build Coastguard Worker 458*8d67ca89SAndroid Build Coastguard Worker if "arm" in syscall: 459*8d67ca89SAndroid Build Coastguard Worker syscall["asm-arm"] = add_footer(32, arm_genstub(syscall), syscall) 460*8d67ca89SAndroid Build Coastguard Worker 461*8d67ca89SAndroid Build Coastguard Worker if "arm64" in syscall: 462*8d67ca89SAndroid Build Coastguard Worker syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall) 463*8d67ca89SAndroid Build Coastguard Worker 464*8d67ca89SAndroid Build Coastguard Worker if "riscv64" in syscall: 465*8d67ca89SAndroid Build Coastguard Worker syscall["asm-riscv64"] = add_footer(64, riscv64_genstub(syscall), syscall) 466*8d67ca89SAndroid Build Coastguard Worker 467*8d67ca89SAndroid Build Coastguard Worker if "x86" in syscall: 468*8d67ca89SAndroid Build Coastguard Worker if syscall["socketcall_id"] >= 0: 469*8d67ca89SAndroid Build Coastguard Worker syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall) 470*8d67ca89SAndroid Build Coastguard Worker else: 471*8d67ca89SAndroid Build Coastguard Worker syscall["asm-x86"] = add_footer(32, x86_genstub(syscall), syscall) 472*8d67ca89SAndroid Build Coastguard Worker elif syscall["socketcall_id"] >= 0: 473*8d67ca89SAndroid Build Coastguard Worker E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t) 474*8d67ca89SAndroid Build Coastguard Worker return 475*8d67ca89SAndroid Build Coastguard Worker 476*8d67ca89SAndroid Build Coastguard Worker if "x86_64" in syscall: 477*8d67ca89SAndroid Build Coastguard Worker syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall) 478*8d67ca89SAndroid Build Coastguard Worker 479*8d67ca89SAndroid Build Coastguard Worker print("/* Generated by gensyscalls.py. Do not edit. */\n") 480*8d67ca89SAndroid Build Coastguard Worker print("#include <private/bionic_asm.h>\n") 481*8d67ca89SAndroid Build Coastguard Worker for syscall in parser.syscalls: 482*8d67ca89SAndroid Build Coastguard Worker if ("asm-%s" % arch) in syscall: 483*8d67ca89SAndroid Build Coastguard Worker print(syscall["asm-%s" % arch]) 484*8d67ca89SAndroid Build Coastguard Worker 485*8d67ca89SAndroid Build Coastguard Worker if arch == 'arm64': 486*8d67ca89SAndroid Build Coastguard Worker print('\nNOTE_GNU_PROPERTY()\n') 487*8d67ca89SAndroid Build Coastguard Worker 488*8d67ca89SAndroid Build Coastguard Workerif __name__ == "__main__": 489*8d67ca89SAndroid Build Coastguard Worker if len(sys.argv) < 2: 490*8d67ca89SAndroid Build Coastguard Worker print("Usage: gensyscalls.py ARCH SOURCE_FILE") 491*8d67ca89SAndroid Build Coastguard Worker sys.exit(1) 492*8d67ca89SAndroid Build Coastguard Worker 493*8d67ca89SAndroid Build Coastguard Worker arch = sys.argv[1] 494*8d67ca89SAndroid Build Coastguard Worker syscall_file = sys.argv[2] 495*8d67ca89SAndroid Build Coastguard Worker main(arch, syscall_file) 496