blob: 1ce1fe67d3c2a8394e0a07d31f08a0b4dc1308ec [file] [log] [blame]
Yabin Cui18581af2022-01-20 11:03:14 -08001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <stdio.h>
20
21#include <memory>
22#include <string>
23
24#include <android-base/logging.h>
25
26#include "environment.h"
27
28namespace simpleperf {
29
30class TempSymFile {
31 public:
32 static std::unique_ptr<TempSymFile> Create(std::string&& path, bool remove_in_destructor) {
33 FILE* fp = fopen(path.data(), "web");
34 if (fp == nullptr) {
35 PLOG(ERROR) << "failed to create " << path;
36 return nullptr;
37 }
38 if (remove_in_destructor) {
39 ScopedTempFiles::RegisterTempFile(path);
40 }
Yabin Cuicac8eb02022-01-20 11:27:53 -080041 std::unique_ptr<TempSymFile> symfile(new TempSymFile(std::move(path), fp));
42 if (!symfile->WriteHeader()) {
43 return nullptr;
44 }
45 return symfile;
Yabin Cui18581af2022-01-20 11:03:14 -080046 }
47
48 bool WriteEntry(const char* data, size_t size) {
49 if (fwrite(data, size, 1, fp_.get()) != 1) {
50 PLOG(ERROR) << "failed to write to " << path_;
51 return false;
52 }
53 file_offset_ += size;
54 need_flush_ = true;
55 return true;
56 }
57
58 bool Flush() {
59 if (need_flush_) {
60 if (fflush(fp_.get()) != 0) {
61 PLOG(ERROR) << "failed to flush " << path_;
62 return false;
63 }
64 need_flush_ = false;
65 }
66 return true;
67 }
68
69 const std::string& GetPath() const { return path_; }
70 uint64_t GetOffset() const { return file_offset_; }
71
72 private:
73 TempSymFile(std::string&& path, FILE* fp) : path_(std::move(path)), fp_(fp, fclose) {}
74
Yabin Cuicac8eb02022-01-20 11:27:53 -080075 bool WriteHeader() {
76 char magic[8] = "JIT_SYM";
77 static_assert(sizeof(magic) == 8);
78 if (fwrite(magic, sizeof(magic), 1, fp_.get()) != 1) {
79 PLOG(ERROR) << "failed to write to " << path_;
80 return false;
81 }
82 file_offset_ = sizeof(magic);
83 return true;
84 }
85
Yabin Cui18581af2022-01-20 11:03:14 -080086 const std::string path_;
87 std::unique_ptr<FILE, decltype(&fclose)> fp_;
88 uint64_t file_offset_ = 0;
89 bool need_flush_ = false;
90};
91
92} // namespace simpleperf