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