Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/tools/profiler/lul/LulElfInt.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
4
// Copyright (c) 2006, 2012, Google Inc.
5
// All rights reserved.
6
//
7
// Redistribution and use in source and binary forms, with or without
8
// modification, are permitted provided that the following conditions are
9
// met:
10
//
11
//     * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
//     * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
16
// distribution.
17
//     * Neither the name of Google Inc. nor the names of its
18
// contributors may be used to endorse or promote products derived from
19
// this software without specific prior written permission.
20
//
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33
// This file is derived from the following files in
34
// toolkit/crashreporter/google-breakpad:
35
//   src/common/android/include/elf.h
36
//   src/common/linux/elfutils.h
37
//   src/common/linux/file_id.h
38
//   src/common/linux/elfutils-inl.h
39
40
#ifndef LulElfInt_h
41
#define LulElfInt_h
42
43
// This header defines functions etc internal to the ELF reader.  It
44
// should not be included outside of LulElf.cpp.
45
46
#include <elf.h>
47
#include <stdlib.h>
48
49
#include "mozilla/Assertions.h"
50
51
#include "PlatformMacros.h"
52
53
54
// (derived from)
55
// elfutils.h: Utilities for dealing with ELF files.
56
//
57
#include <link.h>
58
59
#if defined(GP_OS_android)
60
61
// From toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h
62
// The Android headers don't always define this constant.
63
#ifndef EM_X86_64
64
#define EM_X86_64  62
65
#endif
66
67
#ifndef EM_PPC64
68
#define EM_PPC64   21
69
#endif
70
71
#ifndef EM_S390
72
#define EM_S390    22
73
#endif
74
75
#ifndef NT_GNU_BUILD_ID
76
#define NT_GNU_BUILD_ID 3
77
#endif
78
79
#ifndef ElfW
80
#define ElfW(type)      _ElfW (Elf, ELFSIZE, type)
81
#define _ElfW(e,w,t)    _ElfW_1 (e, w, _##t)
82
#define _ElfW_1(e,w,t)  e##w##t
83
#endif
84
85
#endif
86
87
88
namespace lul {
89
90
// Traits classes so consumers can write templatized code to deal
91
// with specific ELF bits.
92
struct ElfClass32 {
93
  typedef Elf32_Addr Addr;
94
  typedef Elf32_Ehdr Ehdr;
95
  typedef Elf32_Nhdr Nhdr;
96
  typedef Elf32_Phdr Phdr;
97
  typedef Elf32_Shdr Shdr;
98
  typedef Elf32_Half Half;
99
  typedef Elf32_Off Off;
100
  typedef Elf32_Word Word;
101
  static const int kClass = ELFCLASS32;
102
  static const size_t kAddrSize = sizeof(Elf32_Addr);
103
};
104
105
struct ElfClass64 {
106
  typedef Elf64_Addr Addr;
107
  typedef Elf64_Ehdr Ehdr;
108
  typedef Elf64_Nhdr Nhdr;
109
  typedef Elf64_Phdr Phdr;
110
  typedef Elf64_Shdr Shdr;
111
  typedef Elf64_Half Half;
112
  typedef Elf64_Off Off;
113
  typedef Elf64_Word Word;
114
  static const int kClass = ELFCLASS64;
115
  static const size_t kAddrSize = sizeof(Elf64_Addr);
116
};
117
118
bool IsValidElf(const void* elf_header);
119
int ElfClass(const void* elf_base);
120
121
// Attempt to find a section named |section_name| of type |section_type|
122
// in the ELF binary data at |elf_mapped_base|. On success, returns true
123
// and sets |*section_start| to point to the start of the section data,
124
// and |*section_size| to the size of the section's data. If |elfclass|
125
// is not NULL, set |*elfclass| to the ELF file class.
126
bool FindElfSection(const void *elf_mapped_base,
127
                    const char *section_name,
128
                    uint32_t section_type,
129
                    const void **section_start,
130
                    int *section_size,
131
                    int *elfclass);
132
133
// Internal helper method, exposed for convenience for callers
134
// that already have more info.
135
template<typename ElfClass>
136
const typename ElfClass::Shdr*
137
FindElfSectionByName(const char* name,
138
                     typename ElfClass::Word section_type,
139
                     const typename ElfClass::Shdr* sections,
140
                     const char* section_names,
141
                     const char* names_end,
142
                     int nsection);
143
144
// Attempt to find the first segment of type |segment_type| in the ELF
145
// binary data at |elf_mapped_base|. On success, returns true and sets
146
// |*segment_start| to point to the start of the segment data, and
147
// and |*segment_size| to the size of the segment's data. If |elfclass|
148
// is not NULL, set |*elfclass| to the ELF file class.
149
bool FindElfSegment(const void *elf_mapped_base,
150
                    uint32_t segment_type,
151
                    const void **segment_start,
152
                    int *segment_size,
153
                    int *elfclass);
154
155
// Convert an offset from an Elf header into a pointer to the mapped
156
// address in the current process. Takes an extra template parameter
157
// to specify the return type to avoid having to dynamic_cast the
158
// result.
159
template<typename ElfClass, typename T>
160
const T*
161
GetOffset(const typename ElfClass::Ehdr* elf_header,
162
          typename ElfClass::Off offset);
163
164
165
// (derived from)
166
// file_id.h: Return a unique identifier for a file
167
//
168
169
static const size_t kMDGUIDSize = sizeof(MDGUID);
170
171
class FileID {
172
 public:
173
174
  // Load the identifier for the elf file mapped into memory at |base| into
175
  // |identifier|.  Return false if the identifier could not be created for the
176
  // file.
177
  static bool ElfFileIdentifierFromMappedFile(const void* base,
178
                                              uint8_t identifier[kMDGUIDSize]);
179
180
  // Convert the |identifier| data to a NULL terminated string.  The string will
181
  // be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
182
  // The |buffer| should be at least 37 bytes long to receive all of the data
183
  // and termination.  Shorter buffers will contain truncated data.
184
  static void ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize],
185
                                        char* buffer, int buffer_length);
186
};
187
188
189
190
template<typename ElfClass, typename T>
191
const T* GetOffset(const typename ElfClass::Ehdr* elf_header,
192
0
                   typename ElfClass::Off offset) {
193
0
  return reinterpret_cast<const T*>(reinterpret_cast<uintptr_t>(elf_header) +
194
0
                                    offset);
195
0
}
Unexecuted instantiation: Elf32_Phdr const* lul::GetOffset<lul::ElfClass32, Elf32_Phdr>(lul::ElfClass32::Ehdr const*, lul::ElfClass32::Off)
Unexecuted instantiation: Elf32_Shdr const* lul::GetOffset<lul::ElfClass32, Elf32_Shdr>(lul::ElfClass32::Ehdr const*, lul::ElfClass32::Off)
Unexecuted instantiation: char const* lul::GetOffset<lul::ElfClass32, char>(lul::ElfClass32::Ehdr const*, lul::ElfClass32::Off)
Unexecuted instantiation: Elf64_Phdr const* lul::GetOffset<lul::ElfClass64, Elf64_Phdr>(lul::ElfClass64::Ehdr const*, lul::ElfClass64::Off)
Unexecuted instantiation: Elf64_Shdr const* lul::GetOffset<lul::ElfClass64, Elf64_Shdr>(lul::ElfClass64::Ehdr const*, lul::ElfClass64::Off)
Unexecuted instantiation: char const* lul::GetOffset<lul::ElfClass64, char>(lul::ElfClass64::Ehdr const*, lul::ElfClass64::Off)
196
197
template<typename ElfClass>
198
const typename ElfClass::Shdr* FindElfSectionByName(
199
    const char* name,
200
    typename ElfClass::Word section_type,
201
    const typename ElfClass::Shdr* sections,
202
    const char* section_names,
203
    const char* names_end,
204
0
    int nsection) {
205
0
  MOZ_ASSERT(name != NULL);
206
0
  MOZ_ASSERT(sections != NULL);
207
0
  MOZ_ASSERT(nsection > 0);
208
0
209
0
  int name_len = strlen(name);
210
0
  if (name_len == 0)
211
0
    return NULL;
212
0
213
0
  for (int i = 0; i < nsection; ++i) {
214
0
    const char* section_name = section_names + sections[i].sh_name;
215
0
    if (sections[i].sh_type == section_type &&
216
0
        names_end - section_name >= name_len + 1 &&
217
0
        strcmp(name, section_name) == 0) {
218
0
      return sections + i;
219
0
    }
220
0
  }
221
0
  return NULL;
222
0
}
Unexecuted instantiation: lul::ElfClass32::Shdr const* lul::FindElfSectionByName<lul::ElfClass32>(char const*, lul::ElfClass32::Word, lul::ElfClass32::Shdr const*, char const*, char const*, int)
Unexecuted instantiation: lul::ElfClass64::Shdr const* lul::FindElfSectionByName<lul::ElfClass64>(char const*, lul::ElfClass64::Word, lul::ElfClass64::Shdr const*, char const*, char const*, int)
223
224
} // namespace lul
225
226
227
// And finally, the external interface, offered to LulMain.cpp
228
#include "LulElfExt.h"
229
230
#endif // LulElfInt_h