Path: blob/main/contrib/llvm-project/lldb/source/Host/common/ZipFileResolver.cpp
39607 views
//===-- ZipFileResolver.cpp -----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Host/common/ZipFileResolver.h"9#include "lldb/Host/FileSystem.h"10#include "lldb/Utility/DataBuffer.h"11#include "lldb/Utility/FileSpec.h"12#include "lldb/Utility/ZipFile.h"1314using namespace lldb_private;15using namespace llvm::support;1617bool ZipFileResolver::ResolveSharedLibraryPath(const FileSpec &file_spec,18FileKind &file_kind,19std::string &file_path,20lldb::offset_t &so_file_offset,21lldb::offset_t &so_file_size) {22// When bionic loads .so file from APK or zip file, this file_spec will be23// "zip_path!/so_path". Otherwise it is just a normal file path.24static constexpr llvm::StringLiteral k_zip_separator("!/");25std::string path(file_spec.GetPath());26size_t pos = path.find(k_zip_separator);2728#if defined(_WIN32)29// When the file_spec is resolved as a Windows path, the zip .so path will be30// "zip_path!\so_path". Support both patterns on Windows.31static constexpr llvm::StringLiteral k_zip_separator_win("!\\");32if (pos == std::string::npos)33pos = path.find(k_zip_separator_win);34#endif3536if (pos == std::string::npos) {37// This file_spec does not contain the zip separator.38// Treat this file_spec as a normal file.39// so_file_offset and so_file_size should be 0.40file_kind = FileKind::eFileKindNormal;41file_path = path;42so_file_offset = 0;43so_file_size = 0;44return true;45}4647// This file_spec is a zip .so path. Extract the zip path and the .so path.48std::string zip_path(path.substr(0, pos));49std::string so_path(path.substr(pos + k_zip_separator.size()));5051#if defined(_WIN32)52// Replace the .so path to use POSIX file separator for file searching inside53// the zip file.54std::replace(so_path.begin(), so_path.end(), '\\', '/');55#endif5657// Try to find the .so file from the zip file.58FileSpec zip_file_spec(zip_path);59uint64_t zip_file_size = FileSystem::Instance().GetByteSize(zip_file_spec);60lldb::DataBufferSP zip_data =61FileSystem::Instance().CreateDataBuffer(zip_file_spec, zip_file_size);62if (ZipFile::Find(zip_data, so_path, so_file_offset, so_file_size)) {63// Found the .so file from the zip file and got the file offset and size.64// Return the zip path. so_file_offset and so_file_size are already set.65file_kind = FileKind::eFileKindZip;66file_path = zip_path;67return true;68}6970return false;71}727374