Files
clang-p2996/lldb/source/Host/common/ZipFileResolver.cpp
Kazuki Sakamoto 5c4071d225 [lldb][Windows] Fix ZipFileResolver tests
D152759 introduced the Android .zip so file support, but it only considered
POSIX path. The code also runs on Windows, so the path could be Windows path.
Support both patterns on Windows.

Differential Revision: https://reviews.llvm.org/D153390
2023-06-22 10:42:40 -07:00

73 lines
2.8 KiB
C++

//===-- ZipFileResolver.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "lldb/Host/common/ZipFileResolver.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/ZipFile.h"
using namespace lldb_private;
using namespace llvm::support;
bool ZipFileResolver::ResolveSharedLibraryPath(const FileSpec &file_spec,
FileKind &file_kind,
std::string &file_path,
lldb::offset_t &so_file_offset,
lldb::offset_t &so_file_size) {
// When bionic loads .so file from APK or zip file, this file_spec will be
// "zip_path!/so_path". Otherwise it is just a normal file path.
static constexpr llvm::StringLiteral k_zip_separator("!/");
std::string path(file_spec.GetPath());
size_t pos = path.find(k_zip_separator);
#if defined(_WIN32)
// When the file_spec is resolved as a Windows path, the zip .so path will be
// "zip_path!\so_path". Support both patterns on Windows.
static constexpr llvm::StringLiteral k_zip_separator_win("!\\");
if (pos == std::string::npos)
pos = path.find(k_zip_separator_win);
#endif
if (pos == std::string::npos) {
// This file_spec does not contain the zip separator.
// Treat this file_spec as a normal file.
// so_file_offset and so_file_size should be 0.
file_kind = FileKind::eFileKindNormal;
file_path = path;
so_file_offset = 0;
so_file_size = 0;
return true;
}
// This file_spec is a zip .so path. Extract the zip path and the .so path.
std::string zip_path(path.substr(0, pos));
std::string so_path(path.substr(pos + k_zip_separator.size()));
#if defined(_WIN32)
// Replace the .so path to use POSIX file separator for file searching inside
// the zip file.
std::replace(so_path.begin(), so_path.end(), '\\', '/');
#endif
// Try to find the .so file from the zip file.
FileSpec zip_file_spec(zip_path);
uint64_t zip_file_size = FileSystem::Instance().GetByteSize(zip_file_spec);
lldb::DataBufferSP zip_data =
FileSystem::Instance().CreateDataBuffer(zip_file_spec, zip_file_size);
if (ZipFile::Find(zip_data, so_path, so_file_offset, so_file_size)) {
// Found the .so file from the zip file and got the file offset and size.
// Return the zip path. so_file_offset and so_file_size are already set.
file_kind = FileKind::eFileKindZip;
file_path = zip_path;
return true;
}
return false;
}