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
28namespace lldb_private
29{
30class DataExtractor;
31} // End namespace lldb_private.
32
33namespace 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//@{
43typedef uint64_t elf_addr;
44typedef uint64_t elf_off;
45typedef uint16_t elf_half;
46typedef uint32_t elf_word;
47typedef int32_t  elf_sword;
48typedef uint64_t elf_size;
49typedef uint64_t elf_xword;
50typedef 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.
59struct 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 ELFHeader 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 ELFHeader was successfully read and false
124    ///    otherwise.
125    bool
126    Parse(lldb_private::DataExtractor &data, lldb::offset_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.
153struct 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, lldb::offset_t *offset);
185};
186
187//------------------------------------------------------------------------------
188/// @class ELFProgramHeader
189/// @brief Generic representation of an ELF program header.
190struct 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, lldb::offset_t *offset);
220};
221
222//------------------------------------------------------------------------------
223/// @class ELFSymbol
224/// @brief Represents a symbol within an ELF symbol table.
225struct 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    static const char *
248    bindingToCString(unsigned char binding);
249
250    static const char *
251    typeToCString(unsigned char type);
252
253    static const char *
254    sectionIndexToCString(elf_half shndx,
255                          const lldb_private::SectionList *section_list);
256
257    /// Parse an ELFSymbol entry from the given DataExtractor starting at
258    /// position \p offset.  The address size of the DataExtractor determines if
259    /// a 32 or 64 bit object is to be parsed.
260    ///
261    /// @param[in] data
262    ///    The DataExtractor to read from.  The address size of the extractor
263    ///    determines if a 32 or 64 bit object should be read.
264    ///
265    /// @param[in,out] offset
266    ///    Pointer to an offset in the data.  On return the offset will be
267    ///    advanced by the number of bytes read.
268    ///
269    /// @return
270    ///    True if the ELFSymbol was successfully read and false otherwise.
271    bool
272    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
273
274    void
275    Dump (lldb_private::Stream *s,
276          uint32_t idx,
277          const lldb_private::DataExtractor *strtab_data,
278          const lldb_private::SectionList *section_list);
279};
280
281//------------------------------------------------------------------------------
282/// @class ELFDynamic
283/// @brief Represents an entry in an ELF dynamic table.
284struct ELFDynamic
285{
286    elf_sxword d_tag;           ///< Type of dynamic table entry.
287    union
288    {
289        elf_xword d_val;        ///< Integer value of the table entry.
290        elf_addr  d_ptr;        ///< Pointer value of the table entry.
291    };
292
293    ELFDynamic();
294
295    /// Parse an ELFDynamic entry from the given DataExtractor starting at
296    /// position \p offset.  The address size of the DataExtractor determines if
297    /// a 32 or 64 bit object is to be parsed.
298    ///
299    /// @param[in] data
300    ///    The DataExtractor to read from.  The address size of the extractor
301    ///    determines if a 32 or 64 bit object should be read.
302    ///
303    /// @param[in,out] offset
304    ///    Pointer to an offset in the data.  On return the offset will be
305    ///    advanced by the number of bytes read.
306    ///
307    /// @return
308    ///    True if the ELFDynamic entry was successfully read and false
309    ///    otherwise.
310    bool
311    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
312};
313
314//------------------------------------------------------------------------------
315/// @class ELFRel
316/// @brief Represents a relocation entry with an implicit addend.
317struct ELFRel
318{
319    elf_addr  r_offset;         ///< Address of reference.
320    elf_xword r_info;           ///< symbol index and type of relocation.
321
322    ELFRel();
323
324    /// Parse an ELFRel entry from the given DataExtractor starting at position
325    /// \p offset.  The address size of the DataExtractor determines if a 32 or
326    /// 64 bit object is to be parsed.
327    ///
328    /// @param[in] data
329    ///    The DataExtractor to read from.  The address size of the extractor
330    ///    determines if a 32 or 64 bit object should be read.
331    ///
332    /// @param[in,out] offset
333    ///    Pointer to an offset in the data.  On return the offset will be
334    ///    advanced by the number of bytes read.
335    ///
336    /// @return
337    ///    True if the ELFRel entry was successfully read and false otherwise.
338    bool
339    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
340
341    /// Returns the type when the given entry represents a 32-bit relocation.
342    static unsigned
343    RelocType32(const ELFRel &rel)
344    {
345        return rel.r_info & 0x0ff;
346    }
347
348    /// Returns the type when the given entry represents a 64-bit relocation.
349    static unsigned
350    RelocType64(const ELFRel &rel)
351    {
352        return rel.r_info & 0xffffffff;
353    }
354
355    /// Returns the symbol index when the given entry represents a 32-bit
356    /// reloction.
357    static unsigned
358    RelocSymbol32(const ELFRel &rel)
359    {
360        return rel.r_info >> 8;
361    }
362
363    /// Returns the symbol index when the given entry represents a 64-bit
364    /// reloction.
365    static unsigned
366    RelocSymbol64(const ELFRel &rel)
367    {
368        return rel.r_info >> 32;
369    }
370};
371
372//------------------------------------------------------------------------------
373/// @class ELFRela
374/// @brief Represents a relocation entry with an explicit addend.
375struct ELFRela
376{
377    elf_addr   r_offset;        ///< Address of reference.
378    elf_xword  r_info;          ///< Symbol index and type of relocation.
379    elf_sxword r_addend;        ///< Constant part of expression.
380
381    ELFRela();
382
383    /// Parse an ELFRela entry from the given DataExtractor starting at position
384    /// \p offset.  The address size of the DataExtractor determines if a 32 or
385    /// 64 bit object is to be parsed.
386    ///
387    /// @param[in] data
388    ///    The DataExtractor to read from.  The address size of the extractor
389    ///    determines if a 32 or 64 bit object should be read.
390    ///
391    /// @param[in,out] offset
392    ///    Pointer to an offset in the data.  On return the offset will be
393    ///    advanced by the number of bytes read.
394    ///
395    /// @return
396    ///    True if the ELFRela entry was successfully read and false otherwise.
397    bool
398    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
399
400    /// Returns the type when the given entry represents a 32-bit relocation.
401    static unsigned
402    RelocType32(const ELFRela &rela)
403    {
404        return rela.r_info & 0x0ff;
405    }
406
407    /// Returns the type when the given entry represents a 64-bit relocation.
408    static unsigned
409    RelocType64(const ELFRela &rela)
410    {
411        return rela.r_info & 0xffffffff;
412    }
413
414    /// Returns the symbol index when the given entry represents a 32-bit
415    /// reloction.
416    static unsigned
417    RelocSymbol32(const ELFRela &rela)
418    {
419        return rela.r_info >> 8;
420    }
421
422    /// Returns the symbol index when the given entry represents a 64-bit
423    /// reloction.
424    static unsigned
425    RelocSymbol64(const ELFRela &rela)
426    {
427        return rela.r_info >> 32;
428    }
429};
430
431} // End namespace elf.
432
433#endif // #ifndef liblldb_ELFHeader_h_
434