diff --git a/irdb-libs/ir_builders/fill_in_indtargs.cpp b/irdb-libs/ir_builders/fill_in_indtargs.cpp index 42aef929f9c499ccf789fb7da8dfe4128cb36be3..7bb7b8838108c2b72c4f6a1224e5ef779575ceb2 100644 --- a/irdb-libs/ir_builders/fill_in_indtargs.cpp +++ b/irdb-libs/ir_builders/fill_in_indtargs.cpp @@ -2476,14 +2476,14 @@ V2: * Now try to find an LEA that loads the table base address into a register. */ auto lea_string1 = string("lea "); - auto lea_string2 = string("do_not_mach "); // may be updated later for searching for the index reg + auto lea_string2 = string("do not match anything "); // may be updated later for searching for the index reg const auto d6 = DecodedInstruction_t::factory(I6); const auto d6_op1 = d6->getOperand(1); const auto d6_op1_is_mem = d6_op1->isMemory(); auto cmp_str = string(" do not match anything "); // to be updated inside if statement below auto bound_stopif = string(" do not match anything "); // to be updated inside if statement below auto and_str = string(" do not match anything "); // to be updated inside if statement below - int32_t index_reg_no = -1; // to be updated inside if statement below + int32_t index_reg_no = -1; // to be updated inside if statement below if (d6_op1_is_mem) { @@ -2502,9 +2502,9 @@ V2: return; index_reg_no = (int32_t) d6->getOperand(1)->getIndexRegister(); const auto index_reg_64bit = regNoToX8664Reg(index_reg_no); - const auto index_reg_32bit = regNoToX8632Reg(index_reg_no); - const auto index_reg_16bit = regNoToX8616Reg(index_reg_no); - const auto index_reg_8bit = regNoToX868Reg(index_reg_no); + const auto index_reg_32bit = regNoToX8632Reg(index_reg_no); + const auto index_reg_16bit = regNoToX8616Reg(index_reg_no); + const auto index_reg_8bit = regNoToX868Reg(index_reg_no); cmp_str = "cmp (" + index_reg_8bit + "|" + index_reg_16bit + "|" + index_reg_32bit + "|" + index_reg_64bit + ")"; @@ -2554,6 +2554,11 @@ V2: const auto allow_unpins = found_leas.size() == 1; for (auto I5_cur : found_leas) { + if (getenv("IB_VERBOSE") || getenv("DEBUG")) + { + cout << "Considering jump at " << hex << I8->getAddress()->getVirtualOffset() + << " with lea at " << I5_cur->getAddress()->getVirtualOffset() << endl; + } PIC_switch_icc_computed_iterate(firp,I5_cur, I6, I8, table_entry_multiplier); PIC_switch_table64_iterate_table( firp, @@ -2672,10 +2677,10 @@ V2: const bool allow_unpins, const int32_t index_reg_no) { - // Copy the strings for potential replace later on - string cmp_str = p_cmp_str; - string bound_stopif = p_bound_stopif; - string and_str = p_and_str; + // Copy the strings for potential replace later on + string cmp_str = p_cmp_str; + string bound_stopif = p_bound_stopif; + string and_str = p_and_str; auto table_load_disasm = DecodedInstruction_t::factory(lea_for_table_base); @@ -2731,158 +2736,163 @@ V2: // cannot find a bounds check on the table size. // auto table_size = 512U; - if(getenv("MAX_JUMP_TABLE_CLAMP_SIZE")){ - auto temp_table_size = strtol(getenv("MAX_JUMP_TABLE_CLAMP_SIZE"), nullptr, 10); - if(temp_table_size > 0){ - table_size = temp_table_size; - } - } + if(getenv("MAX_JUMP_TABLE_CLAMP_SIZE")){ + auto temp_table_size = strtol(getenv("MAX_JUMP_TABLE_CLAMP_SIZE"), nullptr, 10); + if(temp_table_size > 0){ + table_size = temp_table_size; + } + } auto found_table_size = false; auto I1 = static_cast<Instruction_t *>(nullptr); - auto intermediate_write_instr = static_cast<Instruction_t *>(nullptr); - bool found_cmp = false; - bool found_and = false; - auto search_start_instr = table_load_instruction; - - // Check whether the index register has been renamed between bounds-check and use - // Only do this once - for( auto i = 0; i < 2 ; i++) { - found_cmp = backup_until_or_move(cmp_str, I1, search_start_instr, intermediate_write_instr, - bound_stopif, "^jne$|^je$|^jeq$"); - if (!found_cmp && intermediate_write_instr != nullptr) { - auto temp = intermediate_write_instr->getBaseID(); // Remember BaseId for sanity check - assert(temp != IRDB_SDK::BaseObj_t::NOT_IN_DATABASE); - found_and = backup_until_or_move(and_str, I1, search_start_instr, intermediate_write_instr, - bound_stopif); - if (!found_and && intermediate_write_instr != nullptr) { - // We should find the same possible write location for both checks - assert(temp == intermediate_write_instr->getBaseID()); - auto decoded_instr = DecodedInstruction_t::factory(intermediate_write_instr); - if( - // Is a reg to reg move - decoded_instr->getMnemonic().rfind("mov", 0) != string::npos && - decoded_instr->getOperand(0)->isRegister() && decoded_instr->getOperand(1)->isRegister() - // The source register is a equal to the target (modulo size differences) - && decoded_instr->getOperand(0)->getRegNumber() == decoded_instr->getOperand(1)->getRegNumber() - ){ - // If we have a move from self to self, restart searching from here, this is a case where there - // are multiple redirects like so: - // 0003bc30 cmp r12b, 0x21 - // ... - // 0003bc3a movzx ecx, r12w <-- this is the actual move from temporary - // 0003bc3e movzx ecx, cl <-- we detect this as the move from temporary - // ... - // 0003bc48 movsxd rcx, dword [rdx+rcx*4] - - if (getenv("IB_VERBOSE") || getenv("DEBUG")) { - cout << "DEBUG: checking for register rename for index reg of jumptable @ 0x" - << hex << table_load_instruction->getAddress()->getVirtualOffset() << endl; - } - - search_start_instr = intermediate_write_instr; - continue; - } else { - // We have either found what we were looking for or hit a dead end - // We wanted to find a code pattern like this, which copies the index from a temporary register - // into the index reg: - // - // cmp rax, 0x1234 - // ... - // mov rbx, rax - // mov ..., [ ... rbx*4 ...] - - search_start_instr = intermediate_write_instr; - break; - } - } - } - if (found_and || found_cmp) - break; - } + auto intermediate_write_instr = static_cast<Instruction_t *>(nullptr); + bool found_cmp = false; + bool found_and = false; + auto search_start_instr = table_load_instruction; + + // Check whether the index register has been renamed between bounds-check and use + // Only do this once + for( auto i = 0; false && i < 2 ; i++) + { + found_cmp = backup_until_or_move(cmp_str, I1, search_start_instr, intermediate_write_instr, + bound_stopif, "^jne$|^je$|^jeq$"); + if (!found_cmp && intermediate_write_instr != nullptr) + { + auto temp = intermediate_write_instr->getBaseID(); // Remember BaseId for sanity check + assert(temp != IRDB_SDK::BaseObj_t::NOT_IN_DATABASE); + found_and = backup_until_or_move(and_str, I1, search_start_instr, intermediate_write_instr, bound_stopif); + if (!found_and && intermediate_write_instr != nullptr) + { + // We should find the same possible write location for both checks + assert(temp == intermediate_write_instr->getBaseID()); + auto decoded_instr = DecodedInstruction_t::factory(intermediate_write_instr); + if( + // Is a reg to reg move + decoded_instr->getMnemonic().rfind("mov", 0) != string::npos && + decoded_instr->getOperand(0)->isRegister() && decoded_instr->getOperand(1)->isRegister() + // The source register is a equal to the target (modulo size differences) + && decoded_instr->getOperand(0)->getRegNumber() == decoded_instr->getOperand(1)->getRegNumber() + ){ + // If we have a move from self to self, restart searching from here, this is a case where there + // are multiple redirects like so: + // 0003bc30 cmp r12b, 0x21 + // ... + // 0003bc3a movzx ecx, r12w <-- this is the actual move from temporary + // 0003bc3e movzx ecx, cl <-- we detect this as the move from temporary + // ... + // 0003bc48 movsxd rcx, dword [rdx+rcx*4] + + if (getenv("IB_VERBOSE") || getenv("DEBUG")) + { + cout << "DEBUG: checking for register rename for index reg of jumptable @ 0x" + << hex << table_load_instruction->getAddress()->getVirtualOffset() << endl; + } + + search_start_instr = intermediate_write_instr; + continue; + } + else + { + // We have either found what we were looking for or hit a dead end + // We wanted to find a code pattern like this, which copies the index from a temporary register + // into the index reg: + // + // cmp rax, 0x1234 + // ... + // mov rbx, rax + // mov ..., [ ... rbx*4 ...] + + search_start_instr = intermediate_write_instr; + break; + } + } + } + if (found_and || found_cmp) + break; + } #if 0 - killing the following of a move instruction, which generally would be good because of this case: + killing the following of a move instruction, which generally would be good because of this case: - 0x000000000001bf9b <+1131>: cmp eax,0x12 - 0x000000000001bf9e <+1134>: ja 0x1ccf8 <process_section_headers+4552> - 0x000000000001bfa4 <+1140>: cmp eax,0x1 - 0x000000000001bfa7 <+1143>: jbe 0x1c6e0 <process_section_headers+2992> - 0x000000000001bfad <+1149>: mov ecx,eax - 0x000000000001bfaf <+1151>: cmp eax,0x12 - 0x000000000001bfb2 <+1154>: ja 0x1c6e2 <process_section_headers+2994> - 0x000000000001bfb8 <+1160>: lea rdi,[rip+0x66305] # 0x822c4 - 0x000000000001bfbf <+1167>: movsxd rdx,DWORD PTR [rdi+rcx*4] - 0x000000000001bfc3 <+1171>: add rdx,rdi - 0x000000000001bfc6 <+1174>: notrack jmp rdx + 0x000000000001bf9b <+1131>: cmp eax,0x12 + 0x000000000001bf9e <+1134>: ja 0x1ccf8 <process_section_headers+4552> + 0x000000000001bfa4 <+1140>: cmp eax,0x1 + 0x000000000001bfa7 <+1143>: jbe 0x1c6e0 <process_section_headers+2992> + 0x000000000001bfad <+1149>: mov ecx,eax + 0x000000000001bfaf <+1151>: cmp eax,0x12 + 0x000000000001bfb2 <+1154>: ja 0x1c6e2 <process_section_headers+2994> + 0x000000000001bfb8 <+1160>: lea rdi,[rip+0x66305] # 0x822c4 + 0x000000000001bfbf <+1167>: movsxd rdx,DWORD PTR [rdi+rcx*4] + 0x000000000001bfc3 <+1171>: add rdx,rdi + 0x000000000001bfc6 <+1174>: notrack jmp rdx - Zipr followed the move back and found the cmp eax,0x1 and detected the switch table size as 0x1. very bad. - it is not clear whether 0x1c6e0 falls through to the switch, but it very well could. We really need to stop - looking for the switch table size at any cmp instruction unless we can determine better with the above. + Zipr followed the move back and found the cmp eax,0x1 and detected the switch table size as 0x1. very bad. + it is not clear whether 0x1c6e0 falls through to the switch, but it very well could. We really need to stop + looking for the switch table size at any cmp instruction unless we can determine better with the above. #endif - if(false && !found_cmp && !found_and && intermediate_write_instr != nullptr - && intermediate_write_instr->getDisassembly().rfind("mov", 0) != string::npos) { - auto decoded_instr = DecodedInstruction_t::factory(intermediate_write_instr); - if(decoded_instr->getOperand(1)->isRegister()){ - // We found a direct move from a temporary register into the index register. - // Do the same search again starting from this move and check for a comparison with the temporary register - const auto index_reg_64bit = regNoToX8664Reg(index_reg_no); - const auto index_reg_32bit = regNoToX8632Reg(index_reg_no); - const auto temp_index_reg_64bit = - regNoToX8664Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); - const auto temp_index_reg_32bit = - regNoToX8632Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); - const auto temp_index_reg_16bit = - regNoToX8616Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); - const auto temp_index_reg_8bit = - regNoToX868Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); - - if(index_reg_32bit.empty() || index_reg_64bit.empty()){ - cout << "WARNING: Could not detect index register for table load at " << - hex << table_load_instruction->getAddress()->getVirtualOffset() << endl; - } else if (temp_index_reg_32bit.empty() || temp_index_reg_64bit.empty()) { - cout << "WARNING: Could not detect new temporary index register for move into index reg at " << - hex << intermediate_write_instr->getAddress()->getVirtualOffset() << endl; - } else { - auto to_replace = "\\([^()]*" + index_reg_32bit + "\\|" + index_reg_64bit + "\\)"; - auto to_replace_regex = std::regex(to_replace); - auto replace_with = "(" + temp_index_reg_8bit + "|" + temp_index_reg_16bit + "|" + temp_index_reg_32bit + "|" + temp_index_reg_64bit + ")"; - if (getenv("IB_VERBOSE") || getenv("DEBUG")) { - cout << "DEBUG: replacing index reg " << to_replace << " with " << replace_with << " because of instruction '" - << intermediate_write_instr->getDisassembly() << "' @ 0x" - << hex << intermediate_write_instr->getAddress()->getVirtualOffset() << endl; - } - - - cmp_str = std::regex_replace(cmp_str, to_replace_regex, replace_with); - bound_stopif = std::regex_replace(bound_stopif, to_replace_regex, replace_with); - and_str = std::regex_replace(and_str, to_replace_regex, replace_with); - - if (getenv("IB_VERBOSE") || getenv("DEBUG")) { - cout << "After replacement:" << endl << cmp_str << endl << bound_stopif << endl << and_str - << endl; - } - } - } else { - if (getenv("IB_VERBOSE") || getenv("DEBUG")) { - cout << "DEBUG: source operand for move to index reg is not a register '" - << intermediate_write_instr->getDisassembly() << "' @ 0x" - << hex << intermediate_write_instr->getAddress()->getVirtualOffset() << endl; - } - // We have hit a dead end for now, restore initial state - // This is probably a move from memory, where the index was compared in memory - // or before moving it to memory (an example is shown in the known issues list below) - // TODO: Think about handling this case - search_start_instr = table_load_instruction; - } - } + if(false && !found_cmp && !found_and && intermediate_write_instr != nullptr && intermediate_write_instr->getDisassembly().rfind("mov", 0) != string::npos) + { + auto decoded_instr = DecodedInstruction_t::factory(intermediate_write_instr); + if(decoded_instr->getOperand(1)->isRegister()){ + // We found a direct move from a temporary register into the index register. + // Do the same search again starting from this move and check for a comparison with the temporary register + const auto index_reg_64bit = regNoToX8664Reg(index_reg_no); + const auto index_reg_32bit = regNoToX8632Reg(index_reg_no); + const auto temp_index_reg_64bit = + regNoToX8664Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); + const auto temp_index_reg_32bit = + regNoToX8632Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); + const auto temp_index_reg_16bit = + regNoToX8616Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); + const auto temp_index_reg_8bit = + regNoToX868Reg((int32_t) decoded_instr->getOperand(1)->getRegNumber()); + + if(index_reg_32bit.empty() || index_reg_64bit.empty()){ + cout << "WARNING: Could not detect index register for table load at " << + hex << table_load_instruction->getAddress()->getVirtualOffset() << endl; + } else if (temp_index_reg_32bit.empty() || temp_index_reg_64bit.empty()) { + cout << "WARNING: Could not detect new temporary index register for move into index reg at " << + hex << intermediate_write_instr->getAddress()->getVirtualOffset() << endl; + } else { + auto to_replace = "\\([^()]*" + index_reg_32bit + "\\|" + index_reg_64bit + "\\)"; + auto to_replace_regex = std::regex(to_replace); + auto replace_with = "(" + temp_index_reg_8bit + "|" + temp_index_reg_16bit + "|" + temp_index_reg_32bit + "|" + temp_index_reg_64bit + ")"; + if (getenv("IB_VERBOSE") || getenv("DEBUG")) { + cout << "DEBUG: replacing index reg " << to_replace << " with " << replace_with << " because of instruction '" + << intermediate_write_instr->getDisassembly() << "' @ 0x" + << hex << intermediate_write_instr->getAddress()->getVirtualOffset() << endl; + } + + + cmp_str = std::regex_replace(cmp_str, to_replace_regex, replace_with); + bound_stopif = std::regex_replace(bound_stopif, to_replace_regex, replace_with); + and_str = std::regex_replace(and_str, to_replace_regex, replace_with); + + if (getenv("IB_VERBOSE") || getenv("DEBUG")) { + cout << "After replacement:" << endl << cmp_str << endl << bound_stopif << endl << and_str + << endl; + } + } + } else { + if (getenv("IB_VERBOSE") || getenv("DEBUG")) { + cout << "DEBUG: source operand for move to index reg is not a register '" + << intermediate_write_instr->getDisassembly() << "' @ 0x" + << hex << intermediate_write_instr->getAddress()->getVirtualOffset() << endl; + } + // We have hit a dead end for now, restore initial state + // This is probably a move from memory, where the index was compared in memory + // or before moving it to memory (an example is shown in the known issues list below) + // TODO: Think about handling this case + search_start_instr = table_load_instruction; + } + } if (backup_until(cmp_str, I1, search_start_instr, bound_stopif,"^jne$|^je$|^jeq$")) { @@ -2891,8 +2901,10 @@ V2: // notes on table size: // readelf on ubuntu20 has a table size of 4. + cout << "cmp_str = " << cmp_str << endl; + cout << "bound_stopif = " << bound_stopif << endl; cout << "pic64: found cmp-type I1 ('" << d1->getDisassembly() << "'), with table_size=" - << table_size << " at " << hex << I1->getAddress()->getVirtualOffset() << "\n"; + << table_size << " at " << hex << I1->getAddress()->getVirtualOffset() << "\n"; found_table_size = true; } else if (backup_until(and_str, I1, search_start_instr, bound_stopif)) @@ -2909,36 +2921,36 @@ V2: else { cout << "pic64: found and-type I1 ('" << d1->getDisassembly() << "'), but could not find size of switch table" - << "\n"; + << "\n"; } } else { - /* FIXME: Known Issues - We currently miss cases with default values enforced by byte loads and shifts: - 0004326d movzx eax, byte [r14] <-- eax <= 255 - 00043271 mov rdx, rax - 00043274 shr rdx, 0x6 <-- rdx <= (255 >> 6) = 3 - 00043278 lea rsi, [rel jump_table_ffae4] - 0004327f movsxd rdx, dword [rsi+rdx*4] - 00043283 add rdx, rsi - 00043286 jmp rdx - -- - We also miss cases where index and base reg are switched in one of the operations and the index is - compared in memory - cmp DWORD PTR [rbp-0x474],0x1d <-- check for default case - ja 0x55be3 - mov eax,DWORD PTR [rbp-0x474] <-- load index into table (without respecting the entry size) - lea rdx, [4*rax] <-- calculate index in table while respecting the entry size - lea rax,[rip+0xa3286] <-- load base - mov eax,DWORD PTR [rdx+rax] <-- load jump offset from table - cdqe - lea rdx,[rip+0xa327a] <-- load base - add rax,rdx - jmp rax - */ + /* FIXME: Known Issues + We currently miss cases with default values enforced by byte loads and shifts: + 0004326d movzx eax, byte [r14] <-- eax <= 255 + 00043271 mov rdx, rax + 00043274 shr rdx, 0x6 <-- rdx <= (255 >> 6) = 3 + 00043278 lea rsi, [rel jump_table_ffae4] + 0004327f movsxd rdx, dword [rsi+rdx*4] + 00043283 add rdx, rsi + 00043286 jmp rdx + -- + We also miss cases where index and base reg are switched in one of the operations and the index is + compared in memory + cmp DWORD PTR [rbp-0x474],0x1d <-- check for default case + ja 0x55be3 + mov eax,DWORD PTR [rbp-0x474] <-- load index into table (without respecting the entry size) + lea rdx, [4*rax] <-- calculate index in table while respecting the entry size + lea rax,[rip+0xa3286] <-- load base + mov eax,DWORD PTR [rdx+rax] <-- load jump offset from table + cdqe + lea rdx,[rip+0xa327a] <-- load base + add rax,rdx + jmp rax + */ cout << "pic64: could not find size of switch table for table load at " << - hex << table_load_instruction->getAddress()->getVirtualOffset() << endl; + hex << table_load_instruction->getAddress()->getVirtualOffset() << endl; } const auto table_start_addr_it = direct_addresses.find(table_start_address); @@ -2950,7 +2962,7 @@ V2: const auto dont_overflow_size = static_cast<uint32_t>((next_direct_address - table_start_address) / table_entry_size)-1; table_size = min(table_size, dont_overflow_size); cout << "pic64: clamped switch table via direct_address match of address=" - << hex << next_direct_address << '\n'; + << hex << next_direct_address << '\n'; } cout << "pic64: Setting table size = " << dec << table_size << '\n'; @@ -2974,9 +2986,9 @@ V2: const auto table_entry_ptr = reinterpret_cast<const char *>(&(secdata[offset])); const auto raw_table_entry = table_entry_size == 1 ? VirtualOffset_t(*reinterpret_cast<const int8_t *>(table_entry_ptr)) : table_entry_size == 2 ? VirtualOffset_t(*reinterpret_cast<const int16_t *>(table_entry_ptr)) - : table_entry_size == 4 ? VirtualOffset_t(*reinterpret_cast<const int32_t *>(table_entry_ptr)) - : table_entry_size == 8 ? VirtualOffset_t(*reinterpret_cast<const int64_t *>(table_entry_ptr)) - : throw invalid_argument("Cannot detect displacement size to load value "); + : table_entry_size == 4 ? VirtualOffset_t(*reinterpret_cast<const int32_t *>(table_entry_ptr)) + : table_entry_size == 8 ? VirtualOffset_t(*reinterpret_cast<const int64_t *>(table_entry_ptr)) + : throw invalid_argument("Cannot detect displacement size to load value "); const auto table_entry = raw_table_entry * table_entry_multiplier; if (!possible_target(D1 + table_entry, 0 /* from addr unknown */, switch_prov)) @@ -2990,24 +3002,24 @@ V2: } const auto ibtarget = doDisassemblyForIBT( - firp, // the IR. - newInstructions, // output: the set of instructions that - D1 + table_entry, // jump target from table.:w - dispatch_insn->getFunction(), // the function to add new instructions to. - dispatch_insn->getAddress()->getFileID(), // the file to add to. - exeiop, // a handle to the executable so we can read raw data. - true, // do pin - pSec->isExecutable() // table in text - ); + firp, // the IR. + newInstructions, // output: the set of instructions that + D1 + table_entry, // jump target from table.:w + dispatch_insn->getFunction(), // the function to add new instructions to. + dispatch_insn->getAddress()->getFileID(), // the file to add to. + exeiop, // a handle to the executable so we can read raw data. + true, // do pin + pSec->isExecutable() // table in text + ); if (ibtarget) { if (getenv("IB_VERBOSE")) { cout << "jmp table [" << entry << "]: " << hex << table_entry << dec << endl; cout << "Found possible table entry, at: " << std::hex << dispatch_insn->getAddress()->getVirtualOffset() - << " insn: " << table_load_disasm->getDisassembly() << " d1: " - << D1 << " table_entry:" << table_entry - << " target: " << D1 + table_entry << std::dec << endl; + << " insn: " << table_load_disasm->getDisassembly() << " d1: " + << D1 << " table_entry:" << table_entry + << " target: " << D1 + table_entry << std::dec << endl; } ibtargets.insert(ibtarget); } @@ -3033,7 +3045,7 @@ V2: if (!found_table_error && found_table_size) { cout << "pic64: found complete switch table for " << hex << dispatch_insn->getAddress()->getVirtualOffset() - << " detected ibtp_switchtable_type4" << endl; + << " detected ibtp_switchtable_type4" << endl; addSwitchTableScoop(firp, max_valid_table_entry, table_entry_size, D1 + d6_displ, exeiop, table_load_instruction, D1, allow_unpins); if (allow_unpins) jmptables[dispatch_insn].setAnalysisStatus(iasAnalysisComplete); @@ -3041,21 +3053,21 @@ V2: else { cout << "pic64: found incomplete switch table for " << hex << dispatch_insn->getAddress()->getVirtualOffset() - << " detected ibtp_switchtable_type4." - << " found_table_error=" << found_table_error - << endl; + << " detected ibtp_switchtable_type4." + << " found_table_error=" << found_table_error + << endl; addSwitchTableScoop(firp, max_valid_table_entry, table_entry_size, D1 + d6_displ, exeiop, table_load_instruction, D1, false); } } else { cout << "pic64: INVALID switch table detected for " << hex - << dispatch_insn->getDisassembly() << "@" << dispatch_insn->getAddress()->getVirtualOffset() - << " type=ibtp_switchtable_type4 with lea_insn=" - << lea_for_table_base->getAddress()->getVirtualOffset() << "@" << lea_for_table_base->getDisassembly() - << " found_table_error=" << found_table_error - << " ibtargets.size() == " << ibtargets.size() - << endl; + << dispatch_insn->getDisassembly() << "@" << dispatch_insn->getAddress()->getVirtualOffset() + << " type=ibtp_switchtable_type4 with lea_insn=" + << lea_for_table_base->getAddress()->getVirtualOffset() << "@" << lea_for_table_base->getDisassembly() + << " found_table_error=" << found_table_error + << " ibtargets.size() == " << ibtargets.size() + << endl; // try the next L5. return; } @@ -3072,17 +3084,17 @@ V2: * I8: jmp rdx * */ - /* TODO: check whether this is also impacted by the compiler behavior to rename the index before using it - * cmp eax,0x23 + /* TODO: check whether this is also impacted by the compiler behavior to rename the index before using it + * cmp eax,0x23 * mov eax, eax <============== THIS - * ja 0x1400066d3 + * ja 0x1400066d3 * lea_for_table_base: lea rcx,[rip+0xffffffffffff9a7d] # 0x140000000 * I6_2 movzx eax,BYTE PTR [rcx+rax*1+0x6a50] - * mov ebx, eax <============== OR THIS + * mov ebx, eax <============== OR THIS * I6: mov edx,DWORD PTR [rcx+rbx*4+0x6a34] * I7: add rdx,rcx * I8: jmp rdx - */ + */ // sanity check that I understand the variables of this function properly. // and grab the index reg