1""" Please make sure you read the README file COMPLETELY BEFORE reading anything below. 2 It is very critical that you read coding guidelines in Section E in README file. 3 4 Note for adding new register support: 5 6 1. Add target register to "supported registers" in the docstring of DecodeSysreg 7 2. Populate _SYSREG_TO_DECODE_FUNC_MAP with your implementation, optionally using 8 _SYSREG_TO_DOCNAME_MAP 9 3. Populate _SUPPORTED_SYSREGS list with target register 10 11""" 12from xnu import * 13import os 14import sys 15import xml.etree.ElementTree as ET 16 17GREEN = '\033[0;32m' 18RED = '\033[0;31m' 19NC = '\033[0m' 20 21_SUPPORTED_SYSREGS = ['ESR_EL1'] 22 23_SYSREG_DOC_PATH = os.path.dirname(os.path.abspath(__file__)) + '/sysregdoc/' 24 25_SYSREG_TO_DOCNAME_MAP = { 26 'ESR_EL1': 'AArch64-esr_el1.xml' 27} 28 29## Actual definition at the bottom of the file 30_SYSREG_TO_DECODE_FUNC_MAP = None 31 32# Macro: decode_sysreg 33@lldb_command('decode_sysreg') 34def DecodeSysreg(cmd_args=None): 35 """ Print out human-understandable explanation of a system register value 36 usage: decode_sysreg <sysreg> <value> 37 example: decode_sysreg esr_el1 0x96000021 38 39 supported registers: 40 ESR_EL1 41 """ 42 43 ## For now, require exactly 2 arguments 44 if not cmd_args or len(cmd_args) != 2: 45 raise ArgumentError("Missing arguments.") 46 47 reg_name = cmd_args[0].upper() 48 reg_value = ArgumentStringToInt(cmd_args[1]) 49 50 if reg_name not in _SUPPORTED_SYSREGS: 51 raise ArgumentError("{} is not supported".format(reg_name)) 52 53 _SYSREG_TO_DECODE_FUNC_MAP[reg_name](reg_value) 54# EndMacro: decode_sysreg 55 56 57lldb_alias('decode_esr', 'decode_sysreg esr_el1') 58 59 60def PrintEsrEl1Explanation(regval): 61 """ Print out a detailed explanation of regval regarded as the value of 62 ESR_EL1, by parsing ARM machine readable specification 63 """ 64 xmlfilename = _SYSREG_DOC_PATH + _SYSREG_TO_DOCNAME_MAP['ESR_EL1'] 65 tree = ET.parse(xmlfilename) 66 root = tree.getroot() 67 68 ec = (regval >> 26) & ((1 << 6) - 1) 69 ecstring = '0b{:06b}'.format(ec) 70 71 print(_Colorify(VT.Green, 'EC == ' + ecstring)) 72 73 ecxpath = './registers/register/reg_fieldsets/fields/field[@id="EC_31_26"]/field_values/field_value_instance[field_value="{}"]/field_value_description//para'.format(ecstring) 74 ec_desc_paras = root.findall(ecxpath) 75 76 if ec_desc_paras is None or len(ec_desc_paras) == 0: 77 print('EC not defined.') 78 print('\r\n') 79 80 for para in ec_desc_paras: 81 sys.stdout.write(para.text) 82 for child in para: 83 sys.stdout.write(_GetParaChildrenStr(child)) 84 sys.stdout.write(child.tail) 85 print('\r\n') 86 print('\r\n') 87 88 iss = regval & ((1 << 25) - 1); 89 issstring = '0x{:07x}'.format(iss) 90 print(_Colorify(VT.Green, 'ISS == ' + issstring)) 91 print('\r\n') 92 93 iss_condition_xpath = './registers/register/reg_fieldsets/fields/field[@id="EC_31_26"]/field_values/field_value_instance[field_value="{}"]/field_value_links_to'.format(ecstring) 94 iss_condition = root.find(iss_condition_xpath) 95 iss_condition_str = iss_condition.attrib['linked_field_condition'] 96 97 iss_fields_xpath = './registers/register/reg_fieldsets/fields/field[@id="ISS_24_0"]/partial_fieldset/fields[fields_instance="{}"]//field'.format(iss_condition_str) 98 iss_fields = root.findall(iss_fields_xpath) 99 100 for field in iss_fields: 101 _PrintEsrIssField(field, regval) 102 103 104def _GetParaChildrenStr(elem): 105 """ Convert child tags of <para> element into text for printing 106 """ 107 108 if elem.tag == 'binarynumber': 109 return elem.text 110 if elem.tag == 'arm-defined-word': 111 return elem.text 112 elif elem.tag == 'xref': 113 return elem.attrib['browsertext'] 114 elif elem.tag == 'register_link': 115 return elem.text 116 else: 117 return _Colorify(VT.Red, '*unsupported text*') 118 119 120def _PrintEsrIssField(elem, regval): 121 """ Print detailed explanation of the ISS field of ESR 122 """ 123 124 field_name_str = elem.find('field_name').text 125 field_msb = int(elem.find('field_msb').text) 126 field_lsb = int(elem.find('field_lsb').text) 127 fd_before_paras = elem.findall('./field_description[@order="before"]//para') 128 fd_after_paras = elem.findall('./field_description[@order="after"]//para') 129 130 field_bits = field_msb - field_lsb + 1 131 field_value = (regval >> field_lsb) & ((1 << field_bits) - 1) 132 field_value_string = ('0b{:0' + '{}'.format(field_bits) + 'b}').format(field_value) 133 134 print(_Colorify(VT.Green, _GetIndentedString(2, field_name_str) + ' == ' + field_value_string)) 135 136 fv_desc_paras = elem.findall('./field_values/field_value_instance[field_value="{}"]/field_value_description//para'.format(field_value_string)) 137 138 if fv_desc_paras and len(fv_desc_paras): 139 for para in fv_desc_paras: 140 sys.stdout.write(_GetIndentedString(2, '')) 141 sys.stdout.write(para.text) 142 for child in para: 143 sys.stdout.write(_GetParaChildrenStr(child)) 144 sys.stdout.write((child.tail)) 145 print('\r\n') 146 print('\r\n') 147 else: 148 print(_Colorify(VT.Red, _GetIndentedString(2, '(No matching value, dumping out full description)'))) 149 for para in fd_before_paras: 150 sys.stdout.write(_GetIndentedString(2, '')) 151 sys.stdout.write(para.text) 152 for child in para: 153 sys.stdout.write(_GetParaChildrenStr(child)) 154 sys.stdout.write(child.tail) 155 print('\r\n') 156 print('\r\n') 157 158 ## Dump all possible values 159 all_field_values = elem.findall('./field_values/field_value_instance//field_value') 160 all_field_values_str = [fv.text for fv in all_field_values] 161 if all_field_values_str != []: 162 print(_GetIndentedString(2, ', '.join(all_field_values_str))) 163 164 for para in fd_after_paras: 165 sys.stdout.write(_GetIndentedString(2, '')) 166 sys.stdout.write(para.text) 167 for child in para: 168 sys.stdout.write(_GetParaChildrenStr(child)) 169 sys.stdout.write(child.tail) 170 print('\r\n') 171 print('\r\n') 172 173 174def _GetIndentedString(indentation, msg): 175 """ Return `msg` indented by `indentation` number of spaces 176 """ 177 return ' ' * indentation + msg 178 179 180def _Colorify(color, msg): 181 """ Return `msg` enclosed by color codes 182 """ 183 return color + msg + VT.Reset 184 185 186_SYSREG_TO_DECODE_FUNC_MAP = { 187 'ESR_EL1': PrintEsrEl1Explanation 188} 189