1 // Copyright (c) 2012, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // 30 // elfutils.h: Utilities for dealing with ELF files. 31 // 32 33 #ifndef COMMON_LINUX_ELFUTILS_H_ 34 #define COMMON_LINUX_ELFUTILS_H_ 35 36 #include <elf.h> 37 #include <link.h> 38 #include <stdint.h> 39 40 #include "common/memory_allocator.h" 41 42 namespace google_breakpad { 43 44 // Traits classes so consumers can write templatized code to deal 45 // with specific ELF bits. 46 struct ElfClass32 { 47 typedef Elf32_Addr Addr; 48 typedef Elf32_Dyn Dyn; 49 typedef Elf32_Ehdr Ehdr; 50 typedef Elf32_Nhdr Nhdr; 51 typedef Elf32_Phdr Phdr; 52 typedef Elf32_Shdr Shdr; 53 typedef Elf32_Half Half; 54 typedef Elf32_Off Off; 55 typedef Elf32_Sym Sym; 56 typedef Elf32_Word Word; 57 58 static const int kClass = ELFCLASS32; 59 static const uint16_t kMachine = EM_386; 60 static const size_t kAddrSize = sizeof(Elf32_Addr); 61 static constexpr const char* kMachineName = "x86"; 62 }; 63 64 struct ElfClass64 { 65 typedef Elf64_Addr Addr; 66 typedef Elf64_Dyn Dyn; 67 typedef Elf64_Ehdr Ehdr; 68 typedef Elf64_Nhdr Nhdr; 69 typedef Elf64_Phdr Phdr; 70 typedef Elf64_Shdr Shdr; 71 typedef Elf64_Half Half; 72 typedef Elf64_Off Off; 73 typedef Elf64_Sym Sym; 74 typedef Elf64_Word Word; 75 76 static const int kClass = ELFCLASS64; 77 static const uint16_t kMachine = EM_X86_64; 78 static const size_t kAddrSize = sizeof(Elf64_Addr); 79 static constexpr const char* kMachineName = "x86_64"; 80 }; 81 82 bool IsValidElf(const void* elf_header); 83 int ElfClass(const void* elf_base); 84 85 // Attempt to find a section named |section_name| of type |section_type| 86 // in the ELF binary data at |elf_mapped_base|. On success, returns true 87 // and sets |*section_start| to point to the start of the section data, 88 // and |*section_size| to the size of the section's data. 89 bool FindElfSection(const void *elf_mapped_base, 90 const char *section_name, 91 uint32_t section_type, 92 const void **section_start, 93 size_t *section_size); 94 95 // Internal helper method, exposed for convenience for callers 96 // that already have more info. 97 template<typename ElfClass> 98 const typename ElfClass::Shdr* 99 FindElfSectionByName(const char* name, 100 typename ElfClass::Word section_type, 101 const typename ElfClass::Shdr* sections, 102 const char* section_names, 103 const char* names_end, 104 int nsection); 105 106 struct ElfSegment { 107 const void* start; 108 size_t size; 109 }; 110 111 // Attempt to find all segments of type |segment_type| in the ELF 112 // binary data at |elf_mapped_base|. On success, returns true and fills 113 // |*segments| with a list of segments of the given type. 114 bool FindElfSegments(const void* elf_mapped_base, 115 uint32_t segment_type, 116 wasteful_vector<ElfSegment>* segments); 117 118 // Convert an offset from an Elf header into a pointer to the mapped 119 // address in the current process. Takes an extra template parameter 120 // to specify the return type to avoid having to dynamic_cast the 121 // result. 122 template<typename ElfClass, typename T> 123 const T* 124 GetOffset(const typename ElfClass::Ehdr* elf_header, 125 typename ElfClass::Off offset); 126 127 // Read the value of DT_SONAME from the elf file mapped at |elf_base|. Returns 128 // true and fills |soname| with the result if found. 129 bool ElfFileSoNameFromMappedFile(const void* elf_base, 130 char* soname, 131 size_t soname_size); 132 133 } // namespace google_breakpad 134 135 #endif // COMMON_LINUX_ELFUTILS_H_ 136