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#ifndef LIBPANDAFILE_DEBUG_HELPERS_H 17#define LIBPANDAFILE_DEBUG_HELPERS_H 18 19#include "debug_data_accessor-inl.h" 20#include "file.h" 21#include "file_items.h" 22#include "method_data_accessor-inl.h" 23#include "line_number_program.h" 24#include "libpandabase/utils/span.h" 25 26namespace panda::panda_file::debug_helpers { 27 28class BytecodeOffsetResolver { 29public: 30 BytecodeOffsetResolver(panda_file::LineProgramState *state, uint32_t bc_offset) 31 : state_(state), bc_offset_(bc_offset), prev_line_(state->GetLine()), line_(0) 32 { 33 } 34 35 ~BytecodeOffsetResolver() = default; 36 37 DEFAULT_MOVE_SEMANTIC(BytecodeOffsetResolver); 38 DEFAULT_COPY_SEMANTIC(BytecodeOffsetResolver); 39 40 panda_file::LineProgramState *GetState() const 41 { 42 return state_; 43 } 44 45 uint32_t GetLine() const 46 { 47 return line_; 48 } 49 50 void ProcessBegin() const {} 51 52 void ProcessEnd() 53 { 54 if (line_ == 0) { 55 line_ = state_->GetLine(); 56 } 57 } 58 59 bool HandleAdvanceLine(int32_t line_diff) const 60 { 61 state_->AdvanceLine(line_diff); 62 return true; 63 } 64 65 bool HandleAdvancePc(uint32_t pc_diff) const 66 { 67 state_->AdvancePc(pc_diff); 68 return true; 69 } 70 71 bool HandleSetFile([[maybe_unused]] uint32_t source_file_id) const 72 { 73 return true; 74 } 75 76 bool HandleSetSourceCode([[maybe_unused]] uint32_t source_code_id) const 77 { 78 return true; 79 } 80 81 bool HandleSetPrologueEnd() const 82 { 83 return true; 84 } 85 86 bool HandleSetEpilogueBegin() const 87 { 88 return true; 89 } 90 91 bool HandleStartLocal([[maybe_unused]] int32_t reg_number, [[maybe_unused]] uint32_t name_id, 92 [[maybe_unused]] uint32_t type_id) const 93 { 94 return true; 95 } 96 97 bool HandleStartLocalExtended([[maybe_unused]] int32_t reg_number, [[maybe_unused]] uint32_t name_id, 98 [[maybe_unused]] uint32_t type_id, [[maybe_unused]] uint32_t type_signature_id) const 99 { 100 return true; 101 } 102 103 bool HandleEndLocal([[maybe_unused]] int32_t reg_number) const 104 { 105 return true; 106 } 107 108 bool HandleSetColumn([[maybe_unused]] int32_t column_number) const 109 { 110 return true; 111 } 112 113 bool HandleSpecialOpcode(uint32_t pc_offset, int32_t line_offset) 114 { 115 state_->AdvancePc(pc_offset); 116 state_->AdvanceLine(line_offset); 117 118 if (state_->GetAddress() == bc_offset_) { 119 line_ = state_->GetLine(); 120 return false; 121 } 122 123 if (state_->GetAddress() > bc_offset_) { 124 line_ = prev_line_; 125 return false; 126 } 127 128 prev_line_ = state_->GetLine(); 129 130 return true; 131 } 132 133private: 134 panda_file::LineProgramState *state_; 135 uint32_t bc_offset_; 136 uint32_t prev_line_; 137 uint32_t line_; 138}; 139 140inline size_t GetLineNumber(panda::panda_file::MethodDataAccessor mda, uint32_t bc_offset, 141 const panda::panda_file::File *panda_debug_file) 142{ 143 auto debug_info_id = mda.GetDebugInfoId(); 144 if (!debug_info_id) { 145 return -1; 146 } 147 148 panda::panda_file::DebugInfoDataAccessor dda(*panda_debug_file, debug_info_id.value()); 149 const uint8_t *program = dda.GetLineNumberProgram(); 150 151 panda::panda_file::LineProgramState state(*panda_debug_file, panda::panda_file::File::EntityId(0), 152 dda.GetLineStart(), dda.GetConstantPool()); 153 154 BytecodeOffsetResolver resolver(&state, bc_offset); 155 panda::panda_file::LineNumberProgramProcessor<BytecodeOffsetResolver> program_processor(program, &resolver); 156 program_processor.Process(); 157 158 return resolver.GetLine(); 159} 160 161} // namespace panda::panda_file::debug_helpers 162 163#endif // LIBPANDAFILE_DEBUG_HELPERS_H 164