1 #!/usr/bin/python 2 # 3 # Copyright 2017 - The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 """Generates a report on CKI syscall coverage in VTS LTP. 19 20 This module generates a report on the syscalls in the Android CKI and 21 their coverage in VTS LTP. 22 23 The coverage report provides, for each syscall in the CKI, the number of 24 enabled and disabled LTP tests for the syscall in VTS. If VTS test output is 25 supplied, the report instead provides the number of disabled, skipped, failing, 26 and passing tests for each syscall. 27 28 Assumptions are made about the structure of files in LTP source 29 and the naming convention. 30 """ 31 32 import argparse 33 import os.path 34 import re 35 import sys 36 import xml.etree.ElementTree as ET 37 import subprocess 38 39 if "ANDROID_BUILD_TOP" not in os.environ: 40 print ("Please set up your Android build environment by running " 41 "\". build/envsetup.sh\" and \"lunch\".") 42 sys.exit(-1) 43 44 sys.path.append(os.path.join(os.environ["ANDROID_BUILD_TOP"], 45 "bionic/libc/tools")) 46 import gensyscalls 47 48 sys.path.append(os.path.join(os.environ["ANDROID_BUILD_TOP"], 49 "test/vts-testcase/kernel/ltp/configs")) 50 import disabled_tests as vts_disabled 51 import stable_tests as vts_stable 52 53 bionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc") 54 55 src_url_start = 'https://git.kernel.org/pub/scm/linux/kernel/git/' 56 tip_url = 'torvalds/linux.git/plain/' 57 stable_url = 'stable/linux.git/plain/' 58 unistd_h = 'include/uapi/asm-generic/unistd.h' 59 arm64_unistd32_h = 'arch/arm64/include/asm/unistd32.h' 60 arm_syscall_tbl = 'arch/arm/tools/syscall.tbl' 61 x86_syscall_tbl = 'arch/x86/entry/syscalls/syscall_32.tbl' 62 x86_64_syscall_tbl = 'arch/x86/entry/syscalls/syscall_64.tbl' 63 64 unistd_h_url = src_url_start 65 arm64_unistd32_h_url = src_url_start 66 arm_syscall_tbl_url = src_url_start 67 x86_syscall_tbl_url = src_url_start 68 x86_64_syscall_tbl_url = src_url_start 69 70 # Syscalls which are either banned, optional, or deprecated, so not part of the 71 # CKI. 72 CKI_BLACKLIST = [ 73 'acct', # CONFIG_BSD_PROCESS_ACCT 74 'fanotify_init', # CONFIG_FANOTIFY 75 'fanotify_mark', # CONFIG_FANOTIFY 76 'get_mempolicy', # CONFIG_NUMA 77 'init_module', # b/112470257 (use finit_module) 78 'ipc', # CONFIG_SYSVIPC 79 'kcmp', # CONFIG_CHECKPOINT_RESTORE 80 'kexec_file_load', # CONFIG_EXEC_FILE 81 'kexec_load', # CONFIG_KEXEC 82 'lookup_dcookie', # b/112474343 (requires kernel module) 83 'mbind', # CONFIG_NUMA 84 'membarrier', # CONFIG_MEMBARRIER 85 'migrate_pages', # CONFIG_NUMA 86 'move_pages', # CONFIG_MIGRATION 87 'mq_getsetattr', # CONFIG_POSIX_MQUEUE 88 'mq_notify', # CONFIG_POSIX_MQUEUE 89 'mq_open', # CONFIG_POSIX_MQUEUE 90 'mq_timedreceive', # CONFIG_POSIX_MQUEUE 91 'mq_timedsend', # CONFIG_POSIX_MQUEUE 92 'mq_unlink', # CONFIG_POSIX_MQUEUE 93 'msgctl', # CONFIG_SYSVIPC 94 'msgget', # CONFIG_SYSVIPC 95 'msgrcv', # CONFIG_SYSVIPC 96 'msgsnd', # CONFIG_SYSVIPC 97 'name_to_handle_at', # CONFIG_FHANDLE 98 'nfsservctl', # not present after 3.1 99 'open_by_handle_at', # CONFIG_FHANDLE 100 'pciconfig_iobase', # not present for arm/x86 101 'pciconfig_read', # CONFIG_PCI_SYSCALL 102 'pciconfig_write', # CONFIG_PCI_SYSCALL 103 'pkey_alloc', # CONFIG_MMU, added in 4.9 104 'pkey_free', # CONFIG_MMU, added in 4.9 105 'pkey_mprotect', # CONFIG_MMU, added in 4.9 106 'rseq', # CONFIG_RSEQ 107 'semctl', # CONFIG_SYSVIPC 108 'semget', # CONFIG_SYSVIPC 109 'semop', # CONFIG_SYSVIPC 110 'semtimedop', # CONFIG_SYSVIPC 111 'set_mempolicy', # CONFIG_NUMA 112 'sgetmask', # CONFIG_SGETMASK_SYSCALL 113 'shmat', # CONFIG_SYSVIPC 114 'shmctl', # CONFIG_SYSVIPC 115 'shmdt', # CONFIG_SYSVIPC 116 'shmget', # CONFIG_SYSVIPC 117 'ssetmask', # CONFIG_SGETMASK_SYSCALL 118 'stime', # deprecated 119 'syscall', # deprecated 120 '_sysctl', # CONFIG_SYSCTL_SYSCALL 121 'sysfs', # CONFIG_SYSFS_SYSCALL 122 'uselib', # CONFIG_USELIB 123 'userfaultfd', # CONFIG_USERFAULTFD 124 'vm86', # CONFIG_X86_LEGACY_VM86 125 'vm86old', # CONFIG_X86_LEGACY_VM86 126 'vserver', # deprecated 127 ] 128 129 EXTERNAL_TESTS = [ ("bpf", "libbpf_android/BpfLoadTest.cpp"), 130 ("bpf", "libbpf_android/BpfMapTest.cpp"), 131 ("bpf", "netd/libbpf/BpfMapTest.cpp"), 132 ("bpf", "api/bpf_native_test/BpfTest.cpp"), 133 ("clock_adjtime", "kselftest/timers/valid-adjtimex.c"), 134 ("seccomp", "kselftest/seccomp_bpf") 135 ] 136 137 class CKI_Coverage(object): 138 """Determines current test coverage of CKI system calls in LTP. 139 140 Many of the system calls in the CKI are tested by LTP. For a given 141 system call an LTP test may or may not exist, that LTP test may or may 142 not be currently compiling properly for Android, the test may not be 143 stable, the test may not be running due to environment issues or 144 passing. This class looks at various sources of information to determine 145 the current test coverage of system calls in the CKI from LTP. 146 147 Note that due to some deviations in LTP of tests from the common naming 148 convention there there may be tests that are flagged here as not having 149 coverage when in fact they do. 150 """ 151 152 LTP_KERNEL_ROOT = os.path.join(os.environ["ANDROID_BUILD_TOP"], 153 "external/ltp/testcases/kernel") 154 LTP_KERNEL_TESTSUITES = ["syscalls", "timers"] 155 DISABLED_IN_LTP_PATH = os.path.join(os.environ["ANDROID_BUILD_TOP"], 156 "external/ltp/android/tools/disabled_tests.txt") 157 158 ltp_full_set = [] 159 160 cki_syscalls = [] 161 162 disabled_in_ltp = [] 163 disabled_in_vts_ltp = vts_disabled.DISABLED_TESTS 164 stable_in_vts_ltp = vts_stable.STABLE_TESTS 165 166 syscall_tests = {} 167 disabled_tests = {} 168 169 def __init__(self, arch): 170 self._arch = arch 171 172 def load_ltp_tests(self): 173 """Load the list of LTP syscall tests. 174 175 Load the list of all syscall tests existing in LTP. 176 """ 177 for testsuite in self.LTP_KERNEL_TESTSUITES: 178 self.__load_ltp_testsuite(testsuite) 179 180 def __load_ltp_testsuite(self, testsuite): 181 root = os.path.join(self.LTP_KERNEL_ROOT, testsuite) 182 for path, dirs, files in os.walk(root): 183 for filename in files: 184 basename, ext = os.path.splitext(filename) 185 if ext != ".c": continue 186 self.ltp_full_set.append("%s.%s" % (testsuite, basename)) 187 188 def load_ltp_disabled_tests(self): 189 """Load the list of LTP tests not being compiled. 190 191 The LTP repository in Android contains a list of tests which are not 192 compiled due to incompatibilities with Android. 193 """ 194 with open(self.DISABLED_IN_LTP_PATH) as fp: 195 for line in fp: 196 line = line.strip() 197 if not line: continue 198 test_re = re.compile(r"^(\w+)") 199 test_match = re.match(test_re, line) 200 if not test_match: continue 201 self.disabled_in_ltp.append(test_match.group(1)) 202 203 def ltp_test_special_cases(self, syscall, test): 204 """Detect special cases in syscall to LTP mapping. 205 206 Most syscall tests in LTP follow a predictable naming 207 convention, but some do not. Detect known special cases. 208 209 Args: 210 syscall: The name of a syscall. 211 test: The name of a testcase. 212 213 Returns: 214 A boolean indicating whether the given syscall is tested 215 by the given testcase. 216 """ 217 compat_syscalls = [ "chown32", "fchown32", "getegid32", "geteuid32", 218 "getgid32", "getgroups32", "getresgid32", "getresuid32", 219 "getuid32", "lchown32", "setfsgid32", "setfsuid32", "setgid32", 220 "setgroups32", "setregid32", "setresgid32", "setresuid32", 221 "setreuid32", "setuid32"] 222 if syscall in compat_syscalls: 223 test_re = re.compile(r"^%s\d+$" % syscall[0:-2]) 224 if re.match(test_re, test): 225 return True 226 if syscall == "_llseek" and test.startswith("llseek"): 227 return True 228 if syscall in ("arm_fadvise64_", "fadvise64_") and \ 229 test.startswith("posix_fadvise"): 230 return True 231 if syscall in ("arm_sync_file_range", "sync_file_range2") and \ 232 test.startswith("sync_file_range"): 233 return True 234 if syscall == "clock_nanosleep" and test == "clock_nanosleep2_01": 235 return True 236 if syscall in ("epoll_ctl", "epoll_create") and test == "epoll-ltp": 237 return True 238 if syscall == "futex" and test.startswith("futex_"): 239 return True 240 if syscall == "get_thread_area" and test == "set_thread_area01": 241 return True 242 if syscall == "inotify_add_watch" or syscall == "inotify_rm_watch": 243 test_re = re.compile(r"^inotify\d+$") 244 if re.match(test_re, test): 245 return True 246 inotify_init_tests = [ "inotify01", "inotify02", "inotify03", "inotify04" ] 247 if syscall == "inotify_init" and test in inotify_init_tests: 248 return True 249 if syscall == "lsetxattr" and test.startswith("lgetxattr"): 250 return True 251 if syscall == "newfstatat": 252 test_re = re.compile(r"^fstatat\d+$") 253 if re.match(test_re, test): 254 return True 255 if syscall in ("prlimit", "ugetrlimit") and test == "getrlimit03": 256 return True 257 if syscall == "rt_sigtimedwait" and test == "sigwaitinfo01": 258 return True 259 shutdown_tests = [ "send01", "sendmsg01", "sendto01" ] 260 if syscall == "shutdown" and test in shutdown_tests: 261 return True 262 263 return False 264 265 def match_syscalls_to_tests(self, syscalls): 266 """Match syscalls with tests in LTP. 267 268 Create a mapping from CKI syscalls and tests in LTP. This mapping can 269 largely be determined using a common naming convention in the LTP file 270 hierarchy but there are special cases that have to be taken care of. 271 272 Args: 273 syscalls: List of syscall structures containing all syscalls 274 in the CKI. 275 """ 276 for syscall in syscalls: 277 if self._arch is not None and self._arch not in syscall: 278 continue 279 self.cki_syscalls.append(syscall) 280 self.syscall_tests[syscall["name"]] = [] 281 # LTP does not use the 64 at the end of syscall names for testcases. 282 ltp_syscall_name = syscall["name"] 283 if ltp_syscall_name.endswith("64"): 284 ltp_syscall_name = ltp_syscall_name[0:-2] 285 # Most LTP syscalls have source files for the tests that follow 286 # a naming convention in the regexp below. Exceptions exist though. 287 # For now those are checked for specifically. 288 test_re = re.compile(r"^%s_?0?\d\d?$" % ltp_syscall_name) 289 for full_test_name in self.ltp_full_set: 290 testsuite, test = full_test_name.split('.') 291 if (re.match(test_re, test) or 292 self.ltp_test_special_cases(ltp_syscall_name, test)): 293 # The filenames of the ioctl tests in LTP do not match the name 294 # of the testcase defined in that source, which is what shows 295 # up in VTS. 296 if testsuite == "syscalls" and ltp_syscall_name == "ioctl": 297 full_test_name = "syscalls.ioctl01_02" 298 # Likewise LTP has a test named epoll01, which is built as an 299 # executable named epoll-ltp, and tests the epoll_{create,ctl} 300 # syscalls. 301 if full_test_name == "syscalls.epoll-ltp": 302 full_test_name = "syscalls.epoll01" 303 self.syscall_tests[syscall["name"]].append(full_test_name) 304 for e in EXTERNAL_TESTS: 305 if e[0] == syscall["name"]: 306 self.syscall_tests[syscall["name"]].append(e[1]) 307 self.cki_syscalls.sort(key=lambda tup: tup["name"]) 308 309 def update_test_status(self): 310 """Populate test configuration and output for all CKI syscalls. 311 312 Go through VTS test configuration to populate data for all CKI syscalls. 313 """ 314 for syscall in self.cki_syscalls: 315 self.disabled_tests[syscall["name"]] = [] 316 if not self.syscall_tests[syscall["name"]]: 317 continue 318 for full_test_name in self.syscall_tests[syscall["name"]]: 319 if full_test_name in [t[1] for t in EXTERNAL_TESTS]: 320 continue 321 _, test = full_test_name.split('.') 322 # The VTS LTP stable list is composed of tuples of the test name and 323 # a boolean flag indicating whether it is mandatory. 324 stable_vts_ltp_testnames = [i[0] for i in self.stable_in_vts_ltp] 325 if (test in self.disabled_in_ltp or 326 full_test_name in self.disabled_in_vts_ltp or 327 ("%s_32bit" % full_test_name not in stable_vts_ltp_testnames and 328 "%s_64bit" % full_test_name not in stable_vts_ltp_testnames)): 329 self.disabled_tests[syscall["name"]].append(full_test_name) 330 continue 331 332 def syscall_arch_string(self, syscall, arch): 333 """Return a string showing whether the arch supports the given syscall.""" 334 if arch not in syscall or not syscall[arch]: 335 return " " 336 else: 337 return "*" 338 339 def output_results(self): 340 """Pretty print the CKI syscall LTP coverage.""" 341 count = 0 342 uncovered = 0 343 344 print "" 345 print " Covered Syscalls" 346 for syscall in self.cki_syscalls: 347 if (len(self.syscall_tests[syscall["name"]]) - 348 len(self.disabled_tests[syscall["name"]]) <= 0): 349 continue 350 if not count % 20: 351 print ("%25s Disabled Enabled arm64 arm x86_64 x86 -----------" % 352 "-------------") 353 enabled = (len(self.syscall_tests[syscall["name"]]) - 354 len(self.disabled_tests[syscall["name"]])) 355 if enabled > 9: 356 column_sp = " " 357 else: 358 column_sp = " " 359 sys.stdout.write("%25s %s %s%s%s %s %s %s\n" % 360 (syscall["name"], len(self.disabled_tests[syscall["name"]]), 361 enabled, column_sp, 362 self.syscall_arch_string(syscall, "arm64"), 363 self.syscall_arch_string(syscall, "arm"), 364 self.syscall_arch_string(syscall, "x86_64"), 365 self.syscall_arch_string(syscall, "x86"))) 366 count += 1 367 368 count = 0 369 print "\n" 370 print " Uncovered Syscalls" 371 for syscall in self.cki_syscalls: 372 if (len(self.syscall_tests[syscall["name"]]) - 373 len(self.disabled_tests[syscall["name"]]) > 0): 374 continue 375 if not count % 20: 376 print ("%25s Disabled Enabled arm64 arm x86_64 x86 -----------" % 377 "-------------") 378 enabled = (len(self.syscall_tests[syscall["name"]]) - 379 len(self.disabled_tests[syscall["name"]])) 380 if enabled > 9: 381 column_sp = " " 382 else: 383 column_sp = " " 384 sys.stdout.write("%25s %s %s%s%s %s %s %s\n" % 385 (syscall["name"], len(self.disabled_tests[syscall["name"]]), 386 enabled, column_sp, 387 self.syscall_arch_string(syscall, "arm64"), 388 self.syscall_arch_string(syscall, "arm"), 389 self.syscall_arch_string(syscall, "x86_64"), 390 self.syscall_arch_string(syscall, "x86"))) 391 uncovered += 1 392 count += 1 393 394 print "" 395 print ("Total uncovered syscalls: %s out of %s" % 396 (uncovered, len(self.cki_syscalls))) 397 398 def output_summary(self): 399 """Print a one line summary of the CKI syscall LTP coverage. 400 401 Pretty prints a one line summary of the CKI syscall coverage in LTP 402 for the specified architecture. 403 """ 404 uncovered_with_test = 0 405 uncovered_without_test = 0 406 for syscall in self.cki_syscalls: 407 if (len(self.syscall_tests[syscall["name"]]) - 408 len(self.disabled_tests[syscall["name"]]) > 0): 409 continue 410 if (len(self.disabled_tests[syscall["name"]]) > 0): 411 uncovered_with_test += 1 412 else: 413 uncovered_without_test += 1 414 print ("arch, cki syscalls, uncovered with disabled test(s), " 415 "uncovered with no tests, total uncovered") 416 print ("%s, %s, %s, %s, %s" % (self._arch, len(self.cki_syscalls), 417 uncovered_with_test, uncovered_without_test, 418 uncovered_with_test + uncovered_without_test)) 419 420 def add_syscall(self, cki, syscall, arch): 421 """Note that a syscall has been seen for a particular arch.""" 422 seen = False 423 for s in cki.syscalls: 424 if s["name"] == syscall: 425 s[arch]= True 426 seen = True 427 break 428 if not seen: 429 cki.syscalls.append({"name":syscall, arch:True}) 430 431 def delete_syscall(self, cki, syscall): 432 cki.syscalls = list(filter(lambda i: i["name"] != syscall, cki.syscalls)) 433 434 def check_blacklist(self, cki, error_on_match): 435 unlisted_syscalls = [] 436 for s in cki.syscalls: 437 if s["name"] in CKI_BLACKLIST: 438 if error_on_match: 439 print "Syscall %s found in both bionic CKI and blacklist!" % s["name"] 440 sys.exit() 441 else: 442 unlisted_syscalls.append(s) 443 cki.syscalls = unlisted_syscalls 444 445 def get_x86_64_kernel_syscalls(self, cki): 446 """Retrieve the list of syscalls for x86_64.""" 447 proc = subprocess.Popen(['curl', x86_64_syscall_tbl_url], stdout=subprocess.PIPE) 448 while True: 449 line = proc.stdout.readline() 450 if line != b'': 451 test_re = re.compile(r"^\d+\s+\w+\s+(\w+)\s+(__x64_sys|__x32_compat_sys)") 452 test_match = re.match(test_re, line) 453 if test_match: 454 syscall = test_match.group(1) 455 self.add_syscall(cki, syscall, "x86_64") 456 else: 457 break 458 459 def get_x86_kernel_syscalls(self, cki): 460 """Retrieve the list of syscalls for x86.""" 461 proc = subprocess.Popen(['curl', x86_syscall_tbl_url], stdout=subprocess.PIPE) 462 while True: 463 line = proc.stdout.readline() 464 if line != b'': 465 test_re = re.compile(r"^\d+\s+i386\s+(\w+)\s+sys_") 466 test_match = re.match(test_re, line) 467 if test_match: 468 syscall = test_match.group(1) 469 self.add_syscall(cki, syscall, "x86") 470 else: 471 break 472 473 def get_arm_kernel_syscalls(self, cki): 474 """Retrieve the list of syscalls for arm.""" 475 proc = subprocess.Popen(['curl', arm_syscall_tbl_url], stdout=subprocess.PIPE) 476 while True: 477 line = proc.stdout.readline() 478 if line != b'': 479 test_re = re.compile(r"^\d+\s+\w+\s+(\w+)\s+sys_") 480 test_match = re.match(test_re, line) 481 if test_match: 482 syscall = test_match.group(1) 483 self.add_syscall(cki, syscall, "arm") 484 else: 485 break 486 487 def get_arm64_kernel_syscalls(self, cki): 488 """Retrieve the list of syscalls for arm64.""" 489 # Add AArch64 syscalls 490 proc = subprocess.Popen(['curl', unistd_h_url], stdout=subprocess.PIPE) 491 while True: 492 line = proc.stdout.readline() 493 if line != b'': 494 test_re = re.compile(r"^#define __NR(3264)?_(\w+)\s+(\d+)$") 495 test_match = re.match(test_re, line) 496 if test_match: 497 syscall = test_match.group(2) 498 if (syscall == "sync_file_range2" or 499 syscall == "arch_specific_syscall" or 500 syscall == "syscalls"): 501 continue 502 self.add_syscall(cki, syscall, "arm64") 503 else: 504 break 505 # Add AArch32 syscalls 506 proc = subprocess.Popen(['curl', arm64_unistd32_h_url], stdout=subprocess.PIPE) 507 while True: 508 line = proc.stdout.readline() 509 if line != b'': 510 test_re = re.compile(r"^#define __NR(3264)?_(\w+)\s+(\d+)$") 511 test_match = re.match(test_re, line) 512 if test_match: 513 syscall = test_match.group(2) 514 self.add_syscall(cki, syscall, "arm64") 515 else: 516 break 517 518 def get_kernel_syscalls(self, cki, arch): 519 self.get_arm64_kernel_syscalls(cki) 520 self.get_arm_kernel_syscalls(cki) 521 self.get_x86_kernel_syscalls(cki) 522 self.get_x86_64_kernel_syscalls(cki) 523 524 # restart_syscall is a special syscall which the kernel issues internally 525 # when a process is resumed with SIGCONT. seccomp whitelists this syscall, 526 # but it is not part of the CKI or meaningfully testable from userspace. 527 # See restart_syscall(2) for more details. 528 self.delete_syscall(cki, "restart_syscall") 529 530 if __name__ == "__main__": 531 parser = argparse.ArgumentParser(description="Output list of system calls " 532 "in the Common Kernel Interface and their VTS LTP coverage.") 533 parser.add_argument("-a", "--arch", help="only show syscall CKI for specific arch") 534 parser.add_argument("-l", action="store_true", 535 help="list CKI syscalls only, without coverage") 536 parser.add_argument("-s", action="store_true", 537 help="print one line summary of CKI coverage for arch") 538 parser.add_argument("-f", action="store_true", 539 help="only check syscalls with known Android use") 540 parser.add_argument("-k", action="store_true", 541 help="use lowest supported kernel version instead of tip") 542 543 args = parser.parse_args() 544 if args.arch is not None and args.arch not in gensyscalls.all_arches: 545 print "Arch must be one of the following:" 546 print gensyscalls.all_arches 547 exit(-1) 548 549 if args.k: 550 minversion = "4.9" 551 print "Checking kernel version %s" % minversion 552 minversion = "?h=v" + minversion 553 unistd_h_url += stable_url + unistd_h + minversion 554 arm64_unistd32_h_url += stable_url + arm64_unistd32_h + minversion 555 arm_syscall_tbl_url += stable_url + arm_syscall_tbl + minversion 556 x86_syscall_tbl_url += stable_url + x86_syscall_tbl + minversion 557 x86_64_syscall_tbl_url += stable_url + x86_64_syscall_tbl + minversion 558 else: 559 unistd_h_url += tip_url + unistd_h 560 arm64_unistd32_h_url += tip_url + arm64_unistd32_h 561 arm_syscall_tbl_url += tip_url + arm_syscall_tbl 562 x86_syscall_tbl_url += tip_url + x86_syscall_tbl 563 x86_64_syscall_tbl_url += tip_url + x86_64_syscall_tbl 564 565 cki = gensyscalls.SysCallsTxtParser() 566 cki_cov = CKI_Coverage(args.arch) 567 568 if args.f: 569 cki.parse_file(os.path.join(bionic_libc_root, "SYSCALLS.TXT")) 570 cki.parse_file(os.path.join(bionic_libc_root, "SECCOMP_WHITELIST_APP.TXT")) 571 cki.parse_file(os.path.join(bionic_libc_root, "SECCOMP_WHITELIST_COMMON.TXT")) 572 cki.parse_file(os.path.join(bionic_libc_root, "SECCOMP_WHITELIST_SYSTEM.TXT")) 573 cki.parse_file(os.path.join(bionic_libc_root, "SECCOMP_WHITELIST_GLOBAL.TXT")) 574 cki_cov.check_blacklist(cki, True) 575 else: 576 cki_cov.get_kernel_syscalls(cki, args.arch) 577 cki_cov.check_blacklist(cki, False) 578 579 if args.l: 580 for syscall in cki.syscalls: 581 if args.arch is None or syscall[args.arch]: 582 print syscall["name"] 583 exit(0) 584 585 cki_cov.load_ltp_tests() 586 cki_cov.load_ltp_disabled_tests() 587 cki_cov.match_syscalls_to_tests(cki.syscalls) 588 cki_cov.update_test_status() 589 590 beta_string = ("*** WARNING: This script is still in development and may\n" 591 "*** report both false positives and negatives.") 592 print beta_string 593 594 if args.s: 595 cki_cov.output_summary() 596 exit(0) 597 598 cki_cov.output_results() 599 print beta_string 600