/* * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "disassembler.h" #include #include namespace panda::disasm { void Disassembler::GetInsInfo(const panda_file::File::EntityId& code_id, MethodInfo* method_info /* out */) const { const static size_t FORMAT_WIDTH = 20; const static size_t INSTRUCTION_WIDTH = 4; panda_file::CodeDataAccessor code_accessor(*file_, code_id); auto ins_sz = code_accessor.GetCodeSize(); auto ins_arr = code_accessor.GetInstructions(); auto bc_ins = BytecodeInstruction(ins_arr); auto bc_ins_last = bc_ins.JumpTo(ins_sz); while (bc_ins.GetAddress() != bc_ins_last.GetAddress()) { std::stringstream ss; ss << "offset: 0x" << std::setfill('0') << std::setw(4) << std::hex << code_id.GetOffset() + bc_ins.GetAddress() - BytecodeInstruction(ins_arr).GetAddress(); ss << ", " << std::setfill('.'); BytecodeInstruction::Format format = bc_ins.GetFormat(); switch (format) { % Panda::formats.each do |fmt| case BytecodeInstruction::Format::<%= fmt.pretty.upcase %>: ss << std::setw(FORMAT_WIDTH) << std::left << "[<%= fmt.pretty.upcase %>]"; break; % end default: break; } ss << "["; const uint8_t* pc = bc_ins.GetAddress(); const size_t sz = bc_ins.GetSize(); for (size_t i = 0; i < sz; i++) { ss << "0x" << std::setw(INSTRUCTION_WIDTH) << std::setfill('0') << std::right << std::hex << static_cast(pc[i]); if (i != sz - 1) { ss << " "; } } ss << "]"; method_info->instructions_info.push_back(ss.str()); bc_ins = bc_ins.GetNext(); } return; } } // namespace panda::disasm