Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
Line
Count
Source (jump to first uncovered line)
1
//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
/// \file
10
/// Generic structures and typedefs for ELF files.
11
///
12
/// This file provides definitions for the various entities comprising an ELF
13
/// file.  The structures are generic in the sense that they do not correspond
14
/// to the exact binary layout of an ELF, but can be used to hold the
15
/// information present in both 32 and 64 bit variants of the format.  Each
16
/// entity provides a \c Parse method which is capable of transparently
17
/// reading both 32 and 64 bit instances of the object.
18
//===----------------------------------------------------------------------===//
19
20
#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
21
#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
22
23
#include "llvm/BinaryFormat/ELF.h"
24
25
#include "lldb/lldb-enumerations.h"
26
#include "lldb/lldb-types.h"
27
28
namespace lldb_private {
29
class DataExtractor;
30
} // End namespace lldb_private.
31
32
namespace elf {
33
34
/// \name ELF type definitions.
35
///
36
/// Types used to represent the various components of ELF structures.  All
37
/// types are signed or unsigned integral types wide enough to hold values
38
/// from both
39
/// 32 and 64 bit ELF variants.
40
//@{
41
typedef uint64_t elf_addr;
42
typedef uint64_t elf_off;
43
typedef uint16_t elf_half;
44
typedef uint32_t elf_word;
45
typedef int32_t elf_sword;
46
typedef uint64_t elf_size;
47
typedef uint64_t elf_xword;
48
typedef int64_t elf_sxword;
49
//@}
50
51
/// \class ELFHeader
52
/// Generic representation of an ELF file header.
53
///
54
/// This object is used to identify the general attributes on an ELF file and
55
/// to locate additional sections within the file.
56
struct ELFHeader {
57
  unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
58
  elf_addr e_entry;     ///< Virtual address program entry point.
59
  elf_off e_phoff;      ///< File offset of program header table.
60
  elf_off e_shoff;      ///< File offset of section header table.
61
  elf_word e_flags;     ///< Processor specific flags.
62
  elf_word e_version;   ///< Version of object file (always 1).
63
  elf_half e_type;      ///< Object file type.
64
  elf_half e_machine;   ///< Target architecture.
65
  elf_half e_ehsize;    ///< Byte size of the ELF header.
66
  elf_half e_phentsize; ///< Size of a program header table entry.
67
  elf_half e_phnum_hdr; ///< Number of program header entries.
68
  elf_half e_shentsize; ///< Size of a section header table entry.
69
  elf_half e_shnum_hdr; ///< Number of section header entries.
70
  elf_half e_shstrndx_hdr; ///< String table section index.
71
72
  // In some cases these numbers do not fit in 16 bits and they are
73
  // stored outside of the header in section #0. Here are the actual
74
  // values.
75
  elf_word e_phnum;     ///< Number of program header entries.
76
  elf_word e_shnum;     ///< Number of section header entries.
77
  elf_word e_shstrndx;  ///< String table section index.
78
79
  ELFHeader();
80
81
  /// Returns true if this is a 32 bit ELF file header.
82
  ///
83
  /// \return
84
  ///    True if this is a 32 bit ELF file header.
85
19.9k
  bool Is32Bit() const {
86
19.9k
    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
87
19.9k
  }
88
89
  /// Returns true if this is a 64 bit ELF file header.
90
  ///
91
  /// \return
92
  ///   True if this is a 64 bit ELF file header.
93
0
  bool Is64Bit() const {
94
0
    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
95
0
  }
96
97
  /// The byte order of this ELF file header.
98
  ///
99
  /// \return
100
  ///    The byte order of this ELF file as described by the header.
101
  lldb::ByteOrder GetByteOrder() const;
102
103
  /// The jump slot relocation type of this ELF.
104
  unsigned GetRelocationJumpSlotType() const;
105
106
  /// Check if there should be header extension in section header #0
107
  ///
108
  /// \return
109
  ///    True if parsing the ELFHeader requires reading header extension
110
  ///    and false otherwise.
111
  bool HasHeaderExtension() const;
112
113
  /// Parse an ELFHeader entry starting at position \p offset and update the
114
  /// data extractor with the address size and byte order attributes as
115
  /// defined by the header.
116
  ///
117
  /// \param[in,out] data
118
  ///    The DataExtractor to read from.  Updated with the address size and
119
  ///    byte order attributes appropriate to this header.
120
  ///
121
  /// \param[in,out] offset
122
  ///    Pointer to an offset in the data.  On return the offset will be
123
  ///    advanced by the number of bytes read.
124
  ///
125
  /// \return
126
  ///    True if the ELFHeader was successfully read and false
127
  ///    otherwise.
128
  bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
129
130
  /// Examines at most EI_NIDENT bytes starting from the given pointer and
131
  /// determines if the magic ELF identification exists.
132
  ///
133
  /// \return
134
  ///    True if the given sequence of bytes identifies an ELF file.
135
  static bool MagicBytesMatch(const uint8_t *magic);
136
137
  /// Examines at most EI_NIDENT bytes starting from the given address and
138
  /// determines the address size of the underlying ELF file.  This function
139
  /// should only be called on an pointer for which MagicBytesMatch returns
140
  /// true.
141
  ///
142
  /// \return
143
  ///    The number of bytes forming an address in the ELF file (either 4 or
144
  ///    8), else zero if the address size could not be determined.
145
  static unsigned AddressSizeInBytes(const uint8_t *magic);
146
147
private:
148
149
  /// Parse an ELFHeader header extension entry.  This method is called by
150
  /// Parse().
151
  ///
152
  /// \param[in] data
153
  ///    The DataExtractor to read from.
154
  void ParseHeaderExtension(lldb_private::DataExtractor &data);
155
};
156
157
/// \class ELFSectionHeader
158
/// Generic representation of an ELF section header.
159
struct ELFSectionHeader {
160
  elf_word sh_name;       ///< Section name string index.
161
  elf_word sh_type;       ///< Section type.
162
  elf_xword sh_flags;     ///< Section attributes.
163
  elf_addr sh_addr;       ///< Virtual address of the section in memory.
164
  elf_off sh_offset;      ///< Start of section from beginning of file.
165
  elf_xword sh_size;      ///< Number of bytes occupied in the file.
166
  elf_word sh_link;       ///< Index of associated section.
167
  elf_word sh_info;       ///< Extra section info (overloaded).
168
  elf_xword sh_addralign; ///< Power of two alignment constraint.
169
  elf_xword sh_entsize;   ///< Byte size of each section entry.
170
171
  ELFSectionHeader();
172
173
  /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
174
  /// position \p offset.
175
  ///
176
  /// \param[in] data
177
  ///    The DataExtractor to read from.  The address size of the extractor
178
  ///    determines if a 32 or 64 bit object should be read.
179
  ///
180
  /// \param[in,out] offset
181
  ///    Pointer to an offset in the data.  On return the offset will be
182
  ///    advanced by the number of bytes read.
183
  ///
184
  /// \return
185
  ///    True if the ELFSectionHeader was successfully read and false
186
  ///    otherwise.
187
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
188
};
189
190
/// \class ELFProgramHeader
191
/// Generic representation of an ELF program header.
192
struct ELFProgramHeader {
193
  elf_word p_type;    ///< Type of program segment.
194
  elf_word p_flags;   ///< Segment attributes.
195
  elf_off p_offset;   ///< Start of segment from beginning of file.
196
  elf_addr p_vaddr;   ///< Virtual address of segment in memory.
197
  elf_addr p_paddr;   ///< Physical address (for non-VM systems).
198
  elf_xword p_filesz; ///< Byte size of the segment in file.
199
  elf_xword p_memsz;  ///< Byte size of the segment in memory.
200
  elf_xword p_align;  ///< Segment alignment constraint.
201
202
  ELFProgramHeader();
203
204
  /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
205
  /// position \p offset.  The address size of the DataExtractor determines if
206
  /// a 32 or 64 bit object is to be parsed.
207
  ///
208
  /// \param[in] data
209
  ///    The DataExtractor to read from.  The address size of the extractor
210
  ///    determines if a 32 or 64 bit object should be read.
211
  ///
212
  /// \param[in,out] offset
213
  ///    Pointer to an offset in the data.  On return the offset will be
214
  ///    advanced by the number of bytes read.
215
  ///
216
  /// \return
217
  ///    True if the ELFProgramHeader was successfully read and false
218
  ///    otherwise.
219
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
220
};
221
222
/// \class ELFSymbol
223
/// Represents a symbol within an ELF symbol table.
224
struct ELFSymbol {
225
  elf_addr st_value;      ///< Absolute or relocatable address.
226
  elf_xword st_size;      ///< Size of the symbol or zero.
227
  elf_word st_name;       ///< Symbol name string index.
228
  unsigned char st_info;  ///< Symbol type and binding attributes.
229
  unsigned char st_other; ///< Reserved for future use.
230
  elf_half st_shndx;      ///< Section to which this symbol applies.
231
232
  ELFSymbol();
233
234
  /// Returns the binding attribute of the st_info member.
235
13.7k
  unsigned char getBinding() const { return st_info >> 4; }
236
237
  /// Returns the type attribute of the st_info member.
238
21.1k
  unsigned char getType() const { return st_info & 0x0F; }
239
240
  /// Sets the binding and type of the st_info member.
241
0
  void setBindingAndType(unsigned char binding, unsigned char type) {
242
0
    st_info = (binding << 4) + (type & 0x0F);
243
0
  }
244
245
  static const char *bindingToCString(unsigned char binding);
246
247
  static const char *typeToCString(unsigned char type);
248
249
  static const char *
250
  sectionIndexToCString(elf_half shndx,
251
                        const lldb_private::SectionList *section_list);
252
253
  /// Parse an ELFSymbol entry from the given DataExtractor starting at
254
  /// position \p offset.  The address size of the DataExtractor determines if
255
  /// a 32 or 64 bit object is to be parsed.
256
  ///
257
  /// \param[in] data
258
  ///    The DataExtractor to read from.  The address size of the extractor
259
  ///    determines if a 32 or 64 bit object should be read.
260
  ///
261
  /// \param[in,out] offset
262
  ///    Pointer to an offset in the data.  On return the offset will be
263
  ///    advanced by the number of bytes read.
264
  ///
265
  /// \return
266
  ///    True if the ELFSymbol was successfully read and false otherwise.
267
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
268
269
  void Dump(lldb_private::Stream *s, uint32_t idx,
270
            const lldb_private::DataExtractor *strtab_data,
271
            const lldb_private::SectionList *section_list);
272
};
273
274
/// \class ELFDynamic
275
/// Represents an entry in an ELF dynamic table.
276
struct ELFDynamic {
277
  elf_sxword d_tag; ///< Type of dynamic table entry.
278
  union {
279
    elf_xword d_val; ///< Integer value of the table entry.
280
    elf_addr d_ptr;  ///< Pointer value of the table entry.
281
  };
282
283
  ELFDynamic();
284
285
  /// Parse an ELFDynamic entry from the given DataExtractor starting at
286
  /// position \p offset.  The address size of the DataExtractor determines if
287
  /// a 32 or 64 bit object is to be parsed.
288
  ///
289
  /// \param[in] data
290
  ///    The DataExtractor to read from.  The address size of the extractor
291
  ///    determines if a 32 or 64 bit object should be read.
292
  ///
293
  /// \param[in,out] offset
294
  ///    Pointer to an offset in the data.  On return the offset will be
295
  ///    advanced by the number of bytes read.
296
  ///
297
  /// \return
298
  ///    True if the ELFDynamic entry was successfully read and false
299
  ///    otherwise.
300
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
301
};
302
303
/// \class ELFRel
304
/// Represents a relocation entry with an implicit addend.
305
struct ELFRel {
306
  elf_addr r_offset; ///< Address of reference.
307
  elf_xword r_info;  ///< symbol index and type of relocation.
308
309
  ELFRel();
310
311
  /// Parse an ELFRel entry from the given DataExtractor starting at position
312
  /// \p offset.  The address size of the DataExtractor determines if a 32 or
313
  /// 64 bit object is to be parsed.
314
  ///
315
  /// \param[in] data
316
  ///    The DataExtractor to read from.  The address size of the extractor
317
  ///    determines if a 32 or 64 bit object should be read.
318
  ///
319
  /// \param[in,out] offset
320
  ///    Pointer to an offset in the data.  On return the offset will be
321
  ///    advanced by the number of bytes read.
322
  ///
323
  /// \return
324
  ///    True if the ELFRel entry was successfully read and false otherwise.
325
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
326
327
  /// Returns the type when the given entry represents a 32-bit relocation.
328
6
  static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }
329
330
  /// Returns the type when the given entry represents a 64-bit relocation.
331
0
  static unsigned RelocType64(const ELFRel &rel) {
332
0
    return rel.r_info & 0xffffffff;
333
0
  }
334
335
  /// Returns the symbol index when the given entry represents a 32-bit
336
  /// relocation.
337
6
  static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }
338
339
  /// Returns the symbol index when the given entry represents a 64-bit
340
  /// relocation.
341
0
  static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }
342
};
343
344
/// \class ELFRela
345
/// Represents a relocation entry with an explicit addend.
346
struct ELFRela {
347
  elf_addr r_offset;   ///< Address of reference.
348
  elf_xword r_info;    ///< Symbol index and type of relocation.
349
  elf_sxword r_addend; ///< Constant part of expression.
350
351
  ELFRela();
352
353
  /// Parse an ELFRela entry from the given DataExtractor starting at position
354
  /// \p offset.  The address size of the DataExtractor determines if a 32 or
355
  /// 64 bit object is to be parsed.
356
  ///
357
  /// \param[in] data
358
  ///    The DataExtractor to read from.  The address size of the extractor
359
  ///    determines if a 32 or 64 bit object should be read.
360
  ///
361
  /// \param[in,out] offset
362
  ///    Pointer to an offset in the data.  On return the offset will be
363
  ///    advanced by the number of bytes read.
364
  ///
365
  /// \return
366
  ///    True if the ELFRela entry was successfully read and false otherwise.
367
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
368
369
  /// Returns the type when the given entry represents a 32-bit relocation.
370
1
  static unsigned RelocType32(const ELFRela &rela) {
371
1
    return rela.r_info & 0x0ff;
372
1
  }
373
374
  /// Returns the type when the given entry represents a 64-bit relocation.
375
17.1k
  static unsigned RelocType64(const ELFRela &rela) {
376
17.1k
    return rela.r_info & 0xffffffff;
377
17.1k
  }
378
379
  /// Returns the symbol index when the given entry represents a 32-bit
380
  /// relocation.
381
1
  static unsigned RelocSymbol32(const ELFRela &rela) {
382
1
    return rela.r_info >> 8;
383
1
  }
384
385
  /// Returns the symbol index when the given entry represents a 64-bit
386
  /// relocation.
387
17.1k
  static unsigned RelocSymbol64(const ELFRela &rela) {
388
17.1k
    return rela.r_info >> 32;
389
17.1k
  }
390
};
391
392
} // End namespace elf.
393
394
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H