xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
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.
Is32BitELFHeader85   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.
Is64BitELFHeader93   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 
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.
getBindingELFSymbol235   unsigned char getBinding() const { return st_info >> 4; }
236 
237   /// Returns the type attribute of the st_info member.
getTypeELFSymbol238   unsigned char getType() const { return st_info & 0x0F; }
239 
240   /// Sets the binding and type of the st_info member.
setBindingAndTypeELFSymbol241   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.
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.
RelocType32ELFRel328   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.
RelocType64ELFRel331   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.
RelocSymbol32ELFRel337   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.
RelocSymbol64ELFRel341   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.
RelocType32ELFRela370   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.
RelocType64ELFRela375   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.
RelocSymbol32ELFRela381   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.
RelocSymbol64ELFRela387   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