xref: /xnu-11417.140.69/tools/lldbmacros/nvram.py (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1from ioreg import *
2
3@lldb_command("shownvram")
4def PrintNvramVars(cmd_args=[]):
5    """
6    Print NVRAM variables.
7    """
8    dt_plane = GetRegistryPlane("IODeviceTree")
9    if dt_plane is None:
10        raise ValueError("Couldn't obtain a pointer to IODeviceTree")
11
12    # Registry API functions operate on "plane" global variable
13    global plane
14    prev_plane = plane
15    plane = dt_plane
16    options = FindRegistryObjectRecurse(kern.globals.gRegistryRoot, "options")
17    # Restore original plane after getting options
18    plane = prev_plane
19    if options is None:
20        print("Couldn't obtain options IORegistryEntry")
21        return
22
23    nvram_diags = kern.GetValueFromAddress('((IODTNVRAM *)' + hex(options) + ')->_diags', 'IOService *')
24    nvram_vers = LookupKeyInPropTable(nvram_diags.fPropertyTable, "Version")
25
26    if (GetNumber(nvram_vers) == "3"):
27        var_dict = kern.GetValueFromAddress('((IONVRAMV3Handler *)((IODTNVRAM *)' + hex(options) + ')->_format)->_varDict.ptr_', 'OSDictionary *')
28    else:
29        var_dict = kern.GetValueFromAddress('((IONVRAMCHRPHandler *)((IODTNVRAM *)' + hex(options) + ')->_format)->_varDict.ptr_', 'OSDictionary *')
30
31    if var_dict is None:
32        print("Couldn't obtain varDict")
33        return
34
35    for x in range(var_dict.count):
36        name = var_dict.dictionary[x].key.string
37        value = var_dict.dictionary[x].value
38
39        # get value type
40        value_info = GetObjectTypeStr(value)
41        if value_info is None:
42            print("Couldn't obtain object type for name:", name, "value:", value)
43            continue
44        srch = re.search(r'vtable for ([A-Za-z].*)', value_info)
45        if not srch:
46            print("Couldn't find type in value_info:", value_info)
47            continue
48        value_type = srch.group(1)
49
50        if (value_type == 'OSString'):
51            print(name, '=', GetString(value))
52        elif (value_type == 'OSData'):
53            data_ptr = Cast(value.data, 'uint8_t *')
54            print (name, '= ', end ='')
55            data_buffer = ""
56            for i in range(value.length):
57                if ((data_ptr[i] >= 0x20 and data_ptr[i] <= 0x7e) and chr(data_ptr[i]) != '%'):
58                    data_buffer += chr(data_ptr[i])
59                else:
60                    data_buffer += "%%%02x" % data_ptr[i]
61            print (data_buffer)
62        elif (value_type == 'OSNumber'):
63            print(name, '=', GetNumber(value))
64        elif (value_type == 'OSBoolean'):
65            print(name, '=', GetBoolean(value))
66        else:
67            print("Invalid type:", value_type)