elfutils.cc revision 7867fcbc885065ceb6afee36b824da9d0dd47fe8
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#include "common/linux/elfutils.h" 31 32#include <assert.h> 33#include <string.h> 34 35#include "common/linux/linux_libc_support.h" 36#include "common/linux/elfutils-inl.h" 37 38namespace google_breakpad { 39 40namespace { 41 42template<typename ElfClass> 43void FindElfClassSection(const char *elf_base, 44 const char *section_name, 45 typename ElfClass::Word section_type, 46 const void **section_start, 47 int *section_size) { 48 typedef typename ElfClass::Ehdr Ehdr; 49 typedef typename ElfClass::Shdr Shdr; 50 51 assert(elf_base); 52 assert(section_start); 53 assert(section_size); 54 55 assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0); 56 57 const Ehdr* elf_header = reinterpret_cast<const Ehdr*>(elf_base); 58 assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); 59 60 const Shdr* sections = 61 GetOffset<ElfClass,Shdr>(elf_header, elf_header->e_shoff); 62 const Shdr* section_names = sections + elf_header->e_shstrndx; 63 const char* names = 64 GetOffset<ElfClass,char>(elf_header, section_names->sh_offset); 65 const char *names_end = names + section_names->sh_size; 66 67 const Shdr* section = 68 FindElfSectionByName<ElfClass>(section_name, section_type, 69 sections, names, names_end, 70 elf_header->e_shnum); 71 72 if (section != NULL && section->sh_size > 0) { 73 *section_start = elf_base + section->sh_offset; 74 *section_size = section->sh_size; 75 } 76} 77 78} // namespace 79 80bool IsValidElf(const void* elf_base) { 81 return my_strncmp(reinterpret_cast<const char*>(elf_base), 82 ELFMAG, SELFMAG) == 0; 83} 84 85int ElfClass(const void* elf_base) { 86 const ElfW(Ehdr)* elf_header = 87 reinterpret_cast<const ElfW(Ehdr)*>(elf_base); 88 89 return elf_header->e_ident[EI_CLASS]; 90} 91 92bool FindElfSection(const void *elf_mapped_base, 93 const char *section_name, 94 uint32_t section_type, 95 const void **section_start, 96 int *section_size, 97 int *elfclass) { 98 assert(elf_mapped_base); 99 assert(section_start); 100 assert(section_size); 101 102 *section_start = NULL; 103 *section_size = 0; 104 105 if (!IsValidElf(elf_mapped_base)) 106 return false; 107 108 int cls = ElfClass(elf_mapped_base); 109 if (elfclass) { 110 *elfclass = cls; 111 } 112 113 const char* elf_base = 114 static_cast<const char*>(elf_mapped_base); 115 116 if (cls == ELFCLASS32) { 117 FindElfClassSection<ElfClass32>(elf_base, section_name, section_type, 118 section_start, section_size); 119 return *section_start != NULL; 120 } else if (cls == ELFCLASS64) { 121 FindElfClassSection<ElfClass64>(elf_base, section_name, section_type, 122 section_start, section_size); 123 return *section_start != NULL; 124 } 125 126 return false; 127} 128 129} // namespace google_breakpad 130