mirror of
https://gitee.com/openharmony/arkcompiler_runtime_core
synced 2025-04-17 18:10:19 +00:00
Fix Method::GetLineNumFromBytecodeOffset
Change-Id: I82a68723ef70c57ffc7dc015333860b242d0b57f Signed-off-by: Konstantin Baladurin <konstantin.baladurin@huawei.com>
This commit is contained in:
parent
031d76da4d
commit
68856e746b
@ -169,8 +169,8 @@ if(PANDA_WITH_TOOLCHAIN)
|
||||
add_subdirectory(${PANDA_THIRD_PARTY_CONFIG_DIR}/securec)
|
||||
add_subdirectory(libpandabase)
|
||||
|
||||
set(MINIZ_ROOT ${PANDA_THIRD_PARTY_SOURCES_DIR}/miniz/amalgamation)
|
||||
add_subdirectory(${PANDA_THIRD_PARTY_CONFIG_DIR}/miniz)
|
||||
set(ZLIB_ROOT ${PANDA_THIRD_PARTY_SOURCES_DIR}/zlib)
|
||||
add_subdirectory(${PANDA_THIRD_PARTY_CONFIG_DIR}/zlib)
|
||||
add_subdirectory(libziparchive)
|
||||
|
||||
add_subdirectory(libpandafile)
|
||||
|
36
cmake/ark-third-party/miniz/CMakeLists.txt
vendored
36
cmake/ark-third-party/miniz/CMakeLists.txt
vendored
@ -1,36 +0,0 @@
|
||||
# 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.
|
||||
|
||||
project(miniz)
|
||||
|
||||
add_library(miniz ${MINIZ_ROOT}/miniz.c)
|
||||
target_include_directories(miniz PUBLIC ${MINIZ_ROOT})
|
||||
|
||||
target_compile_options(miniz PUBLIC -Wno-return-type-c-linkage)
|
||||
|
||||
# NB! We always build miniz statically, but there seems
|
||||
# no obvious reasons for that. If we reconsider, the logic
|
||||
# below should be replaced with something like:
|
||||
#
|
||||
# add_library(miniz ${PANDA_DEFAULT_LIB_TYPE} miniz.c)
|
||||
#
|
||||
# **Besides** build of host tools should be fixed to
|
||||
# take into account new shared library
|
||||
if(NOT PANDA_TARGET_WINDOWS)
|
||||
target_compile_options(miniz PRIVATE -fPIC)
|
||||
endif()
|
||||
|
||||
if (PANDA_ENABLE_AFL)
|
||||
include("${PANDA_ROOT}/fuzzing/Fuzzing.cmake")
|
||||
panda_substitute_libs(TARGET miniz)
|
||||
endif()
|
202
cmake/ark-third-party/zlib/CMakeLists.txt
vendored
Normal file
202
cmake/ark-third-party/zlib/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
cmake_minimum_required(VERSION 2.4.4)
|
||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
|
||||
|
||||
project(zlib C)
|
||||
|
||||
set(VERSION "1.2.11")
|
||||
|
||||
option(ASM686 "Enable building i686 assembly implementation")
|
||||
option(AMD64 "Enable building amd64 assembly implementation")
|
||||
|
||||
set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
|
||||
set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
|
||||
set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
|
||||
set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
|
||||
set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
|
||||
|
||||
include(CheckTypeSize)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckCSourceCompiles)
|
||||
enable_testing()
|
||||
|
||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_file(stdint.h HAVE_STDINT_H)
|
||||
check_include_file(stddef.h HAVE_STDDEF_H)
|
||||
|
||||
#
|
||||
# Check to see if we have large file support
|
||||
#
|
||||
set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
|
||||
# We add these other definitions here because CheckTypeSize.cmake
|
||||
# in CMake 2.4.x does not automatically do so and we want
|
||||
# compatibility with CMake 2.4.x.
|
||||
if(HAVE_SYS_TYPES_H)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
|
||||
endif()
|
||||
if(HAVE_STDINT_H)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
|
||||
endif()
|
||||
if(HAVE_STDDEF_H)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
|
||||
endif()
|
||||
check_type_size(off64_t OFF64_T)
|
||||
if(HAVE_OFF64_T)
|
||||
add_definitions(-D_LARGEFILE64_SOURCE=1)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
|
||||
|
||||
#
|
||||
# Check for fseeko
|
||||
#
|
||||
check_function_exists(fseeko HAVE_FSEEKO)
|
||||
if(NOT HAVE_FSEEKO)
|
||||
add_definitions(-DNO_FSEEKO)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Check for unistd.h
|
||||
#
|
||||
check_include_file(unistd.h Z_HAVE_UNISTD_H)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
# If we're doing an out of source build and the user has a zconf.h
|
||||
# in their source tree...
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
|
||||
message(STATUS "Renaming")
|
||||
message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
|
||||
message(STATUS "to 'zconf.h.included' because this file is included with zlib")
|
||||
message(STATUS "but CMake generates it automatically in the build directory.")
|
||||
file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
|
||||
configure_file( ${PANDA_THIRD_PARTY_SOURCES_DIR}/zlib/zlib.pc.cmakein
|
||||
${ZLIB_PC} @ONLY)
|
||||
configure_file( ${PANDA_THIRD_PARTY_SOURCES_DIR}/zlib/zconf.h.cmakein
|
||||
${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
|
||||
|
||||
|
||||
#============================================================================
|
||||
# zlib
|
||||
#============================================================================
|
||||
|
||||
set(ZLIB_PUBLIC_HDRS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/zconf.h
|
||||
${ZLIB_ROOT}/zlib.h
|
||||
)
|
||||
set(ZLIB_PRIVATE_HDRS
|
||||
${ZLIB_ROOT}/crc32.h
|
||||
${ZLIB_ROOT}/deflate.h
|
||||
${ZLIB_ROOT}/gzguts.h
|
||||
${ZLIB_ROOT}/inffast.h
|
||||
${ZLIB_ROOT}/inffixed.h
|
||||
${ZLIB_ROOT}/inflate.h
|
||||
${ZLIB_ROOT}/inftrees.h
|
||||
${ZLIB_ROOT}/trees.h
|
||||
${ZLIB_ROOT}/zutil.h
|
||||
)
|
||||
set(ZLIB_SRCS
|
||||
${ZLIB_ROOT}/adler32.c
|
||||
${ZLIB_ROOT}/compress.c
|
||||
${ZLIB_ROOT}/contrib/minizip/ioapi.c
|
||||
${ZLIB_ROOT}/contrib/minizip/unzip.c
|
||||
${ZLIB_ROOT}/contrib/minizip/zip.c
|
||||
${ZLIB_ROOT}/crc32.c
|
||||
${ZLIB_ROOT}/deflate.c
|
||||
${ZLIB_ROOT}/gzclose.c
|
||||
${ZLIB_ROOT}/gzlib.c
|
||||
${ZLIB_ROOT}/gzread.c
|
||||
${ZLIB_ROOT}/gzwrite.c
|
||||
${ZLIB_ROOT}/inflate.c
|
||||
${ZLIB_ROOT}/infback.c
|
||||
${ZLIB_ROOT}/inftrees.c
|
||||
${ZLIB_ROOT}/inffast.c
|
||||
${ZLIB_ROOT}/trees.c
|
||||
${ZLIB_ROOT}/uncompr.c
|
||||
${ZLIB_ROOT}/zutil.c
|
||||
)
|
||||
|
||||
if(NOT MINGW)
|
||||
set(ZLIB_DLL_SRCS
|
||||
${ZLIB_ROOT}/win32/zlib1.rc # If present will override custom build rule below.
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if(ASM686)
|
||||
set(ZLIB_ASMS ${ZLIB_ROOT}/contrib/asm686/match.S)
|
||||
elseif (AMD64)
|
||||
set(ZLIB_ASMS ${ZLIB_ROOT}/contrib/amd64/amd64-match.S)
|
||||
endif ()
|
||||
|
||||
if(ZLIB_ASMS)
|
||||
add_definitions(-DASMV)
|
||||
set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(ASM686)
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
set(ZLIB_ASMS
|
||||
${ZLIB_ROOT}/contrib/masmx86/inffas32.asm
|
||||
${ZLIB_ROOT}/contrib/masmx86/match686.asm
|
||||
)
|
||||
elseif (AMD64)
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
set(ZLIB_ASMS
|
||||
${ZLIB_ROOT}/contrib/masmx64/gvmat64.asm
|
||||
${ZLIB_ROOT}/contrib/masmx64/inffasx64.asm
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ZLIB_ASMS)
|
||||
add_definitions(-DASMV -DASMINF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
|
||||
file(READ ${PANDA_THIRD_PARTY_SOURCES_DIR}/zlib/zlib.h _zlib_h_contents)
|
||||
string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
|
||||
"\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
|
||||
|
||||
add_library(zlib STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
|
||||
target_include_directories(zlib PUBLIC ${ZLIB_ROOT})
|
||||
|
||||
target_compile_options(zlib PUBLIC -Wno-return-type-c-linkage)
|
||||
|
||||
if(HOST_TOOLS)
|
||||
set_target_properties(zlib
|
||||
PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/third_party/zlib
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/third_party/zlib
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/third_party/zlib
|
||||
)
|
||||
endif()
|
||||
|
||||
# NB! We always build zlib statically, but there seems
|
||||
# no obvious reasons for that. If we reconsider, the logic
|
||||
# below should be replaced with something like:
|
||||
#
|
||||
# add_library(zlib ${PANDA_DEFAULT_LIB_TYPE} zlib.c)
|
||||
#
|
||||
# **Besides** build of host tools should be fixed to
|
||||
# take into account new shared library
|
||||
if(NOT PANDA_TARGET_WINDOWS)
|
||||
target_compile_options(zlib PRIVATE -fPIC)
|
||||
endif()
|
||||
|
||||
if (PANDA_ENABLE_AFL)
|
||||
include("${PANDA_ROOT}/fuzzing/Fuzzing.cmake")
|
||||
panda_substitute_libs(TARGET zlib)
|
||||
endif()
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "debug_info_extractor.h"
|
||||
#include "line_program_state.h"
|
||||
#include "line_number_program.h"
|
||||
#include "class_data_accessor-inl.h"
|
||||
#include "debug_data_accessor-inl.h"
|
||||
#include "utils/utf.h"
|
||||
@ -31,93 +31,134 @@ DebugInfoExtractor::DebugInfoExtractor(const File *pf)
|
||||
Extract(pf);
|
||||
}
|
||||
|
||||
class LineNumberProgramProcessor {
|
||||
class LineNumberProgramHandler {
|
||||
public:
|
||||
LineNumberProgramProcessor(LineProgramState state, const uint8_t *program) : state_(state), program_(program) {}
|
||||
explicit LineNumberProgramHandler(LineProgramState *state) : state_(state) {}
|
||||
~LineNumberProgramHandler() = default;
|
||||
|
||||
~LineNumberProgramProcessor() = default;
|
||||
NO_COPY_SEMANTIC(LineNumberProgramHandler);
|
||||
NO_MOVE_SEMANTIC(LineNumberProgramHandler);
|
||||
|
||||
NO_COPY_SEMANTIC(LineNumberProgramProcessor);
|
||||
NO_MOVE_SEMANTIC(LineNumberProgramProcessor);
|
||||
|
||||
void Process()
|
||||
LineProgramState *GetState() const
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
|
||||
void ProcessBegin()
|
||||
{
|
||||
lnt_.push_back({state_->GetAddress(), state_->GetLine()});
|
||||
}
|
||||
|
||||
void ProcessEnd()
|
||||
{
|
||||
auto opcode = ReadOpcode();
|
||||
lnt_.push_back({state_.GetAddress(), state_.GetLine()});
|
||||
while (opcode != Opcode::END_SEQUENCE) {
|
||||
switch (opcode) {
|
||||
case Opcode::ADVANCE_LINE: {
|
||||
HandleAdvanceLine();
|
||||
break;
|
||||
}
|
||||
case Opcode::ADVANCE_PC: {
|
||||
HandleAdvancePc();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_FILE: {
|
||||
HandleSetFile();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_SOURCE_CODE: {
|
||||
HandleSetSourceCode();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_PROLOGUE_END:
|
||||
case Opcode::SET_EPILOGUE_BEGIN:
|
||||
break;
|
||||
case Opcode::START_LOCAL: {
|
||||
HandleStartLocal();
|
||||
break;
|
||||
}
|
||||
case Opcode::START_LOCAL_EXTENDED: {
|
||||
HandleStartLocalExtended();
|
||||
break;
|
||||
}
|
||||
case Opcode::RESTART_LOCAL: {
|
||||
LOG(FATAL, PANDAFILE) << "Opcode RESTART_LOCAL is not supported";
|
||||
break;
|
||||
}
|
||||
case Opcode::END_LOCAL: {
|
||||
HandleEndLocal();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_COLUMN: {
|
||||
HandleSetColumn();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
HandleSpecialOpcode(opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
opcode = ReadOpcode();
|
||||
}
|
||||
ProcessVars();
|
||||
}
|
||||
|
||||
bool HandleAdvanceLine(int32_t line_diff) const
|
||||
{
|
||||
state_->AdvanceLine(line_diff);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleAdvancePc(uint32_t pc_diff) const
|
||||
{
|
||||
state_->AdvancePc(pc_diff);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetFile(uint32_t source_file_id) const
|
||||
{
|
||||
state_->SetFile(source_file_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetSourceCode(uint32_t source_code_id) const
|
||||
{
|
||||
state_->SetSourceCode(source_code_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetPrologueEnd() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetEpilogueBegin() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleStartLocal(int32_t reg_number, uint32_t name_id, uint32_t type_id)
|
||||
{
|
||||
const char *name = GetStringFromConstantPool(state_->GetPandaFile(), name_id);
|
||||
const char *type = GetStringFromConstantPool(state_->GetPandaFile(), type_id);
|
||||
lvt_.push_back({name, type, type, reg_number, state_->GetAddress(), 0});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleStartLocalExtended(int32_t reg_number, uint32_t name_id, uint32_t type_id, uint32_t type_signature_id)
|
||||
{
|
||||
const char *name = GetStringFromConstantPool(state_->GetPandaFile(), name_id);
|
||||
const char *type = GetStringFromConstantPool(state_->GetPandaFile(), type_id);
|
||||
const char *type_sign = GetStringFromConstantPool(state_->GetPandaFile(), type_signature_id);
|
||||
lvt_.push_back({name, type, type_sign, reg_number, state_->GetAddress(), 0});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleEndLocal(int32_t reg_number)
|
||||
{
|
||||
bool found = false;
|
||||
for (auto it = lvt_.rbegin(); it != lvt_.rend(); ++it) {
|
||||
if (it->reg_number == reg_number) {
|
||||
it->end_offset = state_->GetAddress();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
LOG(FATAL, PANDAFILE) << "Unknown variable";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetColumn(int32_t column_number)
|
||||
{
|
||||
state_->SetColumn(column_number);
|
||||
cnt_.push_back({state_->GetAddress(), state_->GetColumn()});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSpecialOpcode(uint32_t pc_offset, int32_t line_offset)
|
||||
{
|
||||
state_->AdvancePc(pc_offset);
|
||||
state_->AdvanceLine(line_offset);
|
||||
lnt_.push_back({state_->GetAddress(), state_->GetLine()});
|
||||
return true;
|
||||
}
|
||||
|
||||
LineNumberTable GetLineNumberTable() const
|
||||
{
|
||||
return lnt_;
|
||||
}
|
||||
|
||||
ColumnNumberTable GetColumnNumberTable() const
|
||||
{
|
||||
return cnt_;
|
||||
}
|
||||
|
||||
LocalVariableTable GetLocalVariableTable() const
|
||||
{
|
||||
return lvt_;
|
||||
}
|
||||
|
||||
ColumnNumberTable GetColumnNumberTable() const
|
||||
{
|
||||
return cnt_;
|
||||
}
|
||||
|
||||
const uint8_t *GetFile() const
|
||||
{
|
||||
return state_.GetFile();
|
||||
return state_->GetFile();
|
||||
}
|
||||
|
||||
const uint8_t *GetSourceCode() const
|
||||
{
|
||||
return state_.GetSourceCode();
|
||||
return state_->GetSourceCode();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -127,112 +168,12 @@ private:
|
||||
{
|
||||
for (auto &var : lvt_) {
|
||||
if (var.end_offset == 0) {
|
||||
var.end_offset = state_.GetAddress();
|
||||
var.end_offset = state_->GetAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Opcode ReadOpcode()
|
||||
{
|
||||
auto opcode = static_cast<Opcode>(*program_);
|
||||
++program_; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
return opcode;
|
||||
}
|
||||
|
||||
int32_t ReadRegisterNumber()
|
||||
{
|
||||
auto [regiser_number, n, is_full] = leb128::DecodeSigned<int32_t>(program_);
|
||||
LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
|
||||
program_ += n; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
return regiser_number;
|
||||
}
|
||||
|
||||
void HandleAdvanceLine()
|
||||
{
|
||||
auto line_diff = state_.ReadSLeb128();
|
||||
state_.AdvanceLine(line_diff);
|
||||
}
|
||||
|
||||
void HandleAdvancePc()
|
||||
{
|
||||
auto pc_diff = state_.ReadULeb128();
|
||||
state_.AdvancePc(pc_diff);
|
||||
}
|
||||
|
||||
void HandleSetFile()
|
||||
{
|
||||
state_.SetFile(state_.ReadULeb128());
|
||||
}
|
||||
|
||||
void HandleSetSourceCode()
|
||||
{
|
||||
state_.SetSourceCode(state_.ReadULeb128());
|
||||
}
|
||||
|
||||
void HandleSetPrologueEnd() {}
|
||||
|
||||
void HandleSetEpilogueBegin() {}
|
||||
|
||||
void HandleStartLocal()
|
||||
{
|
||||
auto reg_number = ReadRegisterNumber();
|
||||
auto name_index = state_.ReadULeb128();
|
||||
auto type_index = state_.ReadULeb128();
|
||||
const char *name = GetStringFromConstantPool(state_.GetPandaFile(), name_index);
|
||||
const char *type = GetStringFromConstantPool(state_.GetPandaFile(), type_index);
|
||||
lvt_.push_back({name, type, type, reg_number, state_.GetAddress(), 0});
|
||||
}
|
||||
|
||||
void HandleStartLocalExtended()
|
||||
{
|
||||
auto reg_number = ReadRegisterNumber();
|
||||
auto name_index = state_.ReadULeb128();
|
||||
auto type_index = state_.ReadULeb128();
|
||||
auto type_signature_index = state_.ReadULeb128();
|
||||
const char *name = GetStringFromConstantPool(state_.GetPandaFile(), name_index);
|
||||
const char *type = GetStringFromConstantPool(state_.GetPandaFile(), type_index);
|
||||
const char *type_sign = GetStringFromConstantPool(state_.GetPandaFile(), type_signature_index);
|
||||
lvt_.push_back({name, type, type_sign, reg_number, state_.GetAddress(), 0});
|
||||
}
|
||||
|
||||
void HandleEndLocal()
|
||||
{
|
||||
auto reg_number = ReadRegisterNumber();
|
||||
bool found = false;
|
||||
for (auto it = lvt_.rbegin(); it != lvt_.rend(); ++it) {
|
||||
if (it->reg_number == reg_number) {
|
||||
it->end_offset = state_.GetAddress();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
LOG(FATAL, PANDAFILE) << "Unknown variable";
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSetColumn()
|
||||
{
|
||||
auto cn = state_.ReadULeb128();
|
||||
state_.SetColumn(cn);
|
||||
cnt_.push_back({state_.GetAddress(), state_.GetColumn()});
|
||||
}
|
||||
|
||||
void HandleSpecialOpcode(LineNumberProgramItem::Opcode opcode)
|
||||
{
|
||||
ASSERT(static_cast<uint8_t>(opcode) >= LineNumberProgramItem::OPCODE_BASE);
|
||||
|
||||
auto adjust_opcode = static_cast<uint8_t>(static_cast<uint8_t>(opcode) - LineNumberProgramItem::OPCODE_BASE);
|
||||
auto pc_offset = static_cast<uint32_t>(adjust_opcode / LineNumberProgramItem::LINE_RANGE);
|
||||
int32_t line_offset =
|
||||
static_cast<int32_t>(adjust_opcode) % LineNumberProgramItem::LINE_RANGE + LineNumberProgramItem::LINE_BASE;
|
||||
state_.AdvancePc(pc_offset);
|
||||
state_.AdvanceLine(line_offset);
|
||||
lnt_.push_back({state_.GetAddress(), state_.GetLine()});
|
||||
}
|
||||
|
||||
LineProgramState state_;
|
||||
const uint8_t *program_;
|
||||
LineProgramState *state_;
|
||||
LineNumberTable lnt_;
|
||||
LocalVariableTable lvt_;
|
||||
ColumnNumberTable cnt_;
|
||||
@ -278,15 +219,16 @@ void DebugInfoExtractor::Extract(const File *pf)
|
||||
LineProgramState state(panda_file, source_file_id.value_or(File::EntityId(0)), dda.GetLineStart(),
|
||||
dda.GetConstantPool());
|
||||
|
||||
LineNumberProgramProcessor program_processor(state, program);
|
||||
LineNumberProgramHandler handler(&state);
|
||||
LineNumberProgramProcessor<LineNumberProgramHandler> program_processor(program, &handler);
|
||||
program_processor.Process();
|
||||
|
||||
File::EntityId method_id = mda.GetMethodId();
|
||||
const char *source_file = utf::Mutf8AsCString(program_processor.GetFile());
|
||||
const char *source_code = utf::Mutf8AsCString(program_processor.GetSourceCode());
|
||||
methods_.push_back({source_file, source_code, method_id, program_processor.GetLineNumberTable(),
|
||||
program_processor.GetLocalVariableTable(), std::move(param_names),
|
||||
program_processor.GetColumnNumberTable()});
|
||||
const char *source_file = utf::Mutf8AsCString(handler.GetFile());
|
||||
const char *source_code = utf::Mutf8AsCString(handler.GetSourceCode());
|
||||
methods_.push_back({source_file, source_code, method_id, handler.GetLineNumberTable(),
|
||||
handler.GetLocalVariableTable(), std::move(param_names),
|
||||
handler.GetColumnNumberTable()});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -489,8 +489,8 @@ public:
|
||||
SET_EPILOGUE_BEGIN = 0x08,
|
||||
SET_FILE = 0x09,
|
||||
SET_SOURCE_CODE = 0x0a,
|
||||
SET_COLUMN = 0X0b, // The SET_COLUMN opcode takes a single unsigned LEB128 operand and
|
||||
// stores it in the column register of the state machine.
|
||||
SET_COLUMN = 0X0b, // The SET_COLUMN opcode takes a single unsigned LEB128 operand and
|
||||
// stores it in the column register of the state machine.
|
||||
LAST
|
||||
};
|
||||
|
||||
|
291
libpandafile/line_number_program.h
Normal file
291
libpandafile/line_number_program.h
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef LIBPANDAFILE_LINE_NUMBER_PROGRAM_H
|
||||
#define LIBPANDAFILE_LINE_NUMBER_PROGRAM_H
|
||||
|
||||
#include "file-inl.h"
|
||||
#include "file_items.h"
|
||||
|
||||
namespace panda::panda_file {
|
||||
|
||||
class LineProgramState {
|
||||
public:
|
||||
LineProgramState(const File &pf, File::EntityId file, size_t line, Span<const uint8_t> constant_pool)
|
||||
: pf_(pf), file_(file), line_(line), constant_pool_(constant_pool)
|
||||
{
|
||||
}
|
||||
|
||||
void AdvanceLine(int32_t v)
|
||||
{
|
||||
line_ += v;
|
||||
}
|
||||
|
||||
void AdvancePc(uint32_t v)
|
||||
{
|
||||
address_ += v;
|
||||
}
|
||||
|
||||
void SetFile(uint32_t offset)
|
||||
{
|
||||
file_ = File::EntityId(offset);
|
||||
}
|
||||
|
||||
const uint8_t *GetFile() const
|
||||
{
|
||||
return pf_.GetStringData(file_).data;
|
||||
}
|
||||
|
||||
bool HasFile() const
|
||||
{
|
||||
return file_.IsValid();
|
||||
}
|
||||
|
||||
void SetSourceCode(uint32_t offset)
|
||||
{
|
||||
source_code_ = File::EntityId(offset);
|
||||
}
|
||||
|
||||
const uint8_t *GetSourceCode() const
|
||||
{
|
||||
return pf_.GetStringData(source_code_).data;
|
||||
}
|
||||
|
||||
bool HasSourceCode() const
|
||||
{
|
||||
return source_code_.IsValid();
|
||||
}
|
||||
|
||||
size_t GetLine() const
|
||||
{
|
||||
return line_;
|
||||
}
|
||||
|
||||
void SetColumn(int32_t c)
|
||||
{
|
||||
column_ = c;
|
||||
}
|
||||
|
||||
size_t GetColumn() const
|
||||
{
|
||||
return column_;
|
||||
}
|
||||
|
||||
uint32_t GetAddress() const
|
||||
{
|
||||
return address_;
|
||||
}
|
||||
|
||||
uint32_t ReadULeb128()
|
||||
{
|
||||
return panda_file::helpers::ReadULeb128(&constant_pool_);
|
||||
}
|
||||
|
||||
int32_t ReadSLeb128()
|
||||
{
|
||||
return panda_file::helpers::ReadLeb128(&constant_pool_);
|
||||
}
|
||||
|
||||
const File &GetPandaFile() const
|
||||
{
|
||||
return pf_;
|
||||
}
|
||||
|
||||
private:
|
||||
const File &pf_;
|
||||
|
||||
File::EntityId file_;
|
||||
File::EntityId source_code_;
|
||||
size_t line_;
|
||||
size_t column_ {0};
|
||||
Span<const uint8_t> constant_pool_;
|
||||
|
||||
uint32_t address_ {0};
|
||||
};
|
||||
|
||||
template <class Handler>
|
||||
class LineNumberProgramProcessor {
|
||||
public:
|
||||
LineNumberProgramProcessor(const uint8_t *program, Handler *handler)
|
||||
: state_(handler->GetState()), program_(program), handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
~LineNumberProgramProcessor() = default;
|
||||
|
||||
NO_COPY_SEMANTIC(LineNumberProgramProcessor);
|
||||
NO_MOVE_SEMANTIC(LineNumberProgramProcessor);
|
||||
|
||||
// CODECHECK-NOLINTNEXTLINE(C_RULE_ID_FUNCTION_SIZE)
|
||||
void Process()
|
||||
{
|
||||
handler_->ProcessBegin();
|
||||
|
||||
auto opcode = ReadOpcode();
|
||||
bool res = false;
|
||||
while (opcode != Opcode::END_SEQUENCE) {
|
||||
switch (opcode) {
|
||||
case Opcode::ADVANCE_LINE: {
|
||||
res = HandleAdvanceLine();
|
||||
break;
|
||||
}
|
||||
case Opcode::ADVANCE_PC: {
|
||||
res = HandleAdvancePc();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_FILE: {
|
||||
res = HandleSetFile();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_SOURCE_CODE: {
|
||||
res = HandleSetSourceCode();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_PROLOGUE_END:
|
||||
case Opcode::SET_EPILOGUE_BEGIN:
|
||||
break;
|
||||
case Opcode::START_LOCAL: {
|
||||
res = HandleStartLocal();
|
||||
break;
|
||||
}
|
||||
case Opcode::START_LOCAL_EXTENDED: {
|
||||
res = HandleStartLocalExtended();
|
||||
break;
|
||||
}
|
||||
case Opcode::RESTART_LOCAL: {
|
||||
LOG(FATAL, PANDAFILE) << "Opcode RESTART_LOCAL is not supported";
|
||||
break;
|
||||
}
|
||||
case Opcode::END_LOCAL: {
|
||||
res = HandleEndLocal();
|
||||
break;
|
||||
}
|
||||
case Opcode::SET_COLUMN: {
|
||||
HandleSetColumn();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
res = HandleSpecialOpcode(opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
break;
|
||||
}
|
||||
|
||||
opcode = ReadOpcode();
|
||||
}
|
||||
|
||||
handler_->ProcessEnd();
|
||||
}
|
||||
|
||||
private:
|
||||
using Opcode = LineNumberProgramItem::Opcode;
|
||||
|
||||
Opcode ReadOpcode()
|
||||
{
|
||||
auto opcode = static_cast<Opcode>(*program_);
|
||||
++program_; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
return opcode;
|
||||
}
|
||||
|
||||
int32_t ReadRegisterNumber()
|
||||
{
|
||||
auto [regiser_number, n, is_full] = leb128::DecodeSigned<int32_t>(program_);
|
||||
LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
|
||||
program_ += n; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
return regiser_number;
|
||||
}
|
||||
|
||||
bool HandleAdvanceLine() const
|
||||
{
|
||||
auto line_diff = state_->ReadSLeb128();
|
||||
return handler_->HandleAdvanceLine(line_diff);
|
||||
}
|
||||
|
||||
bool HandleAdvancePc() const
|
||||
{
|
||||
auto pc_diff = state_->ReadULeb128();
|
||||
return handler_->HandleAdvancePc(pc_diff);
|
||||
}
|
||||
|
||||
bool HandleSetFile() const
|
||||
{
|
||||
return handler_->HandleSetFile(state_->ReadULeb128());
|
||||
}
|
||||
|
||||
bool HandleSetSourceCode() const
|
||||
{
|
||||
return handler_->HandleSetSourceCode(state_->ReadULeb128());
|
||||
}
|
||||
|
||||
bool HandleSetPrologueEnd() const
|
||||
{
|
||||
return handler_->HandleSetPrologueEnd();
|
||||
}
|
||||
|
||||
bool HandleSetEpilogueBegin() const
|
||||
{
|
||||
return handler_->HandleSetEpilogueBegin();
|
||||
}
|
||||
|
||||
bool HandleStartLocal()
|
||||
{
|
||||
auto reg_number = ReadRegisterNumber();
|
||||
auto name_index = state_->ReadULeb128();
|
||||
auto type_index = state_->ReadULeb128();
|
||||
return handler_->HandleStartLocal(reg_number, name_index, type_index);
|
||||
}
|
||||
|
||||
bool HandleStartLocalExtended()
|
||||
{
|
||||
auto reg_number = ReadRegisterNumber();
|
||||
auto name_index = state_->ReadULeb128();
|
||||
auto type_index = state_->ReadULeb128();
|
||||
auto type_signature_index = state_->ReadULeb128();
|
||||
return handler_->HandleStartLocalExtended(reg_number, name_index, type_index, type_signature_index);
|
||||
}
|
||||
|
||||
bool HandleEndLocal()
|
||||
{
|
||||
auto reg_number = ReadRegisterNumber();
|
||||
return handler_->HandleEndLocal(reg_number);
|
||||
}
|
||||
|
||||
bool HandleSetColumn()
|
||||
{
|
||||
auto cn = state_->ReadULeb128();
|
||||
return handler_->HandleSetColumn(cn);
|
||||
}
|
||||
|
||||
bool HandleSpecialOpcode(LineNumberProgramItem::Opcode opcode)
|
||||
{
|
||||
ASSERT(static_cast<uint8_t>(opcode) >= LineNumberProgramItem::OPCODE_BASE);
|
||||
|
||||
auto adjust_opcode = static_cast<uint8_t>(opcode) - LineNumberProgramItem::OPCODE_BASE;
|
||||
uint32_t pc_offset = adjust_opcode / LineNumberProgramItem::LINE_RANGE;
|
||||
int32_t line_offset = adjust_opcode % LineNumberProgramItem::LINE_RANGE + LineNumberProgramItem::LINE_BASE;
|
||||
return handler_->HandleSpecialOpcode(pc_offset, line_offset);
|
||||
}
|
||||
|
||||
LineProgramState *state_;
|
||||
const uint8_t *program_;
|
||||
Handler *handler_;
|
||||
};
|
||||
|
||||
} // namespace panda::panda_file
|
||||
|
||||
#endif // LIBPANDAFILE_LINE_NUMBER_PROGRAM_H
|
@ -16,8 +16,12 @@ cmake_minimum_required(VERSION 3.10)
|
||||
project(arkziparchive)
|
||||
|
||||
add_library(arkziparchive ${PANDA_DEFAULT_LIB_TYPE} zip_archive.cpp)
|
||||
target_include_directories(arkziparchive PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(arkziparchive arkbase miniz)
|
||||
target_include_directories(arkziparchive
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PUBLIC ${ZLIB_ROOT}
|
||||
PUBLIC ${ZLIB_ROOT}/contrib/minizip
|
||||
)
|
||||
target_link_libraries(arkziparchive arkbase zlib)
|
||||
|
||||
panda_add_gtest(
|
||||
NAME arkziparchive_tests
|
||||
@ -28,7 +32,7 @@ panda_add_gtest(
|
||||
arkfile
|
||||
arkziparchive
|
||||
arkassembler
|
||||
miniz
|
||||
zlib
|
||||
SANITIZERS
|
||||
${PANDA_SANITIZERS_LIST}
|
||||
)
|
||||
@ -38,7 +42,7 @@ panda_add_sanitizers(TARGET arkziparchive SANITIZERS ${PANDA_SANITIZERS_LIST})
|
||||
|
||||
if (PANDA_ENABLE_AFL)
|
||||
include("${PANDA_ROOT}/fuzzing/Fuzzing.cmake")
|
||||
panda_substitute_libs(TARGET arkziparchive LIBS arkbase miniz)
|
||||
panda_substitute_libs(TARGET arkziparchive LIBS arkbase zlib)
|
||||
endif()
|
||||
|
||||
add_check_style(".")
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "libpandafile/code_data_accessor-inl.h"
|
||||
#include "libpandafile/debug_data_accessor-inl.h"
|
||||
#include "libpandafile/file-inl.h"
|
||||
#include "libpandafile/line_program_state.h"
|
||||
#include "libpandafile/line_number_program.h"
|
||||
#include "libpandafile/method_data_accessor-inl.h"
|
||||
#include "libpandafile/method_data_accessor.h"
|
||||
#include "libpandafile/proto_data_accessor-inl.h"
|
||||
@ -376,6 +376,113 @@ panda_file::Type Method::GetEffectiveReturnType() const
|
||||
return panda_file::GetEffectiveType(GetReturnType());
|
||||
}
|
||||
|
||||
class BytecodeOffsetResolver {
|
||||
public:
|
||||
BytecodeOffsetResolver(panda_file::LineProgramState *state, uint32_t bc_offset)
|
||||
: state_(state), bc_offset_(bc_offset), prev_line_(state->GetLine()), line_(0)
|
||||
{
|
||||
}
|
||||
|
||||
panda_file::LineProgramState *GetState() const
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
|
||||
uint32_t GetLine() const
|
||||
{
|
||||
return line_;
|
||||
}
|
||||
|
||||
void ProcessBegin() const {}
|
||||
|
||||
void ProcessEnd()
|
||||
{
|
||||
if (line_ == 0) {
|
||||
line_ = state_->GetLine();
|
||||
}
|
||||
}
|
||||
|
||||
bool HandleAdvanceLine(int32_t line_diff) const
|
||||
{
|
||||
state_->AdvanceLine(line_diff);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleAdvancePc(uint32_t pc_diff) const
|
||||
{
|
||||
state_->AdvancePc(pc_diff);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetFile([[maybe_unused]] uint32_t source_file_id) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetSourceCode([[maybe_unused]] uint32_t source_code_id) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetPrologueEnd() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetEpilogueBegin() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleStartLocal([[maybe_unused]] int32_t reg_number, [[maybe_unused]] uint32_t name_id,
|
||||
[[maybe_unused]] uint32_t type_id) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleStartLocalExtended([[maybe_unused]] int32_t reg_number, [[maybe_unused]] uint32_t name_id,
|
||||
[[maybe_unused]] uint32_t type_id, [[maybe_unused]] uint32_t type_signature_id) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleEndLocal([[maybe_unused]] int32_t reg_number) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSetColumn([[maybe_unused]] int32_t column_number) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSpecialOpcode(uint32_t pc_offset, int32_t line_offset)
|
||||
{
|
||||
state_->AdvancePc(pc_offset);
|
||||
state_->AdvanceLine(line_offset);
|
||||
|
||||
if (state_->GetAddress() == bc_offset_) {
|
||||
line_ = state_->GetLine();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state_->GetAddress() > bc_offset_) {
|
||||
line_ = prev_line_;
|
||||
return false;
|
||||
}
|
||||
|
||||
prev_line_ = state_->GetLine();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
panda_file::LineProgramState *state_;
|
||||
uint32_t bc_offset_;
|
||||
uint32_t prev_line_;
|
||||
uint32_t line_;
|
||||
};
|
||||
|
||||
int32_t Method::GetLineNumFromBytecodeOffset(uint32_t bc_offset) const
|
||||
{
|
||||
panda_file::MethodDataAccessor mda(*panda_file_, file_id_);
|
||||
@ -384,65 +491,17 @@ int32_t Method::GetLineNumFromBytecodeOffset(uint32_t bc_offset) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
using Opcode = panda_file::LineNumberProgramItem::Opcode;
|
||||
using EntityId = panda_file::File::EntityId;
|
||||
|
||||
panda_file::DebugInfoDataAccessor dda(*panda_file_, debug_info_id.value());
|
||||
const uint8_t *program = dda.GetLineNumberProgram();
|
||||
auto size = panda_file_->GetSpanFromId(panda_file_->GetIdFromPointer(program)).size();
|
||||
auto opcode_sp = Span(reinterpret_cast<const Opcode *>(program), size);
|
||||
|
||||
panda_file::LineProgramState state(*panda_file_, EntityId(0), dda.GetLineStart(), dda.GetConstantPool());
|
||||
panda_file::LineProgramState state(*panda_file_, panda_file::File::EntityId(0), dda.GetLineStart(),
|
||||
dda.GetConstantPool());
|
||||
|
||||
size_t i = 0;
|
||||
Opcode opcode;
|
||||
size_t prev_line = state.GetLine();
|
||||
while ((opcode = opcode_sp[i++]) != Opcode::END_SEQUENCE) {
|
||||
switch (opcode) {
|
||||
case Opcode::ADVANCE_LINE: {
|
||||
auto line_diff = state.ReadSLeb128();
|
||||
state.AdvanceLine(line_diff);
|
||||
break;
|
||||
}
|
||||
case Opcode::ADVANCE_PC: {
|
||||
auto pc_diff = state.ReadULeb128();
|
||||
state.AdvancePc(pc_diff);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// CODECHECK-NOLINTNEXTLINE(C_RULE_ID_REDUNDANT_INIT)
|
||||
auto opcode_value = static_cast<uint8_t>(opcode);
|
||||
if (opcode_value < panda_file::LineNumberProgramItem::OPCODE_BASE) {
|
||||
break;
|
||||
}
|
||||
BytecodeOffsetResolver resolver(&state, bc_offset);
|
||||
panda_file::LineNumberProgramProcessor<BytecodeOffsetResolver> program_processor(program, &resolver);
|
||||
program_processor.Process();
|
||||
|
||||
// CODECHECK-NOLINTNEXTLINE(C_RULE_ID_REDUNDANT_INIT)
|
||||
auto adjust_opcode = opcode_value - panda_file::LineNumberProgramItem::OPCODE_BASE;
|
||||
// CODECHECK-NOLINTNEXTLINE(C_RULE_ID_REDUNDANT_INIT)
|
||||
uint32_t pc_diff = adjust_opcode / panda_file::LineNumberProgramItem::LINE_RANGE;
|
||||
// CODECHECK-NOLINTNEXTLINE(C_RULE_ID_REDUNDANT_INIT)
|
||||
int32_t line_diff = adjust_opcode % panda_file::LineNumberProgramItem::LINE_RANGE +
|
||||
panda_file::LineNumberProgramItem::LINE_BASE;
|
||||
|
||||
state.AdvancePc(pc_diff);
|
||||
state.AdvanceLine(line_diff);
|
||||
|
||||
if (state.GetAddress() == bc_offset) {
|
||||
return state.GetLine();
|
||||
}
|
||||
|
||||
if (state.GetAddress() > bc_offset) {
|
||||
return prev_line;
|
||||
}
|
||||
|
||||
prev_line = state.GetLine();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state.GetLine();
|
||||
return resolver.GetLine();
|
||||
}
|
||||
|
||||
panda_file::File::StringData Method::GetClassSourceFile() const
|
||||
|
@ -344,6 +344,66 @@ TEST_F(MethodTest, GetLineNumFromBytecodeOffset9)
|
||||
VerifyLineNumber({3, 4, 5, 6, 6, 7, 9, 10, 16, 12, 13, 14, 15, 11});
|
||||
}
|
||||
|
||||
TEST_F(MethodTest, GetLineNumFromBytecodeOffset10)
|
||||
{
|
||||
pandasm::Parser p;
|
||||
|
||||
auto source = R"( # line 1
|
||||
.function void foo() { # line 2
|
||||
mov v0, v1 # line 3, offset 0, size 2
|
||||
mov v100, v200 # line 4, offset 2, size 3
|
||||
movi v0, 4 # line 5, offset 5, size 2
|
||||
movi v0, 100 # line 6, offset 7, size 3
|
||||
movi v0, 300 # line 7, offset 10, size 4
|
||||
return.void # line 8, offset 14, size 1
|
||||
}
|
||||
)";
|
||||
|
||||
auto res = p.Parse(source);
|
||||
auto &prog = res.Value();
|
||||
|
||||
auto &function = prog.function_table.at("foo");
|
||||
|
||||
pandasm::debuginfo::LocalVariable lv;
|
||||
lv.name = "a";
|
||||
lv.signature = "I";
|
||||
lv.reg = 0;
|
||||
lv.start = 0;
|
||||
lv.length = 5;
|
||||
|
||||
function.local_variable_debug.push_back(lv);
|
||||
|
||||
lv.name = "b";
|
||||
lv.start = 5;
|
||||
lv.length = 10;
|
||||
|
||||
function.local_variable_debug.push_back(lv);
|
||||
|
||||
auto pf = pandasm::AsmEmitter::Emit(res.Value());
|
||||
ASSERT_NE(pf, nullptr);
|
||||
|
||||
ClassLinker *class_linker = Runtime::GetCurrent()->GetClassLinker();
|
||||
class_linker->AddPandaFile(std::move(pf));
|
||||
auto *extension = class_linker->GetExtension(panda_file::SourceLang::PANDA_ASSEMBLY);
|
||||
|
||||
PandaString descriptor;
|
||||
|
||||
Class *klass = extension->GetClass(ClassHelper::GetDescriptor(utf::CStringAsMutf8("_GLOBAL"), &descriptor));
|
||||
ASSERT_NE(klass, nullptr);
|
||||
|
||||
Method *method = klass->GetDirectMethod(utf::CStringAsMutf8("foo"));
|
||||
ASSERT_NE(method, nullptr);
|
||||
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(0), 3);
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(2), 4);
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(5), 5);
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(7), 6);
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(10), 7);
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(14), 8);
|
||||
|
||||
ASSERT_EQ(method->GetLineNumFromBytecodeOffset(20), 8);
|
||||
}
|
||||
|
||||
TEST_F(MethodTest, GetClassSourceFile)
|
||||
{
|
||||
pandasm::Parser p;
|
||||
|
@ -51,10 +51,10 @@ echo "$MSG_PREFIX Cloning googletest from $GOOGLETEST_URL"
|
||||
|
||||
git clone --depth=1 --verbose "$GOOGLETEST_URL" "$PANDA_THIRD_PARTY_DIR/googletest"
|
||||
|
||||
MINIZ_URL="https://gitee.com/openharmony/third_party_miniz.git"
|
||||
echo "$MSG_PREFIX Cloning miniz from $MINIZ_URL"
|
||||
ZLIB_URL="https://gitee.com/openharmony/third_party_zlib.git"
|
||||
echo "$MSG_PREFIX Cloning zlib from $ZLIB_URL"
|
||||
|
||||
git clone --depth=1 --verbose "$MINIZ_URL" "$PANDA_THIRD_PARTY_DIR/miniz"
|
||||
git clone --depth=1 --verbose "$ZLIB_URL" "$PANDA_THIRD_PARTY_DIR/zlib"
|
||||
|
||||
echo "$MSG_PREFIX Third-party dependencies cloned"
|
||||
exit 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user