zephyr/scripts/gen_kobject_list.py

307 lines
8.7 KiB
Python
Raw Normal View History

kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
#!/usr/bin/env python3
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
import sys
import argparse
import math
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
import os
import struct
from elf_helper import ElfHelper, kobject_to_enum
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
# Keys in this dictionary are structs which should be recognized as kernel
# objects. Values should either be None, or the name of a Kconfig that
# indicates the presence of this object's definition in case it is not
# available in all configurations.
kobjects = {
"k_alert": None,
"k_msgq": None,
"k_mutex": None,
"k_pipe": None,
"k_queue": None,
"k_poll_signal": None,
"k_sem": None,
"k_stack": None,
"k_thread": None,
"k_timer": None,
"_k_thread_stack_element": None,
"net_context": "CONFIG_NETWORKING",
"device": None
}
subsystems = [
"adc_driver_api",
"aio_cmp_driver_api",
"counter_driver_api",
"crypto_driver_api",
"dma_driver_api",
"flash_driver_api",
"gpio_driver_api",
"i2c_driver_api",
"i2s_driver_api",
"ipm_driver_api",
"led_driver_api",
"pinmux_driver_api",
"pwm_driver_api",
"entropy_driver_api",
"rtc_driver_api",
"sensor_driver_api",
"spi_driver_api",
"uart_driver_api",
]
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
header = """%compare-lengths
%define lookup-function-name _k_object_lookup
%language=ANSI-C
%global-table
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
%struct-type
%{
#include <kernel.h>
#include <toolchain.h>
#include <syscall_handler.h>
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
#include <string.h>
%}
struct _k_object;
%%
"""
# Different versions of gperf have different prototypes for the lookup
# function, best to implement the wrapper here. The pointer value itself is
# turned into a string, we told gperf to expect binary strings that are not
# NULL-terminated.
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
footer = """%%
struct _k_object *_k_object_gperf_find(void *obj)
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
{
return _k_object_lookup((const char *)obj, sizeof(void *));
}
void _k_object_gperf_wordlist_foreach(_wordlist_cb_func_t func, void *context)
{
int i;
for (i = MIN_HASH_VALUE; i <= MAX_HASH_VALUE; i++) {
if (wordlist[i].name) {
func(&wordlist[i], context);
}
}
}
#ifndef CONFIG_DYNAMIC_OBJECTS
struct _k_object *_k_object_find(void *obj)
ALIAS_OF(_k_object_gperf_find);
void _k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context)
ALIAS_OF(_k_object_gperf_wordlist_foreach);
#endif
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
"""
def write_gperf_table(fp, eh, objs, static_begin, static_end):
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
fp.write(header)
# Setup variables for mapping thread indexes
syms = eh.get_symbols()
thread_max_bytes = syms["CONFIG_MAX_THREAD_BYTES"]
thread_idx_map = {}
for i in range(0, thread_max_bytes):
thread_idx_map[i] = 0xFF
for obj_addr, ko in objs.items():
obj_type = ko.type_name
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
# pre-initialized objects fall within this memory range, they are
# either completely initialized at build time, or done automatically
# at boot during some PRE_KERNEL_* phase
initialized = obj_addr >= static_begin and obj_addr < static_end
byte_str = struct.pack("<I" if eh.little_endian else ">I", obj_addr)
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
fp.write("\"")
for byte in byte_str:
val = "\\x%02x" % byte
fp.write(val)
fp.write(
"\",{},%s,%s,%d\n" %
(obj_type,
"K_OBJ_FLAG_INITIALIZED" if initialized else "0",
ko.data))
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
if obj_type == "K_OBJ_THREAD":
idx = math.floor(ko.data / 8)
bit = ko.data % 8
thread_idx_map[idx] = thread_idx_map[idx] & ~(2**bit)
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
fp.write(footer)
# Generate the array of already mapped thread indexes
fp.write('\n')
fp.write('u8_t _thread_idx_map[%d] = {' % (thread_max_bytes))
for i in range(0, thread_max_bytes):
fp.write(' 0x%x, ' % (thread_idx_map[i]))
fp.write('};\n')
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
driver_macro_tpl = """
#define Z_SYSCALL_DRIVER_%(driver_upper)s(ptr, op) Z_SYSCALL_DRIVER_GEN(ptr, op, %(driver_lower)s, %(driver_upper)s)
"""
def write_validation_output(fp):
fp.write("#ifndef __DRIVER_VALIDATION_GEN_H__\n")
fp.write("#define __DRIVER_VALIDATION_GEN_H__\n")
fp.write("""#define Z_SYSCALL_DRIVER_GEN(ptr, op, driver_lower_case, driver_upper_case) \\
(Z_SYSCALL_OBJ(ptr, K_OBJ_DRIVER_##driver_upper_case) || \\
Z_SYSCALL_DRIVER_OP(ptr, driver_lower_case##_driver_api, op))
""")
for subsystem in subsystems:
subsystem = subsystem.replace("_driver_api", "")
fp.write(driver_macro_tpl % {
"driver_lower": subsystem.lower(),
"driver_upper": subsystem.upper(),
})
fp.write("#endif /* __DRIVER_VALIDATION_GEN_H__ */\n")
def write_kobj_types_output(fp):
fp.write("/* Core kernel objects */\n")
for kobj, dep in kobjects.items():
if kobj == "device":
continue
if dep:
fp.write("#ifdef %s\n" % dep)
fp.write("%s,\n" % kobject_to_enum(kobj))
if dep:
fp.write("#endif\n")
fp.write("/* Driver subsystems */\n")
for subsystem in subsystems:
subsystem = subsystem.replace("_driver_api", "").upper()
fp.write("K_OBJ_DRIVER_%s,\n" % subsystem)
def write_kobj_otype_output(fp):
fp.write("/* Core kernel objects */\n")
for kobj, dep in kobjects.items():
if kobj == "device":
continue
if dep:
fp.write("#ifdef %s\n" % dep)
fp.write('case %s: ret = "%s"; break;\n' %
(kobject_to_enum(kobj), kobj))
if dep:
fp.write("#endif\n")
fp.write("/* Driver subsystems */\n")
for subsystem in subsystems:
subsystem = subsystem.replace("_driver_api", "")
fp.write('case K_OBJ_DRIVER_%s: ret = "%s driver"; break;\n' % (
subsystem.upper(),
subsystem
))
def write_kobj_size_output(fp):
fp.write("/* Non device/stack objects */\n")
for kobj, dep in kobjects.items():
# device handled by default case. Stacks are not currently handled,
# if they eventually are it will be a special case.
if kobj == "device" or kobj == "_k_thread_stack_element":
continue
if dep:
fp.write("#ifdef %s\n" % dep)
fp.write('case %s: ret = sizeof(struct %s); break;\n' %
(kobject_to_enum(kobj), kobj))
if dep:
fp.write("#endif\n")
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
def parse_args():
global args
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
parser.add_argument("-k", "--kernel", required=False,
help="Input zephyr ELF binary")
parser.add_argument(
"-g", "--gperf-output", required=False,
help="Output list of kernel object addresses for gperf use")
parser.add_argument(
"-V", "--validation-output", required=False,
help="Output driver validation macros")
parser.add_argument(
"-K", "--kobj-types-output", required=False,
help="Output k_object enum values")
parser.add_argument(
"-S", "--kobj-otype-output", required=False,
help="Output case statements for otype_to_str()")
parser.add_argument(
"-Z", "--kobj-size-output", required=False,
help="Output case statements for obj_size_get()")
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
parser.add_argument("-v", "--verbose", action="store_true",
help="Print extra debugging information")
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
args = parser.parse_args()
if "VERBOSE" in os.environ:
args.verbose = 1
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
def main():
parse_args()
if args.gperf_output:
eh = ElfHelper(args.kernel, args.verbose, kobjects, subsystems)
syms = eh.get_symbols()
max_threads = syms["CONFIG_MAX_THREAD_BYTES"] * 8
objs = eh.find_kobjects(syms)
thread_counter = eh.get_thread_counter()
if thread_counter > max_threads:
sys.stderr.write("Too many thread objects (%d)\n" % thread_counter)
sys.stderr.write("Increase CONFIG_MAX_THREAD_BYTES to %d\n",
-(-thread_counter // 8))
sys.exit(1)
with open(args.gperf_output, "w") as fp:
write_gperf_table(fp, eh, objs,
syms["_static_kernel_objects_begin"],
syms["_static_kernel_objects_end"])
if args.validation_output:
with open(args.validation_output, "w") as fp:
write_validation_output(fp)
if args.kobj_types_output:
with open(args.kobj_types_output, "w") as fp:
write_kobj_types_output(fp)
if args.kobj_otype_output:
with open(args.kobj_otype_output, "w") as fp:
write_kobj_otype_output(fp)
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
if args.kobj_size_output:
with open(args.kobj_size_output, "w") as fp:
write_kobj_size_output(fp)
kernel: introduce object validation mechanism All system calls made from userspace which involve pointers to kernel objects (including device drivers) will need to have those pointers validated; userspace should never be able to crash the kernel by passing it garbage. The actual validation with _k_object_validate() will be in the system call receiver code, which doesn't exist yet. - CONFIG_USERSPACE introduced. We are somewhat far away from having an end-to-end implementation, but at least need a Kconfig symbol to guard the incoming code with. Formal documentation doesn't exist yet either, but will appear later down the road once the implementation is mostly finalized. - In the memory region for RAM, the data section has been moved last, past bss and noinit. This ensures that inserting generated tables with addresses of kernel objects does not change the addresses of those objects (which would make the table invalid) - The DWARF debug information in the generated ELF binary is parsed to fetch the locations of all kernel objects and pass this to gperf to create a perfect hash table of their memory addresses. - The generated gperf code doesn't know that we are exclusively working with memory addresses and uses memory inefficently. A post-processing script process_gperf.py adjusts the generated code before it is compiled to work with pointer values directly and not strings containing them. - _k_object_init() calls inserted into the init functions for the set of kernel object types we are going to support so far Issue: ZEP-2187 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-22 22:15:23 +02:00
if __name__ == "__main__":
main()