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