scripts: gen_kobject_list.py cleanup
Un-do the changes made to the code when this was separated out to elf_helper.py. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
fc2f7c3a55
commit
b42fe9c764
1 changed files with 176 additions and 221 deletions
|
@ -122,6 +122,30 @@ def subsystem_to_enum(subsys):
|
||||||
|
|
||||||
scr = os.path.basename(sys.argv[0])
|
scr = os.path.basename(sys.argv[0])
|
||||||
|
|
||||||
|
def debug(text):
|
||||||
|
if not args.verbose:
|
||||||
|
return
|
||||||
|
sys.stdout.write(scr + ": " + text + "\n")
|
||||||
|
|
||||||
|
def error(text):
|
||||||
|
sys.exit("%s ERROR: %s" % (scr, text))
|
||||||
|
|
||||||
|
def debug_die(die, text):
|
||||||
|
lp_header = die.dwarfinfo.line_program_for_CU(die.cu).header
|
||||||
|
files = lp_header["file_entry"]
|
||||||
|
includes = lp_header["include_directory"]
|
||||||
|
|
||||||
|
fileinfo = files[die.attributes["DW_AT_decl_file"].value - 1]
|
||||||
|
filename = fileinfo.name.decode("utf-8")
|
||||||
|
filedir = includes[fileinfo.dir_index - 1].decode("utf-8")
|
||||||
|
|
||||||
|
path = os.path.join(filedir, filename)
|
||||||
|
lineno = die.attributes["DW_AT_decl_line"].value
|
||||||
|
|
||||||
|
debug(str(die))
|
||||||
|
debug("File '%s', line %d:" % (path, lineno))
|
||||||
|
debug(" %s" % text)
|
||||||
|
|
||||||
# -- ELF processing
|
# -- ELF processing
|
||||||
|
|
||||||
DW_OP_addr = 0x3
|
DW_OP_addr = 0x3
|
||||||
|
@ -135,8 +159,6 @@ stack_counter = 0
|
||||||
# Global type environment. Populated by pass 1.
|
# Global type environment. Populated by pass 1.
|
||||||
type_env = {}
|
type_env = {}
|
||||||
extern_env = {}
|
extern_env = {}
|
||||||
elh_kobjects = {}
|
|
||||||
elh_subsystems = {}
|
|
||||||
|
|
||||||
class KobjectInstance:
|
class KobjectInstance:
|
||||||
def __init__(self, type_obj, addr):
|
def __init__(self, type_obj, addr):
|
||||||
|
@ -373,9 +395,9 @@ def analyze_die_struct(die):
|
||||||
if not size:
|
if not size:
|
||||||
return
|
return
|
||||||
|
|
||||||
if name in elh_kobjects:
|
if name in kobjects:
|
||||||
type_env[offset] = KobjectType(offset, name, size)
|
type_env[offset] = KobjectType(offset, name, size)
|
||||||
elif name in elh_subsystems:
|
elif name in subsystems:
|
||||||
type_env[offset] = KobjectType(offset, name, size, api=True)
|
type_env[offset] = KobjectType(offset, name, size, api=True)
|
||||||
else:
|
else:
|
||||||
at = AggregateType(offset, name, size)
|
at = AggregateType(offset, name, size)
|
||||||
|
@ -474,40 +496,14 @@ def device_get_api_addr(elf, addr):
|
||||||
return addr_deref(elf, addr + offset)
|
return addr_deref(elf, addr + offset)
|
||||||
|
|
||||||
|
|
||||||
def get_filename_lineno(die):
|
def find_kobjects(elf, syms):
|
||||||
lp_header = die.dwarfinfo.line_program_for_CU(die.cu).header
|
if not elf.has_dwarf_info():
|
||||||
files = lp_header["file_entry"]
|
|
||||||
includes = lp_header["include_directory"]
|
|
||||||
|
|
||||||
fileinfo = files[die.attributes["DW_AT_decl_file"].value - 1]
|
|
||||||
filename = fileinfo.name.decode("utf-8")
|
|
||||||
filedir = includes[fileinfo.dir_index - 1].decode("utf-8")
|
|
||||||
|
|
||||||
path = os.path.join(filedir, filename)
|
|
||||||
lineno = die.attributes["DW_AT_decl_line"].value
|
|
||||||
return (path, lineno)
|
|
||||||
|
|
||||||
|
|
||||||
class ElfHelper:
|
|
||||||
|
|
||||||
def __init__(self, filename, verbose, kobjs, subs):
|
|
||||||
self.verbose = verbose
|
|
||||||
self.fp = open(filename, "rb")
|
|
||||||
self.elf = ELFFile(self.fp)
|
|
||||||
self.little_endian = self.elf.little_endian
|
|
||||||
global elh_kobjects
|
|
||||||
global elh_subsystems
|
|
||||||
elh_kobjects = kobjs
|
|
||||||
elh_subsystems = subs
|
|
||||||
|
|
||||||
def find_kobjects(self, syms):
|
|
||||||
if not self.elf.has_dwarf_info():
|
|
||||||
sys.exit("ELF file has no DWARF information")
|
sys.exit("ELF file has no DWARF information")
|
||||||
|
|
||||||
app_smem_start = syms["_app_smem_start"]
|
app_smem_start = syms["_app_smem_start"]
|
||||||
app_smem_end = syms["_app_smem_end"]
|
app_smem_end = syms["_app_smem_end"]
|
||||||
|
|
||||||
di = self.elf.get_dwarf_info()
|
di = elf.get_dwarf_info()
|
||||||
|
|
||||||
variables = []
|
variables = []
|
||||||
|
|
||||||
|
@ -564,18 +560,15 @@ class ElfHelper:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if "DW_AT_location" not in die.attributes:
|
if "DW_AT_location" not in die.attributes:
|
||||||
self.debug_die(
|
debug_die(die,
|
||||||
die,
|
"No location information for object '%s'; possibly stack allocated"
|
||||||
"No location information for object '%s'; possibly"
|
% name)
|
||||||
" stack allocated" % name)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
loc = die.attributes["DW_AT_location"]
|
loc = die.attributes["DW_AT_location"]
|
||||||
if loc.form != "DW_FORM_exprloc" and \
|
if loc.form != "DW_FORM_exprloc" and \
|
||||||
loc.form != "DW_FORM_block1":
|
loc.form != "DW_FORM_block1":
|
||||||
self.debug_die(
|
debug_die(die, "kernel object '%s' unexpected location format" %
|
||||||
die,
|
|
||||||
"kernel object '%s' unexpected location format" %
|
|
||||||
name)
|
name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -584,11 +577,9 @@ class ElfHelper:
|
||||||
|
|
||||||
# Check if frame pointer offset DW_OP_fbreg
|
# Check if frame pointer offset DW_OP_fbreg
|
||||||
if opcode == DW_OP_fbreg:
|
if opcode == DW_OP_fbreg:
|
||||||
self.debug_die(die, "kernel object '%s' found on stack" %
|
debug_die(die, "kernel object '%s' found on stack" % name)
|
||||||
name)
|
|
||||||
else:
|
else:
|
||||||
self.debug_die(
|
debug_die(die,
|
||||||
die,
|
|
||||||
"kernel object '%s' unexpected exprloc opcode %s" %
|
"kernel object '%s' unexpected exprloc opcode %s" %
|
||||||
(name, hex(opcode)))
|
(name, hex(opcode)))
|
||||||
continue
|
continue
|
||||||
|
@ -604,7 +595,7 @@ class ElfHelper:
|
||||||
objs = type_obj.get_kobjects(addr)
|
objs = type_obj.get_kobjects(addr)
|
||||||
all_objs.update(objs)
|
all_objs.update(objs)
|
||||||
|
|
||||||
self.debug("symbol '%s' at %s contains %d object(s)"
|
debug("symbol '%s' at %s contains %d object(s)"
|
||||||
% (name, hex(addr), len(objs)))
|
% (name, hex(addr), len(objs)))
|
||||||
|
|
||||||
# Step 4: objs is a dictionary mapping variable memory addresses to
|
# Step 4: objs is a dictionary mapping variable memory addresses to
|
||||||
|
@ -618,10 +609,9 @@ class ElfHelper:
|
||||||
if ko.type_obj.api:
|
if ko.type_obj.api:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
_, user_ram_allowed = elh_kobjects[ko.type_obj.name]
|
_, user_ram_allowed = kobjects[ko.type_obj.name]
|
||||||
if not user_ram_allowed and app_smem_start <= addr < app_smem_end:
|
if not user_ram_allowed and app_smem_start <= addr < app_smem_end:
|
||||||
self.debug_die(die,
|
debug_die(die, "object '%s' found in invalid location %s"
|
||||||
"object '%s' found in invalid location %s"
|
|
||||||
% (name, hex(addr)))
|
% (name, hex(addr)))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -633,13 +623,13 @@ class ElfHelper:
|
||||||
|
|
||||||
# Device struct. Need to get the address of its API struct,
|
# Device struct. Need to get the address of its API struct,
|
||||||
# if it has one.
|
# if it has one.
|
||||||
apiaddr = device_get_api_addr(self.elf, addr)
|
apiaddr = device_get_api_addr(elf, addr)
|
||||||
if apiaddr not in all_objs:
|
if apiaddr not in all_objs:
|
||||||
if apiaddr == 0:
|
if apiaddr == 0:
|
||||||
self.debug("device instance at 0x%x has no associated subsystem"
|
debug("device instance at 0x%x has no associated subsystem"
|
||||||
% addr)
|
% addr)
|
||||||
else:
|
else:
|
||||||
self.debug("device instance at 0x%x has unknown API 0x%x"
|
debug("device instance at 0x%x has unknown API 0x%x"
|
||||||
% (addr, apiaddr))
|
% (addr, apiaddr))
|
||||||
# API struct does not correspond to a known subsystem, skip it
|
# API struct does not correspond to a known subsystem, skip it
|
||||||
continue
|
continue
|
||||||
|
@ -648,7 +638,7 @@ class ElfHelper:
|
||||||
ko.type_name = subsystem_to_enum(apiobj.type_obj.name)
|
ko.type_name = subsystem_to_enum(apiobj.type_obj.name)
|
||||||
ret[addr] = ko
|
ret[addr] = ko
|
||||||
|
|
||||||
self.debug("found %d kernel object instances total" % len(ret))
|
debug("found %d kernel object instances total" % len(ret))
|
||||||
|
|
||||||
# 1. Before python 3.7 dict order is not guaranteed. With Python
|
# 1. Before python 3.7 dict order is not guaranteed. With Python
|
||||||
# 3.5 it doesn't seem random with *integer* keys but can't
|
# 3.5 it doesn't seem random with *integer* keys but can't
|
||||||
|
@ -658,45 +648,14 @@ class ElfHelper:
|
||||||
# 3. Sorting memory address looks good.
|
# 3. Sorting memory address looks good.
|
||||||
return OrderedDict(sorted(ret.items()))
|
return OrderedDict(sorted(ret.items()))
|
||||||
|
|
||||||
def get_symbols(self):
|
def get_symbols(elf):
|
||||||
for section in self.elf.iter_sections():
|
for section in elf.iter_sections():
|
||||||
if isinstance(section, SymbolTableSection):
|
if isinstance(section, SymbolTableSection):
|
||||||
return {sym.name: sym.entry.st_value
|
return {sym.name: sym.entry.st_value
|
||||||
for sym in section.iter_symbols()}
|
for sym in section.iter_symbols()}
|
||||||
|
|
||||||
raise LookupError("Could not find symbol table")
|
raise LookupError("Could not find symbol table")
|
||||||
|
|
||||||
def debug(self, text):
|
|
||||||
if not self.verbose:
|
|
||||||
return
|
|
||||||
sys.stdout.write(scr + ": " + text + "\n")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def error(text):
|
|
||||||
sys.exit("%s ERROR: %s" % (scr, text))
|
|
||||||
|
|
||||||
def debug_die(self, die, text):
|
|
||||||
fn, ln = get_filename_lineno(die)
|
|
||||||
|
|
||||||
self.debug(str(die))
|
|
||||||
self.debug("File '%s', line %d:" % (fn, ln))
|
|
||||||
self.debug(" %s" % text)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_thread_counter():
|
|
||||||
return thread_counter
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_sys_mutex_counter():
|
|
||||||
return sys_mutex_counter
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_futex_counter():
|
|
||||||
return futex_counter
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_stack_counter():
|
|
||||||
return stack_counter
|
|
||||||
|
|
||||||
# -- GPERF generation logic
|
# -- GPERF generation logic
|
||||||
|
|
||||||
|
@ -745,25 +704,23 @@ void z_object_wordlist_foreach(_wordlist_cb_func_t func, void *context)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def write_gperf_table(fp, eh, objs, static_begin, static_end):
|
def write_gperf_table(fp, syms, objs, little_endian, static_begin, static_end):
|
||||||
syms = eh.get_symbols()
|
|
||||||
|
|
||||||
fp.write(header)
|
fp.write(header)
|
||||||
num_mutexes = eh.get_sys_mutex_counter()
|
if sys_mutex_counter != 0:
|
||||||
if num_mutexes != 0:
|
fp.write("static struct k_mutex kernel_mutexes[%d] = {\n"
|
||||||
fp.write("static struct k_mutex kernel_mutexes[%d] = {\n" % num_mutexes)
|
% sys_mutex_counter)
|
||||||
for i in range(num_mutexes):
|
for i in range(sys_mutex_counter):
|
||||||
fp.write("_K_MUTEX_INITIALIZER(kernel_mutexes[%d])" % i)
|
fp.write("_K_MUTEX_INITIALIZER(kernel_mutexes[%d])" % i)
|
||||||
if i != num_mutexes - 1:
|
if i != sys_mutex_counter - 1:
|
||||||
fp.write(", ")
|
fp.write(", ")
|
||||||
fp.write("};\n")
|
fp.write("};\n")
|
||||||
|
|
||||||
num_futex = eh.get_futex_counter()
|
if futex_counter != 0:
|
||||||
if num_futex != 0:
|
fp.write("static struct z_futex_data futex_data[%d] = {\n"
|
||||||
fp.write("static struct z_futex_data futex_data[%d] = {\n" % num_futex)
|
% futex_counter)
|
||||||
for i in range(num_futex):
|
for i in range(futex_counter):
|
||||||
fp.write("Z_FUTEX_DATA_INITIALIZER(futex_data[%d])" % i)
|
fp.write("Z_FUTEX_DATA_INITIALIZER(futex_data[%d])" % i)
|
||||||
if i != num_futex - 1:
|
if i != futex_counter - 1:
|
||||||
fp.write(", ")
|
fp.write(", ")
|
||||||
fp.write("};\n")
|
fp.write("};\n")
|
||||||
|
|
||||||
|
@ -775,15 +732,14 @@ def write_gperf_table(fp, eh, objs, static_begin, static_end):
|
||||||
|
|
||||||
if "CONFIG_GEN_PRIV_STACKS" in syms:
|
if "CONFIG_GEN_PRIV_STACKS" in syms:
|
||||||
metadata_names["K_OBJ_THREAD_STACK_ELEMENT"] = "stack_data"
|
metadata_names["K_OBJ_THREAD_STACK_ELEMENT"] = "stack_data"
|
||||||
num_stack = eh.get_stack_counter()
|
if stack_counter != 0:
|
||||||
if num_stack != 0:
|
|
||||||
fp.write("static u8_t Z_GENERIC_SECTION(.priv_stacks.noinit) "
|
fp.write("static u8_t Z_GENERIC_SECTION(.priv_stacks.noinit) "
|
||||||
" __aligned(Z_PRIVILEGE_STACK_ALIGN)"
|
" __aligned(Z_PRIVILEGE_STACK_ALIGN)"
|
||||||
" priv_stacks[%d][CONFIG_PRIVILEGED_STACK_SIZE];\n"
|
" priv_stacks[%d][CONFIG_PRIVILEGED_STACK_SIZE];\n"
|
||||||
% num_stack);
|
% stack_counter)
|
||||||
|
|
||||||
fp.write("static struct z_stack_data stack_data[%d] = {\n"
|
fp.write("static struct z_stack_data stack_data[%d] = {\n"
|
||||||
% num_stack)
|
% stack_counter)
|
||||||
counter = 0
|
counter = 0
|
||||||
for _, ko in objs.items():
|
for _, ko in objs.items():
|
||||||
if ko.type_name != "K_OBJ_THREAD_STACK_ELEMENT":
|
if ko.type_name != "K_OBJ_THREAD_STACK_ELEMENT":
|
||||||
|
@ -797,7 +753,7 @@ def write_gperf_table(fp, eh, objs, static_begin, static_end):
|
||||||
ko.data = "&stack_data[%d]" % counter
|
ko.data = "&stack_data[%d]" % counter
|
||||||
fp.write("\t{ %d, (u8_t *)(&priv_stacks[%d]) }"
|
fp.write("\t{ %d, (u8_t *)(&priv_stacks[%d]) }"
|
||||||
% (size, counter))
|
% (size, counter))
|
||||||
if counter != (num_stack - 1):
|
if counter != (stack_counter - 1):
|
||||||
fp.write(",")
|
fp.write(",")
|
||||||
fp.write("\n")
|
fp.write("\n")
|
||||||
counter += 1
|
counter += 1
|
||||||
|
@ -826,7 +782,7 @@ def write_gperf_table(fp, eh, objs, static_begin, static_end):
|
||||||
else:
|
else:
|
||||||
format_code = "I"
|
format_code = "I"
|
||||||
|
|
||||||
if eh.little_endian:
|
if little_endian:
|
||||||
endian = "<"
|
endian = "<"
|
||||||
else:
|
else:
|
||||||
endian = ">"
|
endian = ">"
|
||||||
|
@ -945,7 +901,7 @@ def write_kobj_size_output(fp):
|
||||||
dep, _ = obj_info
|
dep, _ = obj_info
|
||||||
# device handled by default case. Stacks are not currently handled,
|
# device handled by default case. Stacks are not currently handled,
|
||||||
# if they eventually are it will be a special case.
|
# if they eventually are it will be a special case.
|
||||||
if kobj in {"device", "z_thread_stack_element"}:
|
if kobj in {"device", STACK_TYPE}:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if dep:
|
if dep:
|
||||||
|
@ -1007,22 +963,21 @@ def main():
|
||||||
|
|
||||||
if args.gperf_output:
|
if args.gperf_output:
|
||||||
assert args.kernel, "--kernel ELF required for --gperf-output"
|
assert args.kernel, "--kernel ELF required for --gperf-output"
|
||||||
eh = ElfHelper(args.kernel, args.verbose, kobjects, subsystems)
|
elf = ELFFile(open(args.kernel, "rb"))
|
||||||
syms = eh.get_symbols()
|
syms = get_symbols(elf)
|
||||||
max_threads = syms["CONFIG_MAX_THREAD_BYTES"] * 8
|
max_threads = syms["CONFIG_MAX_THREAD_BYTES"] * 8
|
||||||
objs = eh.find_kobjects(syms)
|
objs = find_kobjects(elf, syms)
|
||||||
if not objs:
|
if not objs:
|
||||||
sys.stderr.write("WARNING: zero kobject found in %s\n"
|
sys.stderr.write("WARNING: zero kobject found in %s\n"
|
||||||
% args.kernel)
|
% args.kernel)
|
||||||
|
|
||||||
thread_counter = eh.get_thread_counter()
|
|
||||||
if thread_counter > max_threads:
|
if thread_counter > max_threads:
|
||||||
sys.exit("Too many thread objects ({})\n"
|
sys.exit("Too many thread objects ({})\n"
|
||||||
"Increase CONFIG_MAX_THREAD_BYTES to {}"
|
"Increase CONFIG_MAX_THREAD_BYTES to {}"
|
||||||
.format(thread_counter, -(-thread_counter // 8)))
|
.format(thread_counter, -(-thread_counter // 8)))
|
||||||
|
|
||||||
with open(args.gperf_output, "w") as fp:
|
with open(args.gperf_output, "w") as fp:
|
||||||
write_gperf_table(fp, eh, objs,
|
write_gperf_table(fp, syms, objs, elf.little_endian,
|
||||||
syms["_static_kernel_objects_begin"],
|
syms["_static_kernel_objects_begin"],
|
||||||
syms["_static_kernel_objects_end"])
|
syms["_static_kernel_objects_end"])
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue