• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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