def find_kobjects(elf, syms):
    if (not elf.has_dwarf_info()):
        sys.exit('ELF file has no DWARF information')
    app_smem_start = syms['_app_smem_start']
    app_smem_end = syms['_app_smem_end']
    di = elf.get_dwarf_info()
    for CU in di.iter_CUs():
        for die in CU.iter_DIEs():
            if (die.tag == 'DW_TAG_structure_type'):
                analyze_die_struct(die)
            elif (die.tag == 'DW_TAG_const_type'):
                analyze_die_const(die)
            elif (die.tag == 'DW_TAG_array_type'):
                analyze_die_array(die)
            elif (die.tag == 'DW_TAG_typedef'):
                analyze_typedef(die)
            elif (die.tag == 'DW_TAG_variable'):
                variables.append(die)
    bad_offsets = []
    for (offset, type_object) in type_env.items():
        if (not type_object.has_kobject()):
            bad_offsets.append(offset)
    for offset in bad_offsets:
        del type_env[offset]
    all_objs = {}
    for die in variables:
        name = die_get_name(die)
        if (not name):
            continue
        if name.startswith('__init_sys_init'):
            continue
        type_offset = die_get_type_offset(die)
        if (type_offset not in type_env):
            continue
        if ('DW_AT_declaration' in die.attributes):
            extern_env[die.offset] = die
            continue
        if ('DW_AT_location' not in die.attributes):
            debug_die(die, ("No location information for object '%s'; possibly stack allocated" % name))
            continue
        loc = die.attributes['DW_AT_location']
        if ((loc.form != 'DW_FORM_exprloc') and (loc.form != 'DW_FORM_block1')):
            debug_die(die, ("kernel object '%s' unexpected location format" % name))
            continue
        opcode = loc.value[0]
        if (opcode != DW_OP_addr):
            if (opcode == DW_OP_fbreg):
                debug_die(die, ("kernel object '%s' found on stack" % name))
            else:
                debug_die(die, ("kernel object '%s' unexpected exprloc opcode %s" % (name, hex(opcode))))
            continue
        addr = (((loc.value[1] | (loc.value[2] << 8)) | (loc.value[3] << 16)) | (loc.value[4] << 24))
        if (addr == 0):
            continue
        type_obj = type_env[type_offset]
        objs = type_obj.get_kobjects(addr)
        all_objs.update(objs)
        debug(("symbol '%s' at %s contains %d object(s)" % (name, hex(addr), len(objs))))
    ret = {}
    for (addr, ko) in all_objs.items():
        if ko.type_obj.api:
            continue
        (_, user_ram_allowed) = kobjects[ko.type_obj.name]
        if ((not user_ram_allowed) and (app_smem_start <= addr < app_smem_end)):
            debug_die(die, ("object '%s' found in invalid location %s" % (name, hex(addr))))
            continue
        if (ko.type_obj.name != 'device'):
            ko.type_name = kobject_to_enum(ko.type_obj.name)
            ret[addr] = ko
            continue
        apiaddr = device_get_api_addr(elf, addr)
        if (apiaddr not in all_objs):
            if (apiaddr == 0):
                debug(('device instance at 0x%x has no associated subsystem' % addr))
            else:
                debug(('device instance at 0x%x has unknown API 0x%x' % (addr, apiaddr)))
            continue
        apiobj = all_objs[apiaddr]
        ko.type_name = subsystem_to_enum(apiobj.type_obj.name)
        ret[addr] = ko
    debug(('found %d kernel object instances total' % len(ret)))
    return OrderedDict(sorted(ret.items()))
def find_kobjects(elf, syms):
    if (not elf.has_dwarf_info()):
        sys.exit('ELF file has no DWARF information')
    app_smem_start = syms['_app_smem_start']
    app_smem_end = syms['_app_smem_end']
    di = elf.get_dwarf_info()
    for CU in di.iter_CUs():
        for die in CU.iter_DIEs():
            if (die.tag == 'DW_TAG_structure_type'):
                analyze_die_struct(die)
            elif (die.tag == 'DW_TAG_const_type'):
                analyze_die_const(die)
            elif (die.tag == 'DW_TAG_array_type'):
                analyze_die_array(die)
            elif (die.tag == 'DW_TAG_typedef'):
                analyze_typedef(die)
            elif (die.tag == 'DW_TAG_variable'):
                variables.append(die)
    bad_offsets = []
    for (offset, type_object) in type_env.items():
        if (not type_object.has_kobject()):
            bad_offsets.append(offset)
    for offset in bad_offsets:
        del type_env[offset]
    all_objs = {}
    for die in variables:
        name = die_get_name(die)
        if (not name):
            continue
        if name.startswith('__init_sys_init'):
            continue
        type_offset = die_get_type_offset(die)
        if (type_offset not in type_env):
            continue
        if ('DW_AT_declaration' in die.attributes):
            extern_env[die.offset] = die
            continue
        if ('DW_AT_location' not in die.attributes):
            debug_die(die, ("No location information for object '%s'; possibly stack allocated" % name))
            continue
        loc = die.attributes['DW_AT_location']
        if ((loc.form != 'DW_FORM_exprloc') and (loc.form != 'DW_FORM_block1')):
            debug_die(die, ("kernel object '%s' unexpected location format" % name))
            continue
        opcode = loc.value[0]
        if (opcode != DW_OP_addr):
            if (opcode == DW_OP_fbreg):
                debug_die(die, ("kernel object '%s' found on stack" % name))
            else:
                debug_die(die, ("kernel object '%s' unexpected exprloc opcode %s" % (name, hex(opcode))))
            continue
        addr = (((loc.value[1] | (loc.value[2] << 8)) | (loc.value[3] << 16)) | (loc.value[4] << 24))
        if (addr == 0):
            continue
        type_obj = type_env[type_offset]
        objs = type_obj.get_kobjects(addr)
        all_objs.update(objs)
        debug(("symbol '%s' at %s contains %d object(s)" % (name, hex(addr), len(objs))))
    ret = {}
    for (addr, ko) in all_objs.items():
        if ko.type_obj.api:
            continue
        (_, user_ram_allowed) = kobjects[ko.type_obj.name]
        if ((not user_ram_allowed) and (app_smem_start <= addr < app_smem_end)):
            debug_die(die, ("object '%s' found in invalid location %s" % (name, hex(addr))))
            continue
        if (ko.type_obj.name != 'device'):
            ko.type_name = kobject_to_enum(ko.type_obj.name)
            ret[addr] = ko
            continue
        apiaddr = device_get_api_addr(elf, addr)
        if (apiaddr not in all_objs):
            if (apiaddr == 0):
                debug(('device instance at 0x%x has no associated subsystem' % addr))
            else:
                debug(('device instance at 0x%x has unknown API 0x%x' % (addr, apiaddr)))
            continue
        apiobj = all_objs[apiaddr]
        ko.type_name = subsystem_to_enum(apiobj.type_obj.name)
        ret[addr] = ko
    debug(('found %d kernel object instances total' % len(ret)))
    return OrderedDict(sorted(ret.items()))