1254721Semaste//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste//
10254721Semaste/// @file
11254721Semaste/// @brief Generic structures and typedefs for ELF files.
12254721Semaste///
13254721Semaste/// This file provides definitions for the various entities comprising an ELF
14254721Semaste/// file.  The structures are generic in the sense that they do not correspond
15254721Semaste/// to the exact binary layout of an ELF, but can be used to hold the
16254721Semaste/// information present in both 32 and 64 bit variants of the format.  Each
17254721Semaste/// entity provides a \c Parse method which is capable of transparently reading
18254721Semaste/// both 32 and 64 bit instances of the object.
19254721Semaste//===----------------------------------------------------------------------===//
20254721Semaste
21254721Semaste#ifndef liblldb_ELFHeader_h_
22254721Semaste#define liblldb_ELFHeader_h_
23254721Semaste
24254721Semaste#include "llvm/Support/ELF.h"
25254721Semaste
26254721Semaste#include "lldb/lldb-enumerations.h"
27254721Semaste
28254721Semastenamespace lldb_private
29254721Semaste{
30254721Semasteclass DataExtractor;
31254721Semaste} // End namespace lldb_private.
32254721Semaste
33254721Semastenamespace elf
34254721Semaste{
35254721Semaste
36254721Semaste//------------------------------------------------------------------------------
37254721Semaste/// @name ELF type definitions.
38254721Semaste///
39254721Semaste/// Types used to represent the various components of ELF structures.  All types
40254721Semaste/// are signed or unsigned integral types wide enough to hold values from both
41254721Semaste/// 32 and 64 bit ELF variants.
42254721Semaste//@{
43254721Semastetypedef uint64_t elf_addr;
44254721Semastetypedef uint64_t elf_off;
45254721Semastetypedef uint16_t elf_half;
46254721Semastetypedef uint32_t elf_word;
47254721Semastetypedef int32_t  elf_sword;
48254721Semastetypedef uint64_t elf_size;
49254721Semastetypedef uint64_t elf_xword;
50254721Semastetypedef int64_t  elf_sxword;
51254721Semaste//@}
52254721Semaste
53254721Semaste//------------------------------------------------------------------------------
54254721Semaste/// @class ELFHeader
55254721Semaste/// @brief Generic representation of an ELF file header.
56254721Semaste///
57254721Semaste/// This object is used to identify the general attributes on an ELF file and to
58254721Semaste/// locate additional sections within the file.
59254721Semastestruct ELFHeader
60254721Semaste{
61254721Semaste    unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
62254721Semaste    elf_addr      e_entry;            ///< Virtual address program entry point.
63254721Semaste    elf_off       e_phoff;            ///< File offset of program header table.
64254721Semaste    elf_off       e_shoff;            ///< File offset of section header table.
65254721Semaste    elf_word      e_flags;            ///< Processor specific flags.
66254721Semaste    elf_word      e_version;          ///< Version of object file (always 1).
67254721Semaste    elf_half      e_type;             ///< Object file type.
68254721Semaste    elf_half      e_machine;          ///< Target architecture.
69254721Semaste    elf_half      e_ehsize;           ///< Byte size of the ELF header.
70254721Semaste    elf_half      e_phentsize;        ///< Size of a program header table entry.
71254721Semaste    elf_half      e_phnum;            ///< Number of program header entries.
72254721Semaste    elf_half      e_shentsize;        ///< Size of a section header table entry.
73254721Semaste    elf_half      e_shnum;            ///< Number of section header entries.
74254721Semaste    elf_half      e_shstrndx;         ///< String table section index.
75254721Semaste
76254721Semaste    ELFHeader();
77254721Semaste
78254721Semaste    //--------------------------------------------------------------------------
79254721Semaste    /// Returns true if this is a 32 bit ELF file header.
80254721Semaste    ///
81254721Semaste    /// @return
82254721Semaste    ///    True if this is a 32 bit ELF file header.
83254721Semaste    bool Is32Bit() const {
84254721Semaste        return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
85254721Semaste    }
86254721Semaste
87254721Semaste    //--------------------------------------------------------------------------
88254721Semaste    /// Returns true if this is a 64 bit ELF file header.
89254721Semaste    ///
90254721Semaste    /// @return
91254721Semaste    ///   True if this is a 64 bit ELF file header.
92254721Semaste    bool Is64Bit() const {
93254721Semaste        return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
94254721Semaste    }
95254721Semaste
96254721Semaste    //--------------------------------------------------------------------------
97254721Semaste    /// The byte order of this ELF file header.
98254721Semaste    ///
99254721Semaste    /// @return
100254721Semaste    ///    The byte order of this ELF file as described by the header.
101254721Semaste    lldb::ByteOrder
102254721Semaste    GetByteOrder() const;
103254721Semaste
104254721Semaste    //--------------------------------------------------------------------------
105254721Semaste    /// The jump slot relocation type of this ELF.
106254721Semaste    unsigned
107254721Semaste    GetRelocationJumpSlotType() const;
108254721Semaste
109254721Semaste    //--------------------------------------------------------------------------
110254721Semaste    /// Parse an ELFHeader entry starting at position \p offset and
111254721Semaste    /// update the data extractor with the address size and byte order
112254721Semaste    /// attributes as defined by the header.
113254721Semaste    ///
114254721Semaste    /// @param[in,out] data
115254721Semaste    ///    The DataExtractor to read from.  Updated with the address size and
116254721Semaste    ///    byte order attributes appropriate to this header.
117254721Semaste    ///
118254721Semaste    /// @param[in,out] offset
119254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
120254721Semaste    ///    advanced by the number of bytes read.
121254721Semaste    ///
122254721Semaste    /// @return
123254721Semaste    ///    True if the ELFHeader was successfully read and false
124254721Semaste    ///    otherwise.
125254721Semaste    bool
126254721Semaste    Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
127254721Semaste
128254721Semaste    //--------------------------------------------------------------------------
129254721Semaste    /// Examines at most EI_NIDENT bytes starting from the given pointer and
130254721Semaste    /// determines if the magic ELF identification exists.
131254721Semaste    ///
132254721Semaste    /// @return
133254721Semaste    ///    True if the given sequence of bytes identifies an ELF file.
134254721Semaste    static bool
135254721Semaste    MagicBytesMatch(const uint8_t *magic);
136254721Semaste
137254721Semaste    //--------------------------------------------------------------------------
138254721Semaste    /// Examines at most EI_NIDENT bytes starting from the given address and
139254721Semaste    /// determines the address size of the underlying ELF file.  This function
140254721Semaste    /// should only be called on an pointer for which MagicBytesMatch returns
141254721Semaste    /// true.
142254721Semaste    ///
143254721Semaste    /// @return
144254721Semaste    ///    The number of bytes forming an address in the ELF file (either 4 or
145254721Semaste    ///    8), else zero if the address size could not be determined.
146254721Semaste    static unsigned
147254721Semaste    AddressSizeInBytes(const uint8_t *magic);
148254721Semaste};
149254721Semaste
150254721Semaste//------------------------------------------------------------------------------
151254721Semaste/// @class ELFSectionHeader
152254721Semaste/// @brief Generic representation of an ELF section header.
153254721Semastestruct ELFSectionHeader
154254721Semaste{
155254721Semaste    elf_word  sh_name;          ///< Section name string index.
156254721Semaste    elf_word  sh_type;          ///< Section type.
157254721Semaste    elf_xword sh_flags;         ///< Section attributes.
158254721Semaste    elf_addr  sh_addr;          ///< Virtual address of the section in memory.
159254721Semaste    elf_off   sh_offset;        ///< Start of section from beginning of file.
160254721Semaste    elf_xword sh_size;          ///< Number of bytes occupied in the file.
161254721Semaste    elf_word  sh_link;          ///< Index of associated section.
162254721Semaste    elf_word  sh_info;          ///< Extra section info (overloaded).
163254721Semaste    elf_xword sh_addralign;     ///< Power of two alignment constraint.
164254721Semaste    elf_xword sh_entsize;       ///< Byte size of each section entry.
165254721Semaste
166254721Semaste    ELFSectionHeader();
167254721Semaste
168254721Semaste    //--------------------------------------------------------------------------
169254721Semaste    /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
170254721Semaste    /// position \p offset.
171254721Semaste    ///
172254721Semaste    /// @param[in] data
173254721Semaste    ///    The DataExtractor to read from.  The address size of the extractor
174254721Semaste    ///    determines if a 32 or 64 bit object should be read.
175254721Semaste    ///
176254721Semaste    /// @param[in,out] offset
177254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
178254721Semaste    ///    advanced by the number of bytes read.
179254721Semaste    ///
180254721Semaste    /// @return
181254721Semaste    ///    True if the ELFSectionHeader was successfully read and false
182254721Semaste    ///    otherwise.
183254721Semaste    bool
184254721Semaste    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
185254721Semaste};
186254721Semaste
187254721Semaste//------------------------------------------------------------------------------
188254721Semaste/// @class ELFProgramHeader
189254721Semaste/// @brief Generic representation of an ELF program header.
190254721Semastestruct ELFProgramHeader
191254721Semaste{
192254721Semaste    elf_word  p_type;           ///< Type of program segment.
193254721Semaste    elf_word  p_flags;          ///< Segment attributes.
194254721Semaste    elf_off   p_offset;         ///< Start of segment from beginning of file.
195254721Semaste    elf_addr  p_vaddr;          ///< Virtual address of segment in memory.
196254721Semaste    elf_addr  p_paddr;          ///< Physical address (for non-VM systems).
197254721Semaste    elf_xword p_filesz;         ///< Byte size of the segment in file.
198254721Semaste    elf_xword p_memsz;          ///< Byte size of the segment in memory.
199254721Semaste    elf_xword p_align;          ///< Segment alignment constraint.
200254721Semaste
201254721Semaste    ELFProgramHeader();
202254721Semaste
203254721Semaste    /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
204254721Semaste    /// position \p offset.  The address size of the DataExtractor determines if
205254721Semaste    /// a 32 or 64 bit object is to be parsed.
206254721Semaste    ///
207254721Semaste    /// @param[in] data
208254721Semaste    ///    The DataExtractor to read from.  The address size of the extractor
209254721Semaste    ///    determines if a 32 or 64 bit object should be read.
210254721Semaste    ///
211254721Semaste    /// @param[in,out] offset
212254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
213254721Semaste    ///    advanced by the number of bytes read.
214254721Semaste    ///
215254721Semaste    /// @return
216254721Semaste    ///    True if the ELFProgramHeader was successfully read and false
217254721Semaste    ///    otherwise.
218254721Semaste    bool
219254721Semaste    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
220254721Semaste};
221254721Semaste
222254721Semaste//------------------------------------------------------------------------------
223254721Semaste/// @class ELFSymbol
224254721Semaste/// @brief Represents a symbol within an ELF symbol table.
225254721Semastestruct ELFSymbol
226254721Semaste{
227254721Semaste    elf_addr      st_value;     ///< Absolute or relocatable address.
228254721Semaste    elf_xword     st_size;      ///< Size of the symbol or zero.
229254721Semaste    elf_word      st_name;      ///< Symbol name string index.
230254721Semaste    unsigned char st_info;      ///< Symbol type and binding attributes.
231254721Semaste    unsigned char st_other;     ///< Reserved for future use.
232254721Semaste    elf_half      st_shndx;     ///< Section to which this symbol applies.
233254721Semaste
234254721Semaste    ELFSymbol();
235254721Semaste
236254721Semaste    /// Returns the binding attribute of the st_info member.
237254721Semaste    unsigned char getBinding() const { return st_info >> 4; }
238254721Semaste
239254721Semaste    /// Returns the type attribute of the st_info member.
240254721Semaste    unsigned char getType() const { return st_info & 0x0F; }
241254721Semaste
242254721Semaste    /// Sets the binding and type of the st_info member.
243254721Semaste    void setBindingAndType(unsigned char binding, unsigned char type) {
244254721Semaste        st_info = (binding << 4) + (type & 0x0F);
245254721Semaste    }
246254721Semaste
247254721Semaste    static const char *
248254721Semaste    bindingToCString(unsigned char binding);
249254721Semaste
250254721Semaste    static const char *
251254721Semaste    typeToCString(unsigned char type);
252254721Semaste
253254721Semaste    static const char *
254254721Semaste    sectionIndexToCString(elf_half shndx,
255254721Semaste                          const lldb_private::SectionList *section_list);
256254721Semaste
257254721Semaste    /// Parse an ELFSymbol entry from the given DataExtractor starting at
258254721Semaste    /// position \p offset.  The address size of the DataExtractor determines if
259254721Semaste    /// a 32 or 64 bit object is to be parsed.
260254721Semaste    ///
261254721Semaste    /// @param[in] data
262254721Semaste    ///    The DataExtractor to read from.  The address size of the extractor
263254721Semaste    ///    determines if a 32 or 64 bit object should be read.
264254721Semaste    ///
265254721Semaste    /// @param[in,out] offset
266254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
267254721Semaste    ///    advanced by the number of bytes read.
268254721Semaste    ///
269254721Semaste    /// @return
270254721Semaste    ///    True if the ELFSymbol was successfully read and false otherwise.
271254721Semaste    bool
272254721Semaste    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
273254721Semaste
274254721Semaste    void
275254721Semaste    Dump (lldb_private::Stream *s,
276254721Semaste          uint32_t idx,
277254721Semaste          const lldb_private::DataExtractor *strtab_data,
278254721Semaste          const lldb_private::SectionList *section_list);
279254721Semaste};
280254721Semaste
281254721Semaste//------------------------------------------------------------------------------
282254721Semaste/// @class ELFDynamic
283254721Semaste/// @brief Represents an entry in an ELF dynamic table.
284254721Semastestruct ELFDynamic
285254721Semaste{
286254721Semaste    elf_sxword d_tag;           ///< Type of dynamic table entry.
287254721Semaste    union
288254721Semaste    {
289254721Semaste        elf_xword d_val;        ///< Integer value of the table entry.
290254721Semaste        elf_addr  d_ptr;        ///< Pointer value of the table entry.
291254721Semaste    };
292254721Semaste
293254721Semaste    ELFDynamic();
294254721Semaste
295254721Semaste    /// Parse an ELFDynamic entry from the given DataExtractor starting at
296254721Semaste    /// position \p offset.  The address size of the DataExtractor determines if
297254721Semaste    /// a 32 or 64 bit object is to be parsed.
298254721Semaste    ///
299254721Semaste    /// @param[in] data
300254721Semaste    ///    The DataExtractor to read from.  The address size of the extractor
301254721Semaste    ///    determines if a 32 or 64 bit object should be read.
302254721Semaste    ///
303254721Semaste    /// @param[in,out] offset
304254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
305254721Semaste    ///    advanced by the number of bytes read.
306254721Semaste    ///
307254721Semaste    /// @return
308254721Semaste    ///    True if the ELFDynamic entry was successfully read and false
309254721Semaste    ///    otherwise.
310254721Semaste    bool
311254721Semaste    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
312254721Semaste};
313254721Semaste
314254721Semaste//------------------------------------------------------------------------------
315254721Semaste/// @class ELFRel
316254721Semaste/// @brief Represents a relocation entry with an implicit addend.
317254721Semastestruct ELFRel
318254721Semaste{
319254721Semaste    elf_addr  r_offset;         ///< Address of reference.
320254721Semaste    elf_xword r_info;           ///< symbol index and type of relocation.
321254721Semaste
322254721Semaste    ELFRel();
323254721Semaste
324254721Semaste    /// Parse an ELFRel entry from the given DataExtractor starting at position
325254721Semaste    /// \p offset.  The address size of the DataExtractor determines if a 32 or
326254721Semaste    /// 64 bit object is to be parsed.
327254721Semaste    ///
328254721Semaste    /// @param[in] data
329254721Semaste    ///    The DataExtractor to read from.  The address size of the extractor
330254721Semaste    ///    determines if a 32 or 64 bit object should be read.
331254721Semaste    ///
332254721Semaste    /// @param[in,out] offset
333254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
334254721Semaste    ///    advanced by the number of bytes read.
335254721Semaste    ///
336254721Semaste    /// @return
337254721Semaste    ///    True if the ELFRel entry was successfully read and false otherwise.
338254721Semaste    bool
339254721Semaste    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
340254721Semaste
341254721Semaste    /// Returns the type when the given entry represents a 32-bit relocation.
342254721Semaste    static unsigned
343254721Semaste    RelocType32(const ELFRel &rel)
344254721Semaste    {
345254721Semaste        return rel.r_info & 0x0ff;
346254721Semaste    }
347254721Semaste
348254721Semaste    /// Returns the type when the given entry represents a 64-bit relocation.
349254721Semaste    static unsigned
350254721Semaste    RelocType64(const ELFRel &rel)
351254721Semaste    {
352254721Semaste        return rel.r_info & 0xffffffff;
353254721Semaste    }
354254721Semaste
355254721Semaste    /// Returns the symbol index when the given entry represents a 32-bit
356254721Semaste    /// reloction.
357254721Semaste    static unsigned
358254721Semaste    RelocSymbol32(const ELFRel &rel)
359254721Semaste    {
360254721Semaste        return rel.r_info >> 8;
361254721Semaste    }
362254721Semaste
363254721Semaste    /// Returns the symbol index when the given entry represents a 64-bit
364254721Semaste    /// reloction.
365254721Semaste    static unsigned
366254721Semaste    RelocSymbol64(const ELFRel &rel)
367254721Semaste    {
368254721Semaste        return rel.r_info >> 32;
369254721Semaste    }
370254721Semaste};
371254721Semaste
372254721Semaste//------------------------------------------------------------------------------
373254721Semaste/// @class ELFRela
374254721Semaste/// @brief Represents a relocation entry with an explicit addend.
375254721Semastestruct ELFRela
376254721Semaste{
377254721Semaste    elf_addr   r_offset;        ///< Address of reference.
378254721Semaste    elf_xword  r_info;          ///< Symbol index and type of relocation.
379254721Semaste    elf_sxword r_addend;        ///< Constant part of expression.
380254721Semaste
381254721Semaste    ELFRela();
382254721Semaste
383254721Semaste    /// Parse an ELFRela entry from the given DataExtractor starting at position
384254721Semaste    /// \p offset.  The address size of the DataExtractor determines if a 32 or
385254721Semaste    /// 64 bit object is to be parsed.
386254721Semaste    ///
387254721Semaste    /// @param[in] data
388254721Semaste    ///    The DataExtractor to read from.  The address size of the extractor
389254721Semaste    ///    determines if a 32 or 64 bit object should be read.
390254721Semaste    ///
391254721Semaste    /// @param[in,out] offset
392254721Semaste    ///    Pointer to an offset in the data.  On return the offset will be
393254721Semaste    ///    advanced by the number of bytes read.
394254721Semaste    ///
395254721Semaste    /// @return
396254721Semaste    ///    True if the ELFRela entry was successfully read and false otherwise.
397254721Semaste    bool
398254721Semaste    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
399254721Semaste
400254721Semaste    /// Returns the type when the given entry represents a 32-bit relocation.
401254721Semaste    static unsigned
402254721Semaste    RelocType32(const ELFRela &rela)
403254721Semaste    {
404254721Semaste        return rela.r_info & 0x0ff;
405254721Semaste    }
406254721Semaste
407254721Semaste    /// Returns the type when the given entry represents a 64-bit relocation.
408254721Semaste    static unsigned
409254721Semaste    RelocType64(const ELFRela &rela)
410254721Semaste    {
411254721Semaste        return rela.r_info & 0xffffffff;
412254721Semaste    }
413254721Semaste
414254721Semaste    /// Returns the symbol index when the given entry represents a 32-bit
415254721Semaste    /// reloction.
416254721Semaste    static unsigned
417254721Semaste    RelocSymbol32(const ELFRela &rela)
418254721Semaste    {
419254721Semaste        return rela.r_info >> 8;
420254721Semaste    }
421254721Semaste
422254721Semaste    /// Returns the symbol index when the given entry represents a 64-bit
423254721Semaste    /// reloction.
424254721Semaste    static unsigned
425254721Semaste    RelocSymbol64(const ELFRela &rela)
426254721Semaste    {
427254721Semaste        return rela.r_info >> 32;
428254721Semaste    }
429254721Semaste};
430254721Semaste
431254721Semaste} // End namespace elf.
432254721Semaste
433254721Semaste#endif // #ifndef liblldb_ELFHeader_h_
434