Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Host/common/ZipFileResolver.cpp
39607 views
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
9
#include "lldb/Host/common/ZipFileResolver.h"
10
#include "lldb/Host/FileSystem.h"
11
#include "lldb/Utility/DataBuffer.h"
12
#include "lldb/Utility/FileSpec.h"
13
#include "lldb/Utility/ZipFile.h"
14
15
using namespace lldb_private;
16
using namespace llvm::support;
17
18
bool ZipFileResolver::ResolveSharedLibraryPath(const FileSpec &file_spec,
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
}
73
74