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