forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen_priv_stacks.py
executable file
·123 lines (93 loc) · 3.08 KB
/
gen_priv_stacks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python3
#
# Copyright (c) 2017 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
import sys
import argparse
import pprint
import os
import struct
from elf_helper import ElfHelper
kobjects = [
"k_stack",
"_k_thread_stack_element",
]
header = """%compare-lengths
%define lookup-function-name _k_priv_stack_map_lookup
%language=ANSI-C
%global-table
%struct-type
"""
priv_stack_decl_temp = ("static u8_t __used"
" __aligned(CONFIG_PRIVILEGED_STACK_SIZE)"
" priv_stack_%x[CONFIG_PRIVILEGED_STACK_SIZE];\n")
priv_stack_decl_size = "CONFIG_PRIVILEGED_STACK_SIZE"
includes = """#include <kernel.h>
#include <string.h>
"""
structure = """struct _k_priv_stack_map {
char *name;
u8_t *priv_stack_addr;
};
%%
"""
# 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.
footer = """%%
u8_t *_k_priv_stack_find(void *obj)
{
const struct _k_priv_stack_map *map =
_k_priv_stack_map_lookup((const char *)obj, sizeof(void *));
return map->priv_stack_addr;
}
"""
def write_gperf_table(fp, eh, objs, static_begin, static_end):
fp.write(header)
# priv stack declarations
fp.write("%{\n")
fp.write(includes)
for obj_addr, ko in objs.items():
fp.write(priv_stack_decl_temp % (obj_addr))
fp.write("%}\n")
# structure declaration
fp.write(structure)
for obj_addr, ko in objs.items():
byte_str = struct.pack("<I" if eh.little_endian else ">I", obj_addr)
fp.write("\"")
for byte in byte_str:
val = "\\x%02x" % byte
fp.write(val)
fp.write("\",priv_stack_%x\n" % obj_addr)
fp.write(footer)
def parse_args():
global args
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("-k", "--kernel", required=True,
help="Input zephyr ELF binary")
parser.add_argument(
"-o", "--output", required=True,
help="Output list of kernel object addresses for gperf use")
parser.add_argument("-v", "--verbose", action="store_true",
help="Print extra debugging information")
args = parser.parse_args()
def main():
parse_args()
eh = ElfHelper(args.kernel, args.verbose, kobjects, [])
syms = eh.get_symbols()
max_threads = syms["CONFIG_MAX_THREAD_BYTES"] * 8
objs = eh.find_kobjects(syms)
if eh.get_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.output, "w") as fp:
write_gperf_table(fp, eh, objs, syms["_static_kernel_objects_begin"],
syms["_static_kernel_objects_end"])
if __name__ == "__main__":
main()