1c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// Copyright (c) 2012, Google Inc. 2c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// All rights reserved. 3c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// 4c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// Redistribution and use in source and binary forms, with or without 5c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// modification, are permitted provided that the following conditions are 6c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// met: 7c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// 8c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// * Redistributions of source code must retain the above copyright 9c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// notice, this list of conditions and the following disclaimer. 10c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// * Redistributions in binary form must reproduce the above 11c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// copyright notice, this list of conditions and the following disclaimer 12c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// in the documentation and/or other materials provided with the 13c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// distribution. 14c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// * Neither the name of Google Inc. nor the names of its 15c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// contributors may be used to endorse or promote products derived from 16c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// this software without specific prior written permission. 17c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// 18c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// 30c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// elfutils.h: Utilities for dealing with ELF files. 31c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// 32c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 337f0b3e87dd3dd410c280b3f2c071813117c40aa2thestig@chromium.org#ifndef COMMON_LINUX_ELFUTILS_H_ 347f0b3e87dd3dd410c280b3f2c071813117c40aa2thestig@chromium.org#define COMMON_LINUX_ELFUTILS_H_ 35c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 36c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek#include <elf.h> 37c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek#include <link.h> 38c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek#include <stdint.h> 39c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 40c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczareknamespace google_breakpad { 41c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 42c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// Traits classes so consumers can write templatized code to deal 43c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// with specific ELF bits. 44c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarekstruct ElfClass32 { 45c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf32_Addr Addr; 46c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf32_Ehdr Ehdr; 47c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf32_Nhdr Nhdr; 48c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf32_Phdr Phdr; 49c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf32_Shdr Shdr; 507867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typedef Elf32_Half Half; 517867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typedef Elf32_Off Off; 527867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typedef Elf32_Word Word; 53c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek static const int kClass = ELFCLASS32; 547867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek static const size_t kAddrSize = sizeof(Elf32_Addr); 55c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek}; 56c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 57c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarekstruct ElfClass64 { 58c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf64_Addr Addr; 59c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf64_Ehdr Ehdr; 60c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf64_Nhdr Nhdr; 61c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf64_Phdr Phdr; 62c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek typedef Elf64_Shdr Shdr; 637867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typedef Elf64_Half Half; 647867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typedef Elf64_Off Off; 657867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typedef Elf64_Word Word; 66c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek static const int kClass = ELFCLASS64; 677867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek static const size_t kAddrSize = sizeof(Elf64_Addr); 68c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek}; 69c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 707867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarekbool IsValidElf(const void* elf_header); 717867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarekint ElfClass(const void* elf_base); 727867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek 73c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// Attempt to find a section named |section_name| of type |section_type| 74c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// in the ELF binary data at |elf_mapped_base|. On success, returns true 75c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// and sets |*section_start| to point to the start of the section data, 76c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// and |*section_size| to the size of the section's data. If |elfclass| 77c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek// is not NULL, set |*elfclass| to the ELF file class. 78c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarekbool FindElfSection(const void *elf_mapped_base, 79c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek const char *section_name, 80c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek uint32_t section_type, 81c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek const void **section_start, 827f0b3e87dd3dd410c280b3f2c071813117c40aa2thestig@chromium.org size_t *section_size, 83c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek int *elfclass); 84c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 857867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek// Internal helper method, exposed for convenience for callers 867867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek// that already have more info. 877867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarektemplate<typename ElfClass> 887867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarekconst typename ElfClass::Shdr* 897867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarekFindElfSectionByName(const char* name, 907867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typename ElfClass::Word section_type, 917867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek const typename ElfClass::Shdr* sections, 927867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek const char* section_names, 937867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek const char* names_end, 947867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek int nsection); 957867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek 96647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com// Attempt to find the first segment of type |segment_type| in the ELF 97647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com// binary data at |elf_mapped_base|. On success, returns true and sets 98647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com// |*segment_start| to point to the start of the segment data, and 99647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com// and |*segment_size| to the size of the segment's data. If |elfclass| 100647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com// is not NULL, set |*elfclass| to the ELF file class. 101647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.combool FindElfSegment(const void *elf_mapped_base, 102647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com uint32_t segment_type, 103647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com const void **segment_start, 1047f0b3e87dd3dd410c280b3f2c071813117c40aa2thestig@chromium.org size_t *segment_size, 105647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com int *elfclass); 106647f2b96ea04bdc46d0f315850f72bc0e5fbfd5dted.mielczarek@gmail.com 1077867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek// Convert an offset from an Elf header into a pointer to the mapped 1087867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek// address in the current process. Takes an extra template parameter 1097867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek// to specify the return type to avoid having to dynamic_cast the 1107867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek// result. 1117867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarektemplate<typename ElfClass, typename T> 1127867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarekconst T* 1137867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarekGetOffset(const typename ElfClass::Ehdr* elf_header, 1147867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek typename ElfClass::Off offset); 1157867fcbc885065ceb6afee36b824da9d0dd47fe8ted.mielczarek 116c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek} // namespace google_breakpad 117c71d9b4e80f47028a86b0392ba3b7c8d66590664ted.mielczarek 1187f0b3e87dd3dd410c280b3f2c071813117c40aa2thestig@chromium.org#endif // COMMON_LINUX_ELFUTILS_H_ 119