blob: 50b1ce51cb0723d64eeb11293209b4e7b6befc0a [file] [log] [blame]
Andrew Boie945af952017-08-22 13:15:23 -07001#!/usr/bin/env python3
2#
3# Copyright (c) 2017 Intel Corporation
4#
5# SPDX-License-Identifier: Apache-2.0
6
7import sys
8import argparse
9import pprint
10import os
11import struct
Andy Gross6042ae92018-01-22 14:26:49 -060012from elf_helper import ElfHelper
Andrew Boie945af952017-08-22 13:15:23 -070013
Andrew Boie5bd891d2017-09-27 12:59:28 -070014kobjects = [
Anas Nashif72565532017-12-12 08:19:25 -050015 "k_alert",
16 "k_msgq",
17 "k_mutex",
18 "k_pipe",
19 "k_sem",
20 "k_stack",
21 "k_thread",
22 "k_timer",
23 "_k_thread_stack_element",
24 "device"
25]
Andrew Boie5bd891d2017-09-27 12:59:28 -070026
27subsystems = [
Anas Nashif72565532017-12-12 08:19:25 -050028 "adc_driver_api",
29 "aio_cmp_driver_api",
30 "counter_driver_api",
31 "crypto_driver_api",
Andrew Boiece6c8f32018-02-09 13:58:37 -080032 "dma_driver_api",
Anas Nashif72565532017-12-12 08:19:25 -050033 "flash_driver_api",
34 "gpio_driver_api",
35 "i2c_driver_api",
36 "i2s_driver_api",
37 "ipm_driver_api",
38 "pinmux_driver_api",
39 "pwm_driver_api",
40 "entropy_driver_api",
41 "rtc_driver_api",
42 "sensor_driver_api",
43 "spi_driver_api",
44 "uart_driver_api",
45]
Andrew Boie5bd891d2017-09-27 12:59:28 -070046
47
Andrew Boie945af952017-08-22 13:15:23 -070048header = """%compare-lengths
49%define lookup-function-name _k_object_lookup
50%language=ANSI-C
Andrew Boie47f8fd12017-10-05 11:11:02 -070051%global-table
Andrew Boie945af952017-08-22 13:15:23 -070052%struct-type
53%{
54#include <kernel.h>
Andrew Boie47f8fd12017-10-05 11:11:02 -070055#include <syscall_handler.h>
Andrew Boie945af952017-08-22 13:15:23 -070056#include <string.h>
57%}
58struct _k_object;
59%%
60"""
61
62
Andy Gross6042ae92018-01-22 14:26:49 -060063# Different versions of gperf have different prototypes for the lookup
64# function, best to implement the wrapper here. The pointer value itself is
65# turned into a string, we told gperf to expect binary strings that are not
Anas Nashif72565532017-12-12 08:19:25 -050066# NULL-terminated.
Andrew Boie945af952017-08-22 13:15:23 -070067footer = """%%
68struct _k_object *_k_object_find(void *obj)
69{
70 return _k_object_lookup((const char *)obj, sizeof(void *));
71}
Andrew Boie47f8fd12017-10-05 11:11:02 -070072
73void _k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context)
74{
75 int i;
76
77 for (i = MIN_HASH_VALUE; i <= MAX_HASH_VALUE; i++) {
78 if (wordlist[i].name) {
79 func(&wordlist[i], context);
80 }
81 }
82}
Andrew Boie945af952017-08-22 13:15:23 -070083"""
84
85
Andy Gross6042ae92018-01-22 14:26:49 -060086def write_gperf_table(fp, eh, objs, static_begin, static_end):
Andrew Boie945af952017-08-22 13:15:23 -070087 fp.write(header)
88
Andrew Boiebca15da2017-10-15 14:17:48 -070089 for obj_addr, ko in objs.items():
90 obj_type = ko.type_name
Andrew Boie945af952017-08-22 13:15:23 -070091 # pre-initialized objects fall within this memory range, they are
92 # either completely initialized at build time, or done automatically
93 # at boot during some PRE_KERNEL_* phase
94 initialized = obj_addr >= static_begin and obj_addr < static_end
95
Andy Gross6042ae92018-01-22 14:26:49 -060096 byte_str = struct.pack("<I" if eh.little_endian else ">I", obj_addr)
Andrew Boie945af952017-08-22 13:15:23 -070097 fp.write("\"")
98 for byte in byte_str:
99 val = "\\x%02x" % byte
100 fp.write(val)
101
Anas Nashif72565532017-12-12 08:19:25 -0500102 fp.write(
103 "\",{},%s,%s,%d\n" %
104 (obj_type,
105 "K_OBJ_FLAG_INITIALIZED" if initialized else "0",
106 ko.data))
Andrew Boie945af952017-08-22 13:15:23 -0700107
108 fp.write(footer)
109
110
Andrew Boie945af952017-08-22 13:15:23 -0700111def parse_args():
112 global args
113
Anas Nashif72565532017-12-12 08:19:25 -0500114 parser = argparse.ArgumentParser(
115 description=__doc__,
116 formatter_class=argparse.RawDescriptionHelpFormatter)
Andrew Boie945af952017-08-22 13:15:23 -0700117
118 parser.add_argument("-k", "--kernel", required=True,
Anas Nashif72565532017-12-12 08:19:25 -0500119 help="Input zephyr ELF binary")
120 parser.add_argument(
121 "-o", "--output", required=True,
122 help="Output list of kernel object addresses for gperf use")
Andrew Boie945af952017-08-22 13:15:23 -0700123 parser.add_argument("-v", "--verbose", action="store_true",
Anas Nashif72565532017-12-12 08:19:25 -0500124 help="Print extra debugging information")
Andrew Boie945af952017-08-22 13:15:23 -0700125 args = parser.parse_args()
Sebastian Bøe4971d2a2017-12-28 17:34:50 +0100126 if "VERBOSE" in os.environ:
127 args.verbose = 1
Andrew Boie945af952017-08-22 13:15:23 -0700128
129
130def main():
131 parse_args()
132
Andy Gross6042ae92018-01-22 14:26:49 -0600133 eh = ElfHelper(args.kernel, args.verbose, kobjects, subsystems)
134 syms = eh.get_symbols()
135 max_threads = syms["CONFIG_MAX_THREAD_BYTES"] * 8
136 objs = eh.find_kobjects(syms)
Andrew Boie945af952017-08-22 13:15:23 -0700137
Andy Gross6042ae92018-01-22 14:26:49 -0600138 if eh.get_thread_counter() > max_threads:
Andrew Boie818a96d2017-11-03 09:00:35 -0700139 sys.stderr.write("Too many thread objects (%d)\n" % thread_counter)
140 sys.stderr.write("Increase CONFIG_MAX_THREAD_BYTES to %d\n",
Anas Nashif72565532017-12-12 08:19:25 -0500141 -(-thread_counter // 8))
Andrew Boie818a96d2017-11-03 09:00:35 -0700142 sys.exit(1)
143
Andrew Boie945af952017-08-22 13:15:23 -0700144 with open(args.output, "w") as fp:
Andy Gross6042ae92018-01-22 14:26:49 -0600145 write_gperf_table(fp, eh, objs, syms["_static_kernel_objects_begin"],
Anas Nashif72565532017-12-12 08:19:25 -0500146 syms["_static_kernel_objects_end"])
147
Andrew Boie945af952017-08-22 13:15:23 -0700148
149if __name__ == "__main__":
150 main()