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