1/* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "disassembler.h" 17 18#include <sstream> 19#include <iomanip> 20 21namespace panda::disasm { 22 23void Disassembler::GetInsInfo(const panda_file::File::EntityId& code_id, MethodInfo* method_info /* out */) const { 24 const static size_t FORMAT_WIDTH = 20; 25 const static size_t INSTRUCTION_WIDTH = 4; 26 27 panda_file::CodeDataAccessor code_accessor(*file_, code_id); 28 29 auto ins_sz = code_accessor.GetCodeSize(); 30 auto ins_arr = code_accessor.GetInstructions(); 31 32 auto bc_ins = BytecodeInstruction(ins_arr); 33 auto bc_ins_last = bc_ins.JumpTo(ins_sz); 34 35 while (bc_ins.GetAddress() != bc_ins_last.GetAddress()) { 36 std::stringstream ss; 37 38 ss << "offset: 0x" << std::setfill('0') << std::setw(4) << std::hex 39 << code_id.GetOffset() + bc_ins.GetAddress() - BytecodeInstruction(ins_arr).GetAddress(); 40 ss << ", " << std::setfill('.'); 41 42 BytecodeInstruction::Format format = bc_ins.GetFormat(); 43 44 switch (format) { 45% Panda::formats.each do |fmt| 46 case BytecodeInstruction::Format::<%= fmt.pretty.upcase %>: 47 ss << std::setw(FORMAT_WIDTH) << std::left << "[<%= fmt.pretty.upcase %>]"; 48 break; 49% end 50 default: 51 break; 52 } 53 54 ss << "["; 55 56 const uint8_t* pc = bc_ins.GetAddress(); 57 const size_t sz = bc_ins.GetSize(); 58 59 for (size_t i = 0; i < sz; i++) { 60 ss << "0x" << std::setw(INSTRUCTION_WIDTH) << std::setfill('0') << std::right << std::hex << static_cast<int>(pc[i]); 61 62 if (i != sz - 1) { 63 ss << " "; 64 } 65 } 66 67 ss << "]"; 68 69 method_info->instructions_info.push_back(ss.str()); 70 71 bc_ins = bc_ins.GetNext(); 72 } 73 74 return; 75} 76 77} // namespace panda::disasm