xref: /aosp_15_r20/system/extras/simpleperf/read_elf.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 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 #ifndef SIMPLE_PERF_READ_ELF_H_
18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_READ_ELF_H_
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <functional>
21*288bf522SAndroid Build Coastguard Worker #include <ostream>
22*288bf522SAndroid Build Coastguard Worker #include <string>
23*288bf522SAndroid Build Coastguard Worker #include "build_id.h"
24*288bf522SAndroid Build Coastguard Worker 
25*288bf522SAndroid Build Coastguard Worker namespace llvm {
26*288bf522SAndroid Build Coastguard Worker class MemoryBuffer;
27*288bf522SAndroid Build Coastguard Worker }
28*288bf522SAndroid Build Coastguard Worker 
29*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
30*288bf522SAndroid Build Coastguard Worker 
31*288bf522SAndroid Build Coastguard Worker // Read ELF functions are called in different situations, so it is hard to
32*288bf522SAndroid Build Coastguard Worker // decide whether to report error or not. So read ELF functions don't report
33*288bf522SAndroid Build Coastguard Worker // error when something wrong happens, instead they return ElfStatus, which
34*288bf522SAndroid Build Coastguard Worker // identifies different errors met while reading elf file.
35*288bf522SAndroid Build Coastguard Worker enum class ElfStatus {
36*288bf522SAndroid Build Coastguard Worker   NO_ERROR,
37*288bf522SAndroid Build Coastguard Worker   FILE_NOT_FOUND,
38*288bf522SAndroid Build Coastguard Worker   READ_FAILED,
39*288bf522SAndroid Build Coastguard Worker   FILE_MALFORMED,
40*288bf522SAndroid Build Coastguard Worker   NO_SYMBOL_TABLE,
41*288bf522SAndroid Build Coastguard Worker   NO_BUILD_ID,
42*288bf522SAndroid Build Coastguard Worker   BUILD_ID_MISMATCH,
43*288bf522SAndroid Build Coastguard Worker   SECTION_NOT_FOUND,
44*288bf522SAndroid Build Coastguard Worker };
45*288bf522SAndroid Build Coastguard Worker 
46*288bf522SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const ElfStatus& status);
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker ElfStatus GetBuildIdFromNoteFile(const std::string& filename, BuildId* build_id);
49*288bf522SAndroid Build Coastguard Worker 
50*288bf522SAndroid Build Coastguard Worker // The symbol prefix used to indicate that the symbol belongs to android linker.
51*288bf522SAndroid Build Coastguard Worker static const std::string linker_prefix = "__dl_";
52*288bf522SAndroid Build Coastguard Worker 
53*288bf522SAndroid Build Coastguard Worker struct ElfFileSymbol {
54*288bf522SAndroid Build Coastguard Worker   uint64_t vaddr;
55*288bf522SAndroid Build Coastguard Worker   uint64_t len;
56*288bf522SAndroid Build Coastguard Worker   bool is_func;
57*288bf522SAndroid Build Coastguard Worker   bool is_label;
58*288bf522SAndroid Build Coastguard Worker   bool is_in_text_section;
59*288bf522SAndroid Build Coastguard Worker   std::string name;
60*288bf522SAndroid Build Coastguard Worker 
ElfFileSymbolElfFileSymbol61*288bf522SAndroid Build Coastguard Worker   ElfFileSymbol() : vaddr(0), len(0), is_func(false), is_label(false), is_in_text_section(false) {}
62*288bf522SAndroid Build Coastguard Worker };
63*288bf522SAndroid Build Coastguard Worker 
64*288bf522SAndroid Build Coastguard Worker struct ElfSegment {
65*288bf522SAndroid Build Coastguard Worker   uint64_t vaddr = 0;
66*288bf522SAndroid Build Coastguard Worker   uint64_t file_offset = 0;
67*288bf522SAndroid Build Coastguard Worker   uint64_t file_size = 0;
68*288bf522SAndroid Build Coastguard Worker   bool is_executable = false;
69*288bf522SAndroid Build Coastguard Worker   bool is_load = false;
70*288bf522SAndroid Build Coastguard Worker };
71*288bf522SAndroid Build Coastguard Worker 
72*288bf522SAndroid Build Coastguard Worker struct ElfSection {
73*288bf522SAndroid Build Coastguard Worker   std::string name;
74*288bf522SAndroid Build Coastguard Worker   uint64_t vaddr = 0;
75*288bf522SAndroid Build Coastguard Worker   uint64_t file_offset = 0;
76*288bf522SAndroid Build Coastguard Worker   uint64_t size = 0;
77*288bf522SAndroid Build Coastguard Worker };
78*288bf522SAndroid Build Coastguard Worker 
79*288bf522SAndroid Build Coastguard Worker class ElfFile {
80*288bf522SAndroid Build Coastguard Worker  public:
81*288bf522SAndroid Build Coastguard Worker   // Report error instead of returning status.
82*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<ElfFile> Open(const std::string& filename);
Open(const std::string & filename,ElfStatus * status)83*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<ElfFile> Open(const std::string& filename, ElfStatus* status) {
84*288bf522SAndroid Build Coastguard Worker     return Open(filename, nullptr, status);
85*288bf522SAndroid Build Coastguard Worker   }
86*288bf522SAndroid Build Coastguard Worker 
87*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<ElfFile> Open(const std::string& filename,
88*288bf522SAndroid Build Coastguard Worker                                        const BuildId* expected_build_id, ElfStatus* status);
89*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<ElfFile> Open(const char* data, size_t size, ElfStatus* status);
~ElfFile()90*288bf522SAndroid Build Coastguard Worker   virtual ~ElfFile() {}
91*288bf522SAndroid Build Coastguard Worker 
92*288bf522SAndroid Build Coastguard Worker   virtual bool Is64Bit() = 0;
93*288bf522SAndroid Build Coastguard Worker   virtual llvm::MemoryBuffer* GetMemoryBuffer() = 0;
94*288bf522SAndroid Build Coastguard Worker   virtual std::vector<ElfSegment> GetProgramHeader() = 0;
95*288bf522SAndroid Build Coastguard Worker   virtual std::vector<ElfSection> GetSectionHeader() = 0;
96*288bf522SAndroid Build Coastguard Worker   virtual ElfStatus GetBuildId(BuildId* build_id) = 0;
97*288bf522SAndroid Build Coastguard Worker 
98*288bf522SAndroid Build Coastguard Worker   using ParseSymbolCallback = std::function<void(const ElfFileSymbol&)>;
99*288bf522SAndroid Build Coastguard Worker   virtual ElfStatus ParseSymbols(const ParseSymbolCallback& callback) = 0;
100*288bf522SAndroid Build Coastguard Worker   virtual void ParseDynamicSymbols(const ParseSymbolCallback& callback) = 0;
101*288bf522SAndroid Build Coastguard Worker 
102*288bf522SAndroid Build Coastguard Worker   virtual ElfStatus ReadSection(const std::string& section_name, std::string* content) = 0;
103*288bf522SAndroid Build Coastguard Worker   virtual uint64_t ReadMinExecutableVaddr(uint64_t* file_offset_of_min_vaddr) = 0;
104*288bf522SAndroid Build Coastguard Worker   virtual bool VaddrToOff(uint64_t vaddr, uint64_t* file_offset) = 0;
105*288bf522SAndroid Build Coastguard Worker 
106*288bf522SAndroid Build Coastguard Worker  protected:
ElfFile()107*288bf522SAndroid Build Coastguard Worker   ElfFile() {}
108*288bf522SAndroid Build Coastguard Worker };
109*288bf522SAndroid Build Coastguard Worker 
110*288bf522SAndroid Build Coastguard Worker bool IsArmMappingSymbol(const char* name);
111*288bf522SAndroid Build Coastguard Worker ElfStatus IsValidElfFile(int fd, uint64_t file_offset = 0);
112*288bf522SAndroid Build Coastguard Worker bool IsValidElfFileMagic(const char* buf, size_t buf_size);
113*288bf522SAndroid Build Coastguard Worker bool GetBuildIdFromNoteSection(const char* section, size_t section_size, BuildId* build_id);
114*288bf522SAndroid Build Coastguard Worker 
115*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
116*288bf522SAndroid Build Coastguard Worker 
117*288bf522SAndroid Build Coastguard Worker #endif  // SIMPLE_PERF_READ_ELF_H_
118