• 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
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