/*
* 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 "utils/const_value.h"
#include <sstream>
#include <iomanip>
namespace panda::disasm {
void Disassembler::GetInsInfo(const panda_file::File::EntityId& code_id, MethodInfo* method_info /* out */) const {
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);
auto instruction_offset = code_id.GetOffset() + static_cast<uint32_t>(code_accessor.GetInstructions() - file_->GetSpanFromId(code_id).data());
while (bc_ins.GetAddress() != bc_ins_last.GetAddress()) {
std::stringstream ss;
ss << "offset: 0x" << std::setfill('0') << std::setw(ark::INSTRUCTION_OFFSET_WIDTH) << std::hex
<< instruction_offset + 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(ark::INSTRUCTION_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(ark::INSTRUCTION_VALUE_WIDTH) << std::setfill('0') << std::right << std::hex << static_cast<int>(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