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