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
28namespace lldb_private {
29class DataExtractor;
30} // End namespace lldb_private.
31
32namespace 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//@{
41typedef uint64_t elf_addr;
42typedef uint64_t elf_off;
43typedef uint16_t elf_half;
44typedef uint32_t elf_word;
45typedef int32_t elf_sword;
46typedef uint64_t elf_size;
47typedef uint64_t elf_xword;
48typedef 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.
56struct 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 bool Is32Bit() const {
86 return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
87 }
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 bool Is64Bit() const {
94 return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
95 }
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
147private:
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.
159struct 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.
192struct 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.
224struct 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 unsigned char getBinding() const { return st_info >> 4; }
236
237 /// Returns the type attribute of the st_info member.
238 unsigned char getType() const { return st_info & 0x0F; }
239
240 /// Sets the binding and type of the st_info member.
241 void setBindingAndType(unsigned char binding, unsigned char type) {
242 st_info = (binding << 4) + (type & 0x0F);
243 }
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.
276struct 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.
305struct 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 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 static unsigned RelocType64(const ELFRel &rel) {
332 return rel.r_info & 0xffffffff;
333 }
334
335 /// Returns the symbol index when the given entry represents a 32-bit
336 /// relocation.
337 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 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.
346struct 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 static unsigned RelocType32(const ELFRela &rela) {
371 return rela.r_info & 0x0ff;
372 }
373
374 /// Returns the type when the given entry represents a 64-bit relocation.
375 static unsigned RelocType64(const ELFRela &rela) {
376 return rela.r_info & 0xffffffff;
377 }
378
379 /// Returns the symbol index when the given entry represents a 32-bit
380 /// relocation.
381 static unsigned RelocSymbol32(const ELFRela &rela) {
382 return rela.r_info >> 8;
383 }
384
385 /// Returns the symbol index when the given entry represents a 64-bit
386 /// relocation.
387 static unsigned RelocSymbol64(const ELFRela &rela) {
388 return rela.r_info >> 32;
389 }
390};
391
392} // End namespace elf.
393
394#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
395

source code of lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h