# Copyright 2013-2017 Google Inc. +All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import re import sys from optparse import OptionParser
"""
Script to generate syscall stubs from a syscall table file with definitions like this:
For e.g.,
DEF_SYSCALL(0x3, read, 3, int fd, void *buf, int size)
DEF_SYSCALL(0x4, write, 4, int fd, void *buf, int size)
FUNCTION(read)
ldr r12, =__NR_read
swi #0
bx lr
FUNCTION(write)
ldr r12, =__NR_write
swi #0
bx lr
Another file with a enumeration of all syscalls is also generated:
#define __NR_read 0x3 #define __NR_write 0x4
...
Only syscalls with4or less arguments are supported. """
copyright_header = """/*
* Copyright (c) 2012-2018 LK Trusty Authors. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF ORIN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ """
autogen_header = """
/* This file is auto-generated. !!! DO NOT EDIT !!! */
"""
clang_format_off = "/* clang-format off */\n\n"
arch_dict = { "arm" : Architecture (
syscall_stub = """
.section .text._trusty_%(sys_fn)s
.arm
.balign 4
FUNCTION(_trusty_%(sys_fn)s)
ldr r12, =__NR_%(sys_fn)s
svc #0
bx lr
.size _trusty_%(sys_fn)s,.-_trusty_%(sys_fn)s """), "arm64" : Architecture ( # Note: for arm64 we're using "mov" to set the syscall number instead of # "ldr" because of an assembler bug. The ldr instruction would always # load from a constant pool instead of encoding the constant in the # instruction. For arm64, "mov" should work for the range of constants # we care about.
syscall_stub = """
.section .text._trusty_%(sys_fn)s
.balign 4
FUNCTION(_trusty_%(sys_fn)s)
mov x12, #__NR_%(sys_fn)s
svc #0
ret
.size _trusty_%(sys_fn)s,.-_trusty_%(sys_fn)s """,
footer = """
SECTION_GNU_NOTE_PROPERTY_AARCH64_FEATURES(GNU_NOTE_FEATURE_AARCH64_BTI) """), "x86" : Architecture (
syscall_stub = """
.global _trusty_%(sys_fn)s
.type _trusty_%(sys_fn)s,STT_FUNC
_trusty_%(sys_fn)s:
pushq %%r15
movq $__NR_%(sys_fn)s, %%rax
movq %%rcx, %%r10
movq %%rsp, %%r15
syscall
movq %%r15, %%rsp
popq %%r15
ret
.size _trusty_%(sys_fn)s,.-_trusty_%(sys_fn)s """),
}
syscall_pat = (
r'DEF_SYSCALL\s*\('
r'\s*(?P<sys_nr>\d+|0x[\da-fA-F]+)\s*,'# syscall nr
r'\s*(?P<sys_fn>\w+)\s*,'# syscall name
r'\s*(?P<sys_rt>[\w*\s]+)\s*,'# return type
r'\s*(?P<sys_nr_args>\d+)\s*'# nr ags
r'('
r'\)\s*$|'# empty arg list or
r',\s*(?P<sys_args>[\w,*\s]+)'# arg list
r'\)\s*$'
r')')
# Find struct types in the arguments. for arg in sys_args_list: # Remove arg name.
arg = re.sub(r"\s*\w+$", "", arg) # Remove trailing pointer.
arg = re.sub(r"\s*\*$", "", arg) # Remove initial const.
arg = re.sub(r"^const\s+", "", arg) # Ignore the type if it's obviously not a struct. if arg in BUILTIN_TYPES: continue # Require explicit struct declarations, because forward declaring # typedefs is tricky. ifnot arg.startswith("struct "):
fatal_parse_error(line, "Not an integer type or explicit struct " "type: %r. Don't use typedefs." % arg)
struct_types.add(arg)
# Reformat arguments into Rust syntax
rust_args = [] try: for arg in sys_args_list:
m = re.match(r"(.*?)(\w+)$", arg)
ty = m.group(1)
name = m.group(2)
rust_args.append('%s: %s' % (name, reformat_c_to_rust(ty)))
gd['rust_args'] = ', '.join(rust_args)
gd['rust_rt'] = reformat_c_to_rust(gd['sys_rt']) except NotImplementedError as err: # reformat_c_to_rust failed to convert argument or return type
fatal_parse_error(line, err)
# In C, a forward declaration with an empty list of arguments has an # unknown number of arguments. Set it to 'void' to declare there are # zero arguments. if sys_nr_args == 0:
gd['sys_args'] = 'void'
return gd
def process_table(table_file, std_file, stubs_file, rust_file, verify, arch): """
Process a syscall table and generate: 1. A sycall stubs file 2. A trusty_std.h header file with syscall definitions and function prototypes """
define_lines = ""
proto_lines = "\n"
stub_lines = ""
rust_lines = ""
struct_types = set()
tbl = open(table_file, "r") for line in tbl:
line = line.strip()
# skip all lines that don't start with a syscall definition # multi-line definitions are not supported. ifnot line.startswith(syscall_def): continue
if std_file isnotNone: with open(std_file, "w") as std:
std.writelines(copyright_header + autogen_header)
std.writelines(clang_format_off)
std.writelines(define_lines + asm_ifdef)
std.writelines("\n")
std.writelines(includes_header % "lk/compiler.h")
std.writelines(includes_header % "stdint.h")
std.writelines(beg_cdecls) # Forward declare the struct types.
std.writelines("\n")
std.writelines([t + ";\n"for t in sorted(struct_types)])
std.writelines(proto_lines + end_cdecls + asm_endif)
if stubs_file isnotNone: with open(stubs_file, "w") as stubs:
stubs.writelines(copyright_header + autogen_header)
stubs.writelines(includes_header % "lk/asm.h")
stubs.writelines(includes_header % "trusty_syscalls.h")
stubs.writelines(stub_lines)
stubs.writelines(arch.footer)
if rust_file isnotNone: with open(rust_file, "w") as rust:
rust.writelines(copyright_header + autogen_header)
rust.writelines(beg_rust)
rust.writelines(rust_lines)
rust.writelines(end_rust)
def main():
usage = "usage: %prog [options] <syscall-table>"
op = OptionParser(usage=usage)
op.add_option("-v", "--verify", action="store_true",
dest="verify", default=False,
help="Check syscall table. Do not generate any files.")
op.add_option("-d", "--std-header", type="string",
dest="std_file", default=None,
help="path to syscall definitions header file.")
op.add_option("-s", "--stubs-file", type="string",
dest="stub_file", default=None,
help="path to syscall assembly stubs file.")
op.add_option("-r", "--rust-file", type="string",
dest="rust_file", default=None,
help="path to rust declarations file")
op.add_option("-a", "--arch", type="string",
dest="arch", default="arm",
help="arch of stub assembly files: " + str(arch_dict.keys()))
(opts, args) = op.parse_args()
if len(args) == 0:
op.print_help()
sys.exit(1)
ifnot opts.verify: if opts.std_file isNoneand opts.stub_file isNone:
op.print_help()
sys.exit(1)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.