/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 |