|
1 | 1 | import logging |
2 | 2 | from typing import Union |
| 3 | +from xml.etree.ElementTree import Element |
3 | 4 |
|
4 | 5 | from .arch import Arch, Endness, Register |
5 | 6 | from .archerror import ArchError |
@@ -96,16 +97,7 @@ def find_matching_cid(language, desired): |
96 | 97 | archinfo_regs[sp_reg.lower()].alias_names += ("sp",) |
97 | 98 |
|
98 | 99 | # Get return offset |
99 | | - proto_tags = cspec.find("default_proto") |
100 | | - if proto_tags is not None and len(proto_tags) >= 1: |
101 | | - proto_tag = proto_tags[0] |
102 | | - output_tags = proto_tag.find("output") |
103 | | - if output_tags is not None and len(output_tags) >= 1: |
104 | | - output_tag = output_tags[0] |
105 | | - output_register_tag = output_tag.find("register") |
106 | | - if output_register_tag is not None: |
107 | | - output_reg = output_register_tag.attrib["name"] |
108 | | - ret_offset = RegisterOffset(ctx.registers[output_reg].offset) |
| 100 | + ret_offset = self.__get_ret_offset(cspec, ctx) |
109 | 101 |
|
110 | 102 | if sp_offset is None: |
111 | 103 | log.warning("Unknown stack pointer register offset?") |
@@ -154,3 +146,28 @@ def disasm(self, bytestring, addr=0, thumb=False): |
154 | 146 | ctx.setVariableDefault("TMode", 1 if thumb else 0) |
155 | 147 | instructions = ctx.disassemble(bytestring, addr, 0, len(bytestring), 0).instructions |
156 | 148 | return "\n".join(f"{insn.addr.offset:#x}:\t{insn.mnem} {insn.body}" for insn in instructions) |
| 149 | + |
| 150 | + @staticmethod |
| 151 | + def __get_ret_offset(cspec: Element, ctx: pypcode.Context): |
| 152 | + proto_tags = cspec.find("default_proto") |
| 153 | + if proto_tags is None or len(proto_tags) == 0: |
| 154 | + return RegisterOffset(0) |
| 155 | + |
| 156 | + proto_tag = proto_tags[0] |
| 157 | + output_tags = proto_tag.find("output") |
| 158 | + if output_tags is None: |
| 159 | + return RegisterOffset(0) |
| 160 | + |
| 161 | + output_pentries_tag = output_tags.findall("pentry") |
| 162 | + for pentry_tag in output_pentries_tag: |
| 163 | + if "metatype" in pentry_tag.attrib: |
| 164 | + continue |
| 165 | + |
| 166 | + output_register_tag = pentry_tag.find("register") |
| 167 | + if output_register_tag is None: |
| 168 | + continue |
| 169 | + |
| 170 | + output_reg = output_register_tag.attrib["name"] |
| 171 | + return RegisterOffset(ctx.registers[output_reg].offset) |
| 172 | + |
| 173 | + return RegisterOffset(0) |
0 commit comments