elfutils.cc revision c71d9b4e80f47028a86b0392ba3b7c8d66590664
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 37namespace google_breakpad { 38 39namespace { 40 41template<typename ElfClass> 42void FindElfClassSection(const char *elf_base, 43 const char *section_name, 44 uint32_t section_type, 45 const void **section_start, 46 int *section_size) { 47 typedef typename ElfClass::Ehdr Ehdr; 48 typedef typename ElfClass::Shdr Shdr; 49 50 assert(elf_base); 51 assert(section_start); 52 assert(section_size); 53 54 assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0); 55 56 int name_len = my_strlen(section_name); 57 58 const Ehdr* elf_header = reinterpret_cast<const Ehdr*>(elf_base); 59 assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); 60 61 const Shdr* sections = 62 reinterpret_cast<const Shdr*>(elf_base + elf_header->e_shoff); 63 const Shdr* string_section = sections + elf_header->e_shstrndx; 64 65 const Shdr* section = NULL; 66 for (int i = 0; i < elf_header->e_shnum; ++i) { 67 if (sections[i].sh_type == section_type) { 68 const char* current_section_name = (char*)(elf_base + 69 string_section->sh_offset + 70 sections[i].sh_name); 71 if (!my_strncmp(current_section_name, section_name, name_len)) { 72 section = §ions[i]; 73 break; 74 } 75 } 76 } 77 if (section != NULL && section->sh_size > 0) { 78 *section_start = elf_base + section->sh_offset; 79 *section_size = section->sh_size; 80 } 81} 82 83} // namespace 84 85bool FindElfSection(const void *elf_mapped_base, 86 const char *section_name, 87 uint32_t section_type, 88 const void **section_start, 89 int *section_size, 90 int *elfclass) { 91 assert(elf_mapped_base); 92 assert(section_start); 93 assert(section_size); 94 95 *section_start = NULL; 96 *section_size = 0; 97 98 const char* elf_base = 99 static_cast<const char*>(elf_mapped_base); 100 const ElfW(Ehdr)* elf_header = 101 reinterpret_cast<const ElfW(Ehdr)*>(elf_base); 102 if (my_strncmp(elf_base, ELFMAG, SELFMAG) != 0) 103 return false; 104 105 if (elfclass) { 106 *elfclass = elf_header->e_ident[EI_CLASS]; 107 } 108 109 if (elf_header->e_ident[EI_CLASS] == ELFCLASS32) { 110 FindElfClassSection<ElfClass32>(elf_base, section_name, section_type, 111 section_start, section_size); 112 return *section_start != NULL; 113 } else if (elf_header->e_ident[EI_CLASS] == ELFCLASS64) { 114 FindElfClassSection<ElfClass64>(elf_base, section_name, section_type, 115 section_start, section_size); 116 return *section_start != NULL; 117 } 118 119 return false; 120} 121 122} // namespace google_breakpad 123