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#include "utils/const_value.h" 18 19#include <sstream> 20#include <iomanip> 21 22namespace panda::disasm { 23 24void Disassembler::GetInsInfo(const panda_file::File::EntityId& code_id, MethodInfo* method_info /* out */) const { 25 panda_file::CodeDataAccessor code_accessor(*file_, code_id); 26 27 auto ins_sz = code_accessor.GetCodeSize(); 28 auto ins_arr = code_accessor.GetInstructions(); 29 30 auto bc_ins = BytecodeInstruction(ins_arr); 31 auto bc_ins_last = bc_ins.JumpTo(ins_sz); 32 33 auto instruction_offset = code_id.GetOffset() + static_cast<uint32_t>(code_accessor.GetInstructions() - file_->GetSpanFromId(code_id).data()); 34 while (bc_ins.GetAddress() != bc_ins_last.GetAddress()) { 35 std::stringstream ss; 36 37 ss << "offset: 0x" << std::setfill('0') << std::setw(ark::INSTRUCTION_OFFSET_WIDTH) << std::hex 38 << instruction_offset + bc_ins.GetAddress() - BytecodeInstruction(ins_arr).GetAddress(); 39 ss << ", " << std::setfill('.'); 40 41 BytecodeInstruction::Format format = bc_ins.GetFormat(); 42 43 switch (format) { 44% Panda::formats.each do |fmt| 45 case BytecodeInstruction::Format::<%= fmt.pretty.upcase %>: 46 ss << std::setw(ark::INSTRUCTION_FORMAT_WIDTH) << std::left << "[<%= fmt.pretty.upcase %>]"; 47 break; 48% end 49 default: 50 break; 51 } 52 53 ss << "["; 54 55 const uint8_t* pc = bc_ins.GetAddress(); 56 const size_t sz = bc_ins.GetSize(); 57 58 for (size_t i = 0; i < sz; i++) { 59 ss << "0x" << std::setw(ark::INSTRUCTION_VALUE_WIDTH) << std::setfill('0') << std::right << std::hex << static_cast<int>(pc[i]); 60 61 if (i != sz - 1) { 62 ss << " "; 63 } 64 } 65 66 ss << "]"; 67 68 method_info->instructions_info.push_back(ss.str()); 69 70 bc_ins = bc_ins.GetNext(); 71 } 72 73 return; 74} 75 76} // namespace panda::disasm