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