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
42namespace google_breakpad {
43
44// Traits classes so consumers can write templatized code to deal
45// with specific ELF bits.
46struct 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
64struct 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
82bool IsValidElf(const void* elf_header);
83int 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.
89bool 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.
97template<typename ElfClass>
98const typename ElfClass::Shdr*
99FindElfSectionByName(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
106struct 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.
114bool 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.
122template<typename ElfClass, typename T>
123const T*
124GetOffset(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.
129bool 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