DebugServer2
Loading...
Searching...
No Matches
FileOperationsMixin.hpp
1//
2// Copyright (c) 2014-present, Facebook, Inc.
3// All rights reserved.
4//
5// This source code is licensed under the University of Illinois/NCSA Open
6// Source License found in the LICENSE file in the root directory of this
7// source tree. An additional grant of patent rights can be found in the
8// PATENTS file in the same directory.
9//
10
11#pragma once
12
13#include "DebugServer2/GDBRemote/Mixins/FileOperationsMixin.h"
14#include "DebugServer2/Host/Platform.h"
15
16#include <filesystem>
17#include <iomanip>
18#include <sstream>
19
20using ds2::Host::File;
22
23namespace ds2 {
24namespace GDBRemote {
25
26template <typename T>
27std::string FileOperationsMixin<T>::resolvePath(Session &session,
28 std::string const &path) const {
29 if (std::filesystem::path(path).is_absolute()) {
30 return path;
31 }
32
33 std::string workingDirectory;
34 if (this->onQueryWorkingDirectory(session, workingDirectory) != kSuccess ||
35 workingDirectory.empty()) {
36 return path;
37 }
38
39 // onSetWorkingDirectory canonicalizes to an absolute path before storing
40 // it, so this join always yields an absolute result.
41 return (std::filesystem::path(workingDirectory) / path).string();
42}
43
44template <typename T>
45ErrorCode FileOperationsMixin<T>::onFileOpen(Session &session, std::string const &path,
46 OpenFlags flags, uint32_t mode,
47 int &fd) {
48 static int fileIdx = 0;
49
50 Host::File file(resolvePath(session, path), flags, mode);
51 if (!file.valid()) {
52 return file.lastError();
53 }
54
55 fd = fileIdx++;
56 _openFiles.emplace(fd, std::move(file));
57
58 return kSuccess;
59}
60
61template <typename T>
62ErrorCode FileOperationsMixin<T>::onFileClose(Session &session, int fd) {
63 auto const it = _openFiles.find(fd);
64 if (it == _openFiles.end()) {
65 return kErrorInvalidHandle;
66 }
67
68 _openFiles.erase(it);
69 return kSuccess;
70}
71
72template <typename T>
73ErrorCode FileOperationsMixin<T>::onFileRead(Session &session, int fd,
74 uint64_t &count, uint64_t offset,
75 ByteVector &buffer) {
76 auto it = _openFiles.find(fd);
77 if (it == _openFiles.end()) {
78 return kErrorInvalidHandle;
79 }
80
81 return it->second.pread(buffer, count, offset);
82}
83
84template <typename T>
85ErrorCode FileOperationsMixin<T>::onFileWrite(Session &session, int fd,
86 uint64_t offset,
87 ByteVector const &buffer,
88 uint64_t &nwritten) {
89 auto it = _openFiles.find(fd);
90 if (it == _openFiles.end()) {
91 return kErrorInvalidHandle;
92 }
93
94 return it->second.pwrite(buffer, nwritten, offset);
95}
96
97template <typename T>
98ErrorCode FileOperationsMixin<T>::onFileCreateDirectory(Session &session,
99 std::string const &path,
100 uint32_t flags) {
101 return Host::File::createDirectory(resolvePath(session, path), flags);
102}
103
104template <typename T>
105ErrorCode FileOperationsMixin<T>::onFileExists(Session &session,
106 std::string const &path) {
107 return Host::Platform::IsFilePresent(resolvePath(session, path)) ? kSuccess
108 : kErrorNotFound;
109}
110
111template <typename T>
112ErrorCode FileOperationsMixin<T>::onFileGetSize(Session &session, std::string const &path,
113 uint64_t &size){
114 return Host::File::fileSize(resolvePath(session, path), size);
115}
116
117template <typename T>
118ErrorCode FileOperationsMixin<T>::onFileGetMode(Session &session,
119 std::string const &path,
120 uint32_t &mode) const {
121 return Host::File::fileMode(resolvePath(session, path), mode);
122}
123
124template <typename T>
125ErrorCode FileOperationsMixin<T>::onFileFstat(Session &session, int fd,
126 ByteVector &buffer) const {
127 auto it = _openFiles.find(fd);
128 if (it == _openFiles.end())
129 return kErrorInvalidHandle;
130
131 return it->second.fstat(buffer);
132}
133
134template <typename T>
135ErrorCode FileOperationsMixin<T>::onFileRemove(Session &session,
136 std::string const &path) {
137 return Host::File::unlink(resolvePath(session, path));
138}
139
140template <typename T>
141ErrorCode FileOperationsMixin<T>::onFileSetPermissions(Session &session,
142 std::string const &path,
143 uint32_t mode) {
144 return Host::File::chmod(resolvePath(session, path), mode);
145}
146
147template <typename T>
148ErrorCode FileOperationsMixin<T>::onQueryModuleInfo(Session &session,
149 std::string &path,
150 std::string &triple,
151 ModuleInfo &info) const {
152 ByteVector buildId;
153 if (Platform::GetExecutableFileBuildID(path, buildId)) {
154 // format the uuid as an upper-case string with two hex chars per byte
155 std::ostringstream ss;
156 for(const auto b : buildId)
157 ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << int(b);
158
159 info.uuid = ss.str();
160 }
161
162 // TODO(andrurogerz): Not all executable files contain an embedded build ID.
163 // If GetExecutableFileBuildID fails, calculate an md5 hash of the file
164 // contents and return that as an "md5" field instead of the "uuid" field.
165
166 auto error = File::fileSize(path, info.file_size);
167 if (error != kSuccess)
168 return error;
169
170 info.triple = triple;
171 info.file_path = path;
172 info.file_offset = 0;
173
174 return kSuccess;
175}
176} // namespace GDBRemote
177} // namespace ds2
Definition File.h:24
Definition Platform.h:24