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