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