1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#ifndef LIBPANDAFILE_DEBUG_HELPERS_H
17b1994897Sopenharmony_ci#define LIBPANDAFILE_DEBUG_HELPERS_H
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include "debug_data_accessor-inl.h"
20b1994897Sopenharmony_ci#include "file.h"
21b1994897Sopenharmony_ci#include "file_items.h"
22b1994897Sopenharmony_ci#include "method_data_accessor-inl.h"
23b1994897Sopenharmony_ci#include "line_number_program.h"
24b1994897Sopenharmony_ci#include "libpandabase/utils/span.h"
25b1994897Sopenharmony_ci
26b1994897Sopenharmony_cinamespace panda::panda_file::debug_helpers {
27b1994897Sopenharmony_ci
28b1994897Sopenharmony_ciclass BytecodeOffsetResolver {
29b1994897Sopenharmony_cipublic:
30b1994897Sopenharmony_ci    BytecodeOffsetResolver(panda_file::LineProgramState *state, uint32_t bc_offset)
31b1994897Sopenharmony_ci        : state_(state), bc_offset_(bc_offset), prev_line_(state->GetLine()), line_(0)
32b1994897Sopenharmony_ci    {
33b1994897Sopenharmony_ci    }
34b1994897Sopenharmony_ci
35b1994897Sopenharmony_ci    ~BytecodeOffsetResolver() = default;
36b1994897Sopenharmony_ci
37b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(BytecodeOffsetResolver);
38b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(BytecodeOffsetResolver);
39b1994897Sopenharmony_ci
40b1994897Sopenharmony_ci    panda_file::LineProgramState *GetState() const
41b1994897Sopenharmony_ci    {
42b1994897Sopenharmony_ci        return state_;
43b1994897Sopenharmony_ci    }
44b1994897Sopenharmony_ci
45b1994897Sopenharmony_ci    uint32_t GetLine() const
46b1994897Sopenharmony_ci    {
47b1994897Sopenharmony_ci        return line_;
48b1994897Sopenharmony_ci    }
49b1994897Sopenharmony_ci
50b1994897Sopenharmony_ci    void ProcessBegin() const {}
51b1994897Sopenharmony_ci
52b1994897Sopenharmony_ci    void ProcessEnd()
53b1994897Sopenharmony_ci    {
54b1994897Sopenharmony_ci        if (line_ == 0) {
55b1994897Sopenharmony_ci            line_ = state_->GetLine();
56b1994897Sopenharmony_ci        }
57b1994897Sopenharmony_ci    }
58b1994897Sopenharmony_ci
59b1994897Sopenharmony_ci    bool HandleAdvanceLine(int32_t line_diff) const
60b1994897Sopenharmony_ci    {
61b1994897Sopenharmony_ci        state_->AdvanceLine(line_diff);
62b1994897Sopenharmony_ci        return true;
63b1994897Sopenharmony_ci    }
64b1994897Sopenharmony_ci
65b1994897Sopenharmony_ci    bool HandleAdvancePc(uint32_t pc_diff) const
66b1994897Sopenharmony_ci    {
67b1994897Sopenharmony_ci        state_->AdvancePc(pc_diff);
68b1994897Sopenharmony_ci        return true;
69b1994897Sopenharmony_ci    }
70b1994897Sopenharmony_ci
71b1994897Sopenharmony_ci    bool HandleSetFile([[maybe_unused]] uint32_t source_file_id) const
72b1994897Sopenharmony_ci    {
73b1994897Sopenharmony_ci        return true;
74b1994897Sopenharmony_ci    }
75b1994897Sopenharmony_ci
76b1994897Sopenharmony_ci    bool HandleSetSourceCode([[maybe_unused]] uint32_t source_code_id) const
77b1994897Sopenharmony_ci    {
78b1994897Sopenharmony_ci        return true;
79b1994897Sopenharmony_ci    }
80b1994897Sopenharmony_ci
81b1994897Sopenharmony_ci    bool HandleSetPrologueEnd() const
82b1994897Sopenharmony_ci    {
83b1994897Sopenharmony_ci        return true;
84b1994897Sopenharmony_ci    }
85b1994897Sopenharmony_ci
86b1994897Sopenharmony_ci    bool HandleSetEpilogueBegin() const
87b1994897Sopenharmony_ci    {
88b1994897Sopenharmony_ci        return true;
89b1994897Sopenharmony_ci    }
90b1994897Sopenharmony_ci
91b1994897Sopenharmony_ci    bool HandleStartLocal([[maybe_unused]] int32_t reg_number, [[maybe_unused]] uint32_t name_id,
92b1994897Sopenharmony_ci                          [[maybe_unused]] uint32_t type_id) const
93b1994897Sopenharmony_ci    {
94b1994897Sopenharmony_ci        return true;
95b1994897Sopenharmony_ci    }
96b1994897Sopenharmony_ci
97b1994897Sopenharmony_ci    bool HandleStartLocalExtended([[maybe_unused]] int32_t reg_number, [[maybe_unused]] uint32_t name_id,
98b1994897Sopenharmony_ci                                  [[maybe_unused]] uint32_t type_id, [[maybe_unused]] uint32_t type_signature_id) const
99b1994897Sopenharmony_ci    {
100b1994897Sopenharmony_ci        return true;
101b1994897Sopenharmony_ci    }
102b1994897Sopenharmony_ci
103b1994897Sopenharmony_ci    bool HandleEndLocal([[maybe_unused]] int32_t reg_number) const
104b1994897Sopenharmony_ci    {
105b1994897Sopenharmony_ci        return true;
106b1994897Sopenharmony_ci    }
107b1994897Sopenharmony_ci
108b1994897Sopenharmony_ci    bool HandleSetColumn([[maybe_unused]] int32_t column_number) const
109b1994897Sopenharmony_ci    {
110b1994897Sopenharmony_ci        return true;
111b1994897Sopenharmony_ci    }
112b1994897Sopenharmony_ci
113b1994897Sopenharmony_ci    bool HandleSpecialOpcode(uint32_t pc_offset, int32_t line_offset)
114b1994897Sopenharmony_ci    {
115b1994897Sopenharmony_ci        state_->AdvancePc(pc_offset);
116b1994897Sopenharmony_ci        state_->AdvanceLine(line_offset);
117b1994897Sopenharmony_ci
118b1994897Sopenharmony_ci        if (state_->GetAddress() == bc_offset_) {
119b1994897Sopenharmony_ci            line_ = state_->GetLine();
120b1994897Sopenharmony_ci            return false;
121b1994897Sopenharmony_ci        }
122b1994897Sopenharmony_ci
123b1994897Sopenharmony_ci        if (state_->GetAddress() > bc_offset_) {
124b1994897Sopenharmony_ci            line_ = prev_line_;
125b1994897Sopenharmony_ci            return false;
126b1994897Sopenharmony_ci        }
127b1994897Sopenharmony_ci
128b1994897Sopenharmony_ci        prev_line_ = state_->GetLine();
129b1994897Sopenharmony_ci
130b1994897Sopenharmony_ci        return true;
131b1994897Sopenharmony_ci    }
132b1994897Sopenharmony_ci
133b1994897Sopenharmony_ciprivate:
134b1994897Sopenharmony_ci    panda_file::LineProgramState *state_;
135b1994897Sopenharmony_ci    uint32_t bc_offset_;
136b1994897Sopenharmony_ci    uint32_t prev_line_;
137b1994897Sopenharmony_ci    uint32_t line_;
138b1994897Sopenharmony_ci};
139b1994897Sopenharmony_ci
140b1994897Sopenharmony_ciinline size_t GetLineNumber(panda::panda_file::MethodDataAccessor mda, uint32_t bc_offset,
141b1994897Sopenharmony_ci                            const panda::panda_file::File *panda_debug_file)
142b1994897Sopenharmony_ci{
143b1994897Sopenharmony_ci    auto debug_info_id = mda.GetDebugInfoId();
144b1994897Sopenharmony_ci    if (!debug_info_id) {
145b1994897Sopenharmony_ci        return -1;
146b1994897Sopenharmony_ci    }
147b1994897Sopenharmony_ci
148b1994897Sopenharmony_ci    panda::panda_file::DebugInfoDataAccessor dda(*panda_debug_file, debug_info_id.value());
149b1994897Sopenharmony_ci    const uint8_t *program = dda.GetLineNumberProgram();
150b1994897Sopenharmony_ci
151b1994897Sopenharmony_ci    panda::panda_file::LineProgramState state(*panda_debug_file, panda::panda_file::File::EntityId(0),
152b1994897Sopenharmony_ci                                              dda.GetLineStart(), dda.GetConstantPool());
153b1994897Sopenharmony_ci
154b1994897Sopenharmony_ci    BytecodeOffsetResolver resolver(&state, bc_offset);
155b1994897Sopenharmony_ci    panda::panda_file::LineNumberProgramProcessor<BytecodeOffsetResolver> program_processor(program, &resolver);
156b1994897Sopenharmony_ci    program_processor.Process();
157b1994897Sopenharmony_ci
158b1994897Sopenharmony_ci    return resolver.GetLine();
159b1994897Sopenharmony_ci}
160b1994897Sopenharmony_ci
161b1994897Sopenharmony_ci}  // namespace panda::panda_file::debug_helpers
162b1994897Sopenharmony_ci
163b1994897Sopenharmony_ci#endif  // LIBPANDAFILE_DEBUG_HELPERS_H
164