|
@@ -44,7 +44,6 @@ def fetch_xml_regmap():
|
|
|
|
|
|
total_regs = 0
|
|
total_regs = 0
|
|
reg_map = {}
|
|
reg_map = {}
|
|
- frame = gdb.selected_frame()
|
|
|
|
|
|
|
|
tree = ET.fromstring(xml)
|
|
tree = ET.fromstring(xml)
|
|
for f in tree.findall("feature"):
|
|
for f in tree.findall("feature"):
|
|
@@ -61,12 +60,8 @@ def fetch_xml_regmap():
|
|
for r in regs:
|
|
for r in regs:
|
|
name = r.attrib["name"]
|
|
name = r.attrib["name"]
|
|
regnum = int(r.attrib["regnum"])
|
|
regnum = int(r.attrib["regnum"])
|
|
- try:
|
|
|
|
- value = frame.read_register(name)
|
|
|
|
- except ValueError:
|
|
|
|
- report(False, f"failed to read reg: {name}")
|
|
|
|
|
|
|
|
- entry = { "name": name, "initial": value, "regnum": regnum }
|
|
|
|
|
|
+ entry = { "name": name, "regnum": regnum }
|
|
|
|
|
|
if name in reg_map:
|
|
if name in reg_map:
|
|
report(False, f"duplicate register {entry} vs {reg_map[name]}")
|
|
report(False, f"duplicate register {entry} vs {reg_map[name]}")
|
|
@@ -80,6 +75,15 @@ def fetch_xml_regmap():
|
|
|
|
|
|
return reg_map
|
|
return reg_map
|
|
|
|
|
|
|
|
+def get_register_by_regnum(reg_map, regnum):
|
|
|
|
+ """
|
|
|
|
+ Helper to find a register from the map via its XML regnum
|
|
|
|
+ """
|
|
|
|
+ for regname, entry in reg_map.items():
|
|
|
|
+ if entry['regnum'] == regnum:
|
|
|
|
+ return entry
|
|
|
|
+ return None
|
|
|
|
+
|
|
def crosscheck_remote_xml(reg_map):
|
|
def crosscheck_remote_xml(reg_map):
|
|
"""
|
|
"""
|
|
Cross-check the list of remote-registers with the XML info.
|
|
Cross-check the list of remote-registers with the XML info.
|
|
@@ -90,8 +94,11 @@ def crosscheck_remote_xml(reg_map):
|
|
|
|
|
|
total_regs = len(reg_map.keys())
|
|
total_regs = len(reg_map.keys())
|
|
total_r_regs = 0
|
|
total_r_regs = 0
|
|
|
|
+ total_r_elided_regs = 0
|
|
|
|
|
|
for r in r_regs:
|
|
for r in r_regs:
|
|
|
|
+ r = r.replace("long long", "long_long")
|
|
|
|
+ r = r.replace("long double", "long_double")
|
|
fields = r.split()
|
|
fields = r.split()
|
|
# Some of the registers reported here are "pseudo" registers that
|
|
# Some of the registers reported here are "pseudo" registers that
|
|
# gdb invents based on actual registers so we need to filter them
|
|
# gdb invents based on actual registers so we need to filter them
|
|
@@ -100,6 +107,15 @@ def crosscheck_remote_xml(reg_map):
|
|
r_name = fields[0]
|
|
r_name = fields[0]
|
|
r_regnum = int(fields[6])
|
|
r_regnum = int(fields[6])
|
|
|
|
|
|
|
|
+ # Some registers are "hidden" so don't have a name
|
|
|
|
+ # although they still should have a register number
|
|
|
|
+ if r_name == "''":
|
|
|
|
+ total_r_elided_regs += 1
|
|
|
|
+ x_reg = get_register_by_regnum(reg_map, r_regnum)
|
|
|
|
+ if x_reg is not None:
|
|
|
|
+ x_reg["hidden"] = True
|
|
|
|
+ continue
|
|
|
|
+
|
|
# check in the XML
|
|
# check in the XML
|
|
try:
|
|
try:
|
|
x_reg = reg_map[r_name]
|
|
x_reg = reg_map[r_name]
|
|
@@ -114,17 +130,42 @@ def crosscheck_remote_xml(reg_map):
|
|
else:
|
|
else:
|
|
total_r_regs += 1
|
|
total_r_regs += 1
|
|
|
|
|
|
- # Just print a mismatch in totals as gdb will filter out 64 bit
|
|
|
|
- # registers on a 32 bit machine. Also print what is missing to
|
|
|
|
- # help with debug.
|
|
|
|
- if total_regs != total_r_regs:
|
|
|
|
- print(f"xml-tdesc has ({total_regs}) registers")
|
|
|
|
- print(f"remote-registers has ({total_r_regs}) registers")
|
|
|
|
|
|
+ report(total_regs == total_r_regs + total_r_elided_regs,
|
|
|
|
+ "All XML Registers accounted for")
|
|
|
|
+
|
|
|
|
+ print(f"xml-tdesc has {total_regs} registers")
|
|
|
|
+ print(f"remote-registers has {total_r_regs} registers")
|
|
|
|
+ print(f"of which {total_r_elided_regs} are hidden")
|
|
|
|
+
|
|
|
|
+ for x_key in reg_map.keys():
|
|
|
|
+ x_reg = reg_map[x_key]
|
|
|
|
+ if "hidden" in x_reg:
|
|
|
|
+ print(f"{x_reg} elided by gdb")
|
|
|
|
+ elif "seen" not in x_reg:
|
|
|
|
+ print(f"{x_reg} wasn't seen in remote-registers")
|
|
|
|
+
|
|
|
|
+def initial_register_read(reg_map):
|
|
|
|
+ """
|
|
|
|
+ Do an initial read of all registers that we know gdb cares about
|
|
|
|
+ (so ignore the elided ones).
|
|
|
|
+ """
|
|
|
|
+ frame = gdb.selected_frame()
|
|
|
|
+
|
|
|
|
+ for e in reg_map.values():
|
|
|
|
+ name = e["name"]
|
|
|
|
+ regnum = e["regnum"]
|
|
|
|
+
|
|
|
|
+ try:
|
|
|
|
+ if "hidden" in e:
|
|
|
|
+ value = frame.read_register(regnum)
|
|
|
|
+ e["initial"] = value
|
|
|
|
+ elif "seen" in e:
|
|
|
|
+ value = frame.read_register(name)
|
|
|
|
+ e["initial"] = value
|
|
|
|
+
|
|
|
|
+ except ValueError:
|
|
|
|
+ report(False, f"failed to read reg: {name}")
|
|
|
|
|
|
- for x_key in reg_map.keys():
|
|
|
|
- x_reg = reg_map[x_key]
|
|
|
|
- if "seen" not in x_reg:
|
|
|
|
- print(f"{x_reg} wasn't seen in remote-registers")
|
|
|
|
|
|
|
|
def complete_and_diff(reg_map):
|
|
def complete_and_diff(reg_map):
|
|
"""
|
|
"""
|
|
@@ -144,18 +185,19 @@ def complete_and_diff(reg_map):
|
|
changed = 0
|
|
changed = 0
|
|
|
|
|
|
for e in reg_map.values():
|
|
for e in reg_map.values():
|
|
- name = e["name"]
|
|
|
|
- old_val = e["initial"]
|
|
|
|
|
|
+ if "initial" in e and "hidden" not in e:
|
|
|
|
+ name = e["name"]
|
|
|
|
+ old_val = e["initial"]
|
|
|
|
|
|
- try:
|
|
|
|
- new_val = frame.read_register(name)
|
|
|
|
- except:
|
|
|
|
- report(False, f"failed to read {name} at end of run")
|
|
|
|
- continue
|
|
|
|
|
|
+ try:
|
|
|
|
+ new_val = frame.read_register(name)
|
|
|
|
+ except ValueError:
|
|
|
|
+ report(False, f"failed to read {name} at end of run")
|
|
|
|
+ continue
|
|
|
|
|
|
- if new_val != old_val:
|
|
|
|
- print(f"{name} changes from {old_val} to {new_val}")
|
|
|
|
- changed += 1
|
|
|
|
|
|
+ if new_val != old_val:
|
|
|
|
+ print(f"{name} changes from {old_val} to {new_val}")
|
|
|
|
+ changed += 1
|
|
|
|
|
|
# as long as something changed we can be confident its working
|
|
# as long as something changed we can be confident its working
|
|
report(changed > 0, f"{changed} registers were changed")
|
|
report(changed > 0, f"{changed} registers were changed")
|
|
@@ -168,6 +210,7 @@ def run_test():
|
|
|
|
|
|
if reg_map is not None:
|
|
if reg_map is not None:
|
|
crosscheck_remote_xml(reg_map)
|
|
crosscheck_remote_xml(reg_map)
|
|
|
|
+ initial_register_read(reg_map)
|
|
complete_and_diff(reg_map)
|
|
complete_and_diff(reg_map)
|
|
|
|
|
|
|
|
|