/// <summary> /// Searches for J, JAL, and HI16/LO16 pairs. When it finds these and their values will be zeroed out. /// This is to facilitate searching of function signatures. <para/> /// This method buffers its input. /// </summary> /// <param name="insns"></param> /// <returns></returns> public static IReadOnlyList <InstructionWithPc> ZeroRelocatedValues(this IEnumerable <InstructionWithPc> insns) { var analyzer = new Analyzer(); var lastInsn = new Dictionary <int, Instruction>(); var input = insns.ToArray(); var haveHi16 = new bool[32]; var hi16Index = new int[32]; Action pendingAction = null; for (var i = 0; i < input.Length; i++) { var insn = input[i].Instruction; var action = pendingAction; var insnId = insn.Id; var analysis = analyzer.Analyze(insn); var processedId = insn.IsLoadStore ? MipsInstruction.ADDIU : insnId; switch (processedId) { case MipsInstruction.JAL: //pendingAction = reset; goto J; // Fallthrough case MipsInstruction.J: J: insn.Target = 0; break; case MipsInstruction.LUI: haveHi16[insn.GprRt] = true; hi16Index[insn.GprRt] = i; break; // Case for LO16 relos, ADDIU and load/store ops case MipsInstruction.ADDIU: if (haveHi16[insn.GprRs]) { var tmp = input[hi16Index[insn.GprRs]].Instruction; tmp.Immediate = 0; input[hi16Index[insn.GprRs]] = new InstructionWithPc(input[hi16Index[insn.GprRs]].Pc, tmp); insn.Immediate = 0; } haveHi16[insn.GprRs] = false; hi16Index[insn.GprRs] = 0; break; default: if (analysis != null && analysis.DestinationGpr.HasValue) { haveHi16[analysis.DestinationGpr.Value] = false; } break; } input[i] = new InstructionWithPc(input[i].Pc, insn); action?.Invoke(); } return(input); }
void IDiscoveredFunction.AddInstruction(InstructionWithPc iwp) => _instructions.Add(iwp);