LLDB mainline
ZipFileResolver.cpp
Go to the documentation of this file.
1//===-- ZipFileResolver.cpp -----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
14
15using namespace lldb_private;
16using namespace llvm::support;
17
19 FileKind &file_kind,
20 std::string &file_path,
21 lldb::offset_t &so_file_offset,
22 lldb::offset_t &so_file_size) {
23 // When bionic loads .so file from APK or zip file, this file_spec will be
24 // "zip_path!/so_path". Otherwise it is just a normal file path.
25 static constexpr llvm::StringLiteral k_zip_separator("!/");
26 std::string path(file_spec.GetPath());
27 size_t pos = path.find(k_zip_separator);
28
29#if defined(_WIN32)
30 // When the file_spec is resolved as a Windows path, the zip .so path will be
31 // "zip_path!\so_path". Support both patterns on Windows.
32 static constexpr llvm::StringLiteral k_zip_separator_win("!\\");
33 if (pos == std::string::npos)
34 pos = path.find(k_zip_separator_win);
35#endif
36
37 if (pos == std::string::npos) {
38 // This file_spec does not contain the zip separator.
39 // Treat this file_spec as a normal file.
40 // so_file_offset and so_file_size should be 0.
41 file_kind = FileKind::eFileKindNormal;
42 file_path = path;
43 so_file_offset = 0;
44 so_file_size = 0;
45 return true;
46 }
47
48 // This file_spec is a zip .so path. Extract the zip path and the .so path.
49 std::string zip_path(path.substr(0, pos));
50 std::string so_path(path.substr(pos + k_zip_separator.size()));
51
52#if defined(_WIN32)
53 // Replace the .so path to use POSIX file separator for file searching inside
54 // the zip file.
55 std::replace(so_path.begin(), so_path.end(), '\\', '/');
56#endif
57
58 // Try to find the .so file from the zip file.
59 FileSpec zip_file_spec(zip_path);
60 uint64_t zip_file_size = FileSystem::Instance().GetByteSize(zip_file_spec);
61 lldb::DataBufferSP zip_data =
62 FileSystem::Instance().CreateDataBuffer(zip_file_spec, zip_file_size);
63 if (ZipFile::Find(zip_data, so_path, so_file_offset, so_file_size)) {
64 // Found the .so file from the zip file and got the file offset and size.
65 // Return the zip path. so_file_offset and so_file_size are already set.
66 file_kind = FileKind::eFileKindZip;
67 file_path = zip_path;
68 return true;
69 }
70
71 return false;
72}
A file utility class.
Definition: FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
uint64_t GetByteSize(const FileSpec &file_spec) const
Returns the on-disk size of the given file in bytes.
static FileSystem & Instance()
std::shared_ptr< DataBuffer > CreateDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
Create memory buffer from path.
static bool ResolveSharedLibraryPath(const FileSpec &file_spec, FileKind &file_kind, std::string &file_path, lldb::offset_t &so_file_offset, lldb::offset_t &so_file_size)
static bool Find(lldb::DataBufferSP zip_data, const llvm::StringRef file_path, lldb::offset_t &file_offset, lldb::offset_t &file_size)
Definition: ZipFile.cpp:173
A class that represents a running process on the host machine.
uint64_t offset_t
Definition: lldb-types.h:85
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
Definition: lldb-forward.h:331