def EmitARM32Fib(code_buf): for ins in [ # e92d4030 stm sp!, {r4,r5,lr} dis.InsFromSymbolized("stmdb_update", ["al", "sp", "reglist:16432"]), dis.InsFromSymbolized("cmp_imm", ["al", "r0", "1"]), dis.InsFromSymbolized("b", ["le", "7"]), dis.InsFromSymbolized("mov_imm", ["al", "r4", "0"]), dis.InsFromSymbolized("mov_regimm", ["al", "r5", "r0", "lsl", "0"]), # dis.InsFromSymbolized("sub_imm", ["al", "r0", "r5", "1"]), dis.InsFromSymbolized("bl", ["al", "-8"]), dis.InsFromSymbolized("add_regimm", ["al", "r4", "r4", "r0", "lsl", "0"]), # # dis.InsFromSymbolized("sub_imm", ["al", "r0", "r5", "2"]), dis.InsFromSymbolized("bl", ["al", "-11"]), dis.InsFromSymbolized("add_regimm", ["al", "r0", "r4", "r0", "lsl", "0"]), # e8bd4030 ldm sp!, {r4,r5,pc} dis.InsFromSymbolized("ldmia_update", ["al", "reglist:32816", "sp"]), ]: code_buf.write(a32.Assemble(ins).to_bytes(4, "little"))
def HandleOneInstruction(count: int, line: str, data: int, actual_name: str, actual_ops: List): is_push_pop = "push" in actual_name or "pop" in actual_name ins = arm.Disassemble(data) assert ins.opcode is not None and ins.operands is not None, f"unknown opcode {line}" data2 = arm.Assemble(ins) assert data == data2 expected = dis.RenderInstructionStd(ins) token = expected.split(None, 1) expected_name = token[0] expected_ops = [] if len(token) == 2: expected_ops = [o.strip() for o in token[1].split(",")] actual_name = FixupAliases(actual_name, actual_ops, arm.OPC_FLAG.MULTIPLE in ins.opcode.classes) if actual_name != expected_name: print("BAD NAME", expected_name, actual_name, line) if is_push_pop: expected_ops.pop(0) if OperandsDiffer(actual_ops, expected_ops): print("OPERANDS differ", str(expected_ops), line) operands_str = dis.SymbolizeOperands(ins) operands2 = [dis.UnsymbolizeOperand(o) for o in operands_str] assert tuple(ins.operands) == tuple(operands2), f"{ins.operands} vs {operands2}"
def EmitARM32Mul(code_buf): for ins in [ # "al" predicate is optional dis.InsFromSymbolized("mul", ["r0", "r1", "r0"]), dis.InsFromSymbolized("mov_regimm", ["pc", "lr", "lsl", "0"]) ]: code_buf.write(a32.Assemble(ins).to_bytes(4, "little"))
def AddIns(unit: elf_unit.Unit, ins: a32.Ins): if ins.has_reloc(): sym = unit.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym) unit.AddReloc(ins.reloc_kind, unit.sec_text, sym, ins.operands[ins.reloc_pos]) ins.clear_reloc() unit.sec_text.AddData(a32.Assemble(ins).to_bytes(4, byteorder='little'))
def AddIns(unit: elf_unit.Unit, ins: a32.Ins): if ins.reloc_kind != elf_enum.RELOC_TYPE_ARM.NONE: sym = unit.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym) unit.AddReloc(ins.reloc_kind, unit.sec_text, sym, ins.operands[ins.reloc_pos]) # clear reloc info before proceeding ins.reloc_kind = elf_enum.RELOC_TYPE_ARM.NONE ins.operands[ins.reloc_pos] = 0 unit.sec_text.AddData(a32.Assemble(ins).to_bytes(4, byteorder='little'))
def AddIns(self, ins: arm.Ins): if ins.reloc_kind != elf_enum.RELOC_TYPE_ARM.NONE: sym = self.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym) self.AddReloc(ins.reloc_kind, self.sec_text, sym, ins.operands[ins.reloc_pos]) # clear reloc info before proceeding ins.reloc_kind = elf_enum.RELOC_TYPE_ARM.NONE ins.operands[ins.reloc_pos] = 0 self.sec_text.AddData( arm.Assemble(ins).to_bytes(4, byteorder='little'))
def AppendArmIns(armins: arm.Ins): if armins.reloc_kind != enum_tab.RELOC_TYPE_ARM.NONE: sym = armunit.FindOrAddSymbol(armins.reloc_symbol, armins.is_local_sym) armunit.AddReloc(armins.reloc_kind, sec_text, sym, armins.operands[armins.reloc_pos]) # clear reloc info before proceeding armins.reloc_kind = enum_tab.RELOC_TYPE_ARM.NONE armins.operands[armins.reloc_pos] = 0 sec_text.AddData( arm.Assemble(armins).to_bytes(4, byteorder='little'))
def disass(data): ins = arm.Disassemble(data) if ins.opcode is None: print(f"could not disassemble {data:x}") return print(f"{data:08x}", RenderInstructionStd(ins)) print("OPCODE", ins.opcode.name, ins.opcode.variant) operands_str = SymbolizeOperands(ins) for f, o, o_str in zip(ins.opcode.fields, ins.operands, operands_str): print(f" {f.name:19s} {o_str} ({o})") print() data2 = arm.Assemble(ins) assert data == data2 operands2 = [UnsymbolizeOperand(o) for o in operands_str] assert tuple(ins.operands) == tuple( operands2), f"{ins.operands} vs {operands2}"
def disass(data): ins = a32.Disassemble(data) if ins.opcode is None: print(f"could not disassemble {data:x}") return enum_name, operands_str = symbolic.InsSymbolize(ins) print(f"{data:08x} {enum_name} {', '.join(operands_str)}") for f, o, o_str in zip(ins.opcode.fields, ins.operands, operands_str): print(f" {f.name:25} {o_str:15} ({o})") print() data2 = a32.Assemble(ins) assert data == data2 ins2 = symbolic.InsFromSymbolized(enum_name, operands_str) assert tuple(ins.operands) == tuple( ins2.operands), f"{ins.operands} vs {ins2.operands}"
def batch(): for line in sys.stdin: if not line or line.startswith("#"): continue data = int(line.split()[0], 16) ins = a32.Disassemble(data) if ins.opcode is None: print(f"could not disassemble {data:x}") continue enum_name, ops_str = symbolic.InsSymbolize(ins) print( f"{data:08x} {enum_name}{' ' if ops_str else ''}{', '.join(ops_str)}" ) data2 = a32.Assemble(ins) assert data == data2 ins2 = symbolic.InsFromSymbolized(enum_name, ops_str) assert tuple(ins.operands) == tuple( ins2.operands), f"{ins.operands} vs {ins2.operands}"
def HandleOneInstruction(count: int, line: str, data: int, actual_name: str, actual_ops: List): ins = a32.Disassemble(data) assert ins is not None, f"cannot disassemble [{count}]: {line}" assert ins.opcode is not None and ins.operands is not None, f"unknown opcode {line}" data2 = a32.Assemble(ins) assert data == data2, f"disass mismatch [{ins.opcode.NameForEnum()}] {data:x} vs {data2:x}" actual_name = FixupAliases(ins.opcode, actual_name, actual_ops) if not actual_name.startswith(ins.opcode.official_name): print("BAD NAME", ins.opcode.name, actual_name, line, end="") name, operands_str = symbolic.InsSymbolize(ins) if not OperandsMatch(ins.opcode, actual_name, actual_ops, operands_str): print(f"OPERANDS differ {operands_str} {actual_ops} in line {line}", end="") ins2 = symbolic.InsFromSymbolized(name, operands_str) assert tuple(ins.operands) == tuple(ins2.operands), f"{ins.operands} vs {ins2.operands}"
def EmitARM32Fib(code_buf): for ins in [ # e92d4030 stm sp!, {r4,r5,lr} dis.InsParse("stm", ["PuW", "sp", "reglist:16432"]), dis.InsParse("cmp_imm", ["r0", "1"]), dis.InsParse("b", ["le", "7"]), dis.InsParse("mov_imm", ["r4", "0"]), dis.InsParse("mov_regimm", ["r5", "lsl", "r0", "0"]), # dis.InsParse("sub_imm", ["r0", "r5", "1"]), dis.InsParse("bl", ["lr", "-8"]), dis.InsParse("add_regimm", ["r4", "r4", "lsl", "r0", "0"]), # # dis.InsParse("sub_imm", ["r0", "r5", "2"]), dis.InsParse("bl", ["lr", "-11"]), dis.InsParse("add_regimm", ["r0", "r4", "lsl", "r0", "0"]), # e8bd4030 ldm sp!, {r4,r5,pc} dis.InsParse("ldm", ["reglist:32816", "pUW", "sp"]), ]: code_buf.write(arm.Assemble(ins).to_bytes(4, "little"))
def EmitARM32Mul(code_buf): for ins in [ dis.InsParse("mul", ["r0", "r1", "r0"]), dis.InsParse("mov_regimm", ["r15", "lsl", "r14", "0"]) ]: code_buf.write(arm.Assemble(ins).to_bytes(4, "little"))