1*f325ba9dSStephen Wilson //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//
2*f325ba9dSStephen Wilson //
3*f325ba9dSStephen Wilson //                     The LLVM Compiler Infrastructure
4*f325ba9dSStephen Wilson //
5*f325ba9dSStephen Wilson // This file is distributed under the University of Illinois Open Source
6*f325ba9dSStephen Wilson // License. See LICENSE.TXT for details.
7*f325ba9dSStephen Wilson //
8*f325ba9dSStephen Wilson //===----------------------------------------------------------------------===//
9*f325ba9dSStephen Wilson //
10*f325ba9dSStephen Wilson /// @file
11*f325ba9dSStephen Wilson /// @brief Generic structures and typedefs for ELF files.
12*f325ba9dSStephen Wilson ///
13*f325ba9dSStephen Wilson /// This file provides definitions for the various entities comprising an ELF
14*f325ba9dSStephen Wilson /// file.  The structures are generic in the sense that they do not correspond
15*f325ba9dSStephen Wilson /// to the exact binary layout of an ELF, but can be used to hold the
16*f325ba9dSStephen Wilson /// information present in both 32 and 64 bit variants of the format.  Each
17*f325ba9dSStephen Wilson /// entity provides a \c Parse method which is capable of transparently reading
18*f325ba9dSStephen Wilson /// both 32 and 64 bit instances of the object.
19*f325ba9dSStephen Wilson //===----------------------------------------------------------------------===//
20*f325ba9dSStephen Wilson 
21*f325ba9dSStephen Wilson #ifndef liblldb_ELFHeader_h_
22*f325ba9dSStephen Wilson #define liblldb_ELFHeader_h_
23*f325ba9dSStephen Wilson 
24*f325ba9dSStephen Wilson #include "llvm/Support/ELF.h"
25*f325ba9dSStephen Wilson 
26*f325ba9dSStephen Wilson #include "lldb/lldb-enumerations.h"
27*f325ba9dSStephen Wilson 
28*f325ba9dSStephen Wilson namespace lldb_private
29*f325ba9dSStephen Wilson {
30*f325ba9dSStephen Wilson class DataExtractor;
31*f325ba9dSStephen Wilson } // End namespace lldb_private.
32*f325ba9dSStephen Wilson 
33*f325ba9dSStephen Wilson namespace elf
34*f325ba9dSStephen Wilson {
35*f325ba9dSStephen Wilson 
36*f325ba9dSStephen Wilson //------------------------------------------------------------------------------
37*f325ba9dSStephen Wilson /// @name ELF type definitions.
38*f325ba9dSStephen Wilson ///
39*f325ba9dSStephen Wilson /// Types used to represent the various components of ELF structures.  All types
40*f325ba9dSStephen Wilson /// are signed or unsigned integral types wide enough to hold values from both
41*f325ba9dSStephen Wilson /// 32 and 64 bit ELF variants.
42*f325ba9dSStephen Wilson //@{
43*f325ba9dSStephen Wilson typedef uint64_t elf_addr;
44*f325ba9dSStephen Wilson typedef uint64_t elf_off;
45*f325ba9dSStephen Wilson typedef uint16_t elf_half;
46*f325ba9dSStephen Wilson typedef uint32_t elf_word;
47*f325ba9dSStephen Wilson typedef int32_t  elf_sword;
48*f325ba9dSStephen Wilson typedef uint64_t elf_size;
49*f325ba9dSStephen Wilson typedef uint64_t elf_xword;
50*f325ba9dSStephen Wilson typedef int64_t  elf_sxword;
51*f325ba9dSStephen Wilson //@}
52*f325ba9dSStephen Wilson 
53*f325ba9dSStephen Wilson //------------------------------------------------------------------------------
54*f325ba9dSStephen Wilson /// @class ELFHeader
55*f325ba9dSStephen Wilson /// @brief Generic representation of an ELF file header.
56*f325ba9dSStephen Wilson ///
57*f325ba9dSStephen Wilson /// This object is used to identify the general attributes on an ELF file and to
58*f325ba9dSStephen Wilson /// locate additional sections within the file.
59*f325ba9dSStephen Wilson struct ELFHeader
60*f325ba9dSStephen Wilson {
61*f325ba9dSStephen Wilson     unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
62*f325ba9dSStephen Wilson     elf_addr      e_entry;            ///< Virtual address program entry point.
63*f325ba9dSStephen Wilson     elf_off       e_phoff;            ///< File offset of program header table.
64*f325ba9dSStephen Wilson     elf_off       e_shoff;            ///< File offset of section header table.
65*f325ba9dSStephen Wilson     elf_word      e_flags;            ///< Processor specific flags.
66*f325ba9dSStephen Wilson     elf_word      e_version;          ///< Version of object file (always 1).
67*f325ba9dSStephen Wilson     elf_half      e_type;             ///< Object file type.
68*f325ba9dSStephen Wilson     elf_half      e_machine;          ///< Target architecture.
69*f325ba9dSStephen Wilson     elf_half      e_ehsize;           ///< Byte size of the ELF header.
70*f325ba9dSStephen Wilson     elf_half      e_phentsize;        ///< Size of a program header table entry.
71*f325ba9dSStephen Wilson     elf_half      e_phnum;            ///< Number of program header entrys.
72*f325ba9dSStephen Wilson     elf_half      e_shentsize;        ///< Size of a section header table entry.
73*f325ba9dSStephen Wilson     elf_half      e_shnum;            ///< Number of section header entrys.
74*f325ba9dSStephen Wilson     elf_half      e_shstrndx;         ///< String table section index.
75*f325ba9dSStephen Wilson 
76*f325ba9dSStephen Wilson     ELFHeader();
77*f325ba9dSStephen Wilson 
78*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
79*f325ba9dSStephen Wilson     /// Returns true if this is a 32 bit ELF file header.
80*f325ba9dSStephen Wilson     ///
81*f325ba9dSStephen Wilson     /// @return
82*f325ba9dSStephen Wilson     ///    True if this is a 32 bit ELF file header.
83*f325ba9dSStephen Wilson     bool Is32Bit() const {
84*f325ba9dSStephen Wilson         return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
85*f325ba9dSStephen Wilson     }
86*f325ba9dSStephen Wilson 
87*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
88*f325ba9dSStephen Wilson     /// Returns true if this is a 64 bit ELF file header.
89*f325ba9dSStephen Wilson     ///
90*f325ba9dSStephen Wilson     /// @return
91*f325ba9dSStephen Wilson     ///   True if this is a 64 bit ELF file header.
92*f325ba9dSStephen Wilson     bool Is64Bit() const {
93*f325ba9dSStephen Wilson         return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
94*f325ba9dSStephen Wilson     }
95*f325ba9dSStephen Wilson 
96*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
97*f325ba9dSStephen Wilson     /// The byte order of this ELF file header.
98*f325ba9dSStephen Wilson     ///
99*f325ba9dSStephen Wilson     /// @return
100*f325ba9dSStephen Wilson     ///    The byte order of this ELF file as described by the header.
101*f325ba9dSStephen Wilson     lldb::ByteOrder
102*f325ba9dSStephen Wilson     GetByteOrder() const;
103*f325ba9dSStephen Wilson 
104*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
105*f325ba9dSStephen Wilson     /// Parse an ELFSectionHeader entry starting at position \p offset and
106*f325ba9dSStephen Wilson     /// update the data extractor with the address size and byte order
107*f325ba9dSStephen Wilson     /// attributes as defined by the header.
108*f325ba9dSStephen Wilson     ///
109*f325ba9dSStephen Wilson     /// @param[in,out] data
110*f325ba9dSStephen Wilson     ///    The DataExtractor to read from.  Updated with the address size and
111*f325ba9dSStephen Wilson     ///    byte order attributes appropriate to this header.
112*f325ba9dSStephen Wilson     ///
113*f325ba9dSStephen Wilson     /// @param[in,out] offset
114*f325ba9dSStephen Wilson     ///    Pointer to an offset in the data.  On return the offset will be
115*f325ba9dSStephen Wilson     ///    advanced by the number of bytes read.
116*f325ba9dSStephen Wilson     ///
117*f325ba9dSStephen Wilson     /// @return
118*f325ba9dSStephen Wilson     ///    True if the ELFSectionHeader was successfully read and false
119*f325ba9dSStephen Wilson     ///    otherwise.
120*f325ba9dSStephen Wilson     bool
121*f325ba9dSStephen Wilson     Parse(lldb_private::DataExtractor &data, uint32_t *offset);
122*f325ba9dSStephen Wilson 
123*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
124*f325ba9dSStephen Wilson     /// Examines at most EI_NIDENT bytes starting from the given pointer and
125*f325ba9dSStephen Wilson     /// determines if the magic ELF identification exists.
126*f325ba9dSStephen Wilson     ///
127*f325ba9dSStephen Wilson     /// @return
128*f325ba9dSStephen Wilson     ///    True if the given sequence of bytes identifies an ELF file.
129*f325ba9dSStephen Wilson     static bool
130*f325ba9dSStephen Wilson     MagicBytesMatch(const uint8_t *magic);
131*f325ba9dSStephen Wilson 
132*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
133*f325ba9dSStephen Wilson     /// Examines at most EI_NIDENT bytes starting from the given address and
134*f325ba9dSStephen Wilson     /// determines the address size of the underlying ELF file.  This function
135*f325ba9dSStephen Wilson     /// should only be called on an pointer for which MagicBytesMatch returns
136*f325ba9dSStephen Wilson     /// true.
137*f325ba9dSStephen Wilson     ///
138*f325ba9dSStephen Wilson     /// @return
139*f325ba9dSStephen Wilson     ///    The number of bytes forming an address in the ELF file (either 4 or
140*f325ba9dSStephen Wilson     ///    8), else zero if the address size could not be determined.
141*f325ba9dSStephen Wilson     static unsigned
142*f325ba9dSStephen Wilson     AddressSizeInBytes(const uint8_t *magic);
143*f325ba9dSStephen Wilson };
144*f325ba9dSStephen Wilson 
145*f325ba9dSStephen Wilson //------------------------------------------------------------------------------
146*f325ba9dSStephen Wilson /// @class ELFSectionHeader
147*f325ba9dSStephen Wilson /// @brief Generic representation of an ELF section header.
148*f325ba9dSStephen Wilson struct ELFSectionHeader
149*f325ba9dSStephen Wilson {
150*f325ba9dSStephen Wilson     elf_word  sh_name;          ///< Section name string index.
151*f325ba9dSStephen Wilson     elf_word  sh_type;          ///< Section type.
152*f325ba9dSStephen Wilson     elf_xword sh_flags;         ///< Section attributes.
153*f325ba9dSStephen Wilson     elf_addr  sh_addr;          ///< Virtual address of the section in memory.
154*f325ba9dSStephen Wilson     elf_off   sh_offset;        ///< Start of section from beginning of file.
155*f325ba9dSStephen Wilson     elf_xword sh_size;          ///< Number of bytes occupied in the file.
156*f325ba9dSStephen Wilson     elf_word  sh_link;          ///< Index of associated section.
157*f325ba9dSStephen Wilson     elf_word  sh_info;          ///< Extra section info (overloaded).
158*f325ba9dSStephen Wilson     elf_xword sh_addralign;     ///< Power of two alignment constraint.
159*f325ba9dSStephen Wilson     elf_xword sh_entsize;       ///< Byte size of each section entry.
160*f325ba9dSStephen Wilson 
161*f325ba9dSStephen Wilson     ELFSectionHeader();
162*f325ba9dSStephen Wilson 
163*f325ba9dSStephen Wilson     //--------------------------------------------------------------------------
164*f325ba9dSStephen Wilson     /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
165*f325ba9dSStephen Wilson     /// position \p offset.
166*f325ba9dSStephen Wilson     ///
167*f325ba9dSStephen Wilson     /// @param[in] data
168*f325ba9dSStephen Wilson     ///    The DataExtractor to read from.  The address size of the extractor
169*f325ba9dSStephen Wilson     ///    determines if a 32 or 64 bit object should be read.
170*f325ba9dSStephen Wilson     ///
171*f325ba9dSStephen Wilson     /// @param[in,out] offset
172*f325ba9dSStephen Wilson     ///    Pointer to an offset in the data.  On return the offset will be
173*f325ba9dSStephen Wilson     ///    advanced by the number of bytes read.
174*f325ba9dSStephen Wilson     ///
175*f325ba9dSStephen Wilson     /// @return
176*f325ba9dSStephen Wilson     ///    True if the ELFSectionHeader was successfully read and false
177*f325ba9dSStephen Wilson     ///    otherwise.
178*f325ba9dSStephen Wilson     bool
179*f325ba9dSStephen Wilson     Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
180*f325ba9dSStephen Wilson };
181*f325ba9dSStephen Wilson 
182*f325ba9dSStephen Wilson //------------------------------------------------------------------------------
183*f325ba9dSStephen Wilson /// @class ELFProgramHeader
184*f325ba9dSStephen Wilson /// @brief Generic representation of an ELF program header.
185*f325ba9dSStephen Wilson struct ELFProgramHeader
186*f325ba9dSStephen Wilson {
187*f325ba9dSStephen Wilson     elf_word  p_type;           ///< Type of program segement.
188*f325ba9dSStephen Wilson     elf_word  p_flags;          ///< Segement attibutes.
189*f325ba9dSStephen Wilson     elf_off   p_offset;         ///< Start of segment from begining of file.
190*f325ba9dSStephen Wilson     elf_addr  p_vaddr;          ///< Virtual address of segment in memory.
191*f325ba9dSStephen Wilson     elf_addr  p_paddr;          ///< Physical address (for non-VM systems).
192*f325ba9dSStephen Wilson     elf_xword p_filesz;         ///< Byte size of the segment in file.
193*f325ba9dSStephen Wilson     elf_xword p_memsz;          ///< Byte size of the segment in memory.
194*f325ba9dSStephen Wilson     elf_xword p_align;          ///< Segement alignement constraint.
195*f325ba9dSStephen Wilson 
196*f325ba9dSStephen Wilson     ELFProgramHeader();
197*f325ba9dSStephen Wilson 
198*f325ba9dSStephen Wilson     /// Parse an ELFProgramHeader entry from the given DataExtracter starting at
199*f325ba9dSStephen Wilson     /// position \p offset.  The address size of the DataExtracter determines if
200*f325ba9dSStephen Wilson     /// a 32 or 64 bit object is to be parsed.
201*f325ba9dSStephen Wilson     ///
202*f325ba9dSStephen Wilson     /// @param[in] data
203*f325ba9dSStephen Wilson     ///    The DataExtractor to read from.  The address size of the extractor
204*f325ba9dSStephen Wilson     ///    determines if a 32 or 64 bit object should be read.
205*f325ba9dSStephen Wilson     ///
206*f325ba9dSStephen Wilson     /// @param[in,out] offset
207*f325ba9dSStephen Wilson     ///    Pointer to an offset in the data.  On return the offset will be
208*f325ba9dSStephen Wilson     ///    advanced by the number of bytes read.
209*f325ba9dSStephen Wilson     ///
210*f325ba9dSStephen Wilson     /// @return
211*f325ba9dSStephen Wilson     ///    True if the ELFProgramHeader was successfully read and false
212*f325ba9dSStephen Wilson     ///    otherwise.
213*f325ba9dSStephen Wilson     bool
214*f325ba9dSStephen Wilson     Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
215*f325ba9dSStephen Wilson };
216*f325ba9dSStephen Wilson 
217*f325ba9dSStephen Wilson //------------------------------------------------------------------------------
218*f325ba9dSStephen Wilson /// @class ELFSymbol
219*f325ba9dSStephen Wilson /// @brief Represents a symbol within an ELF symbol table.
220*f325ba9dSStephen Wilson struct ELFSymbol
221*f325ba9dSStephen Wilson {
222*f325ba9dSStephen Wilson     elf_addr      st_value;     ///< Absolute or relocatable address.
223*f325ba9dSStephen Wilson     elf_xword     st_size;      ///< Size of the symbol or zero.
224*f325ba9dSStephen Wilson     elf_word      st_name;      ///< Symbol name string index.
225*f325ba9dSStephen Wilson     unsigned char st_info;      ///< Symbol type and binding attributes.
226*f325ba9dSStephen Wilson     unsigned char st_other;     ///< Reserved for future use.
227*f325ba9dSStephen Wilson     elf_half      st_shndx;     ///< Section to which this symbol applies.
228*f325ba9dSStephen Wilson 
229*f325ba9dSStephen Wilson     ELFSymbol();
230*f325ba9dSStephen Wilson 
231*f325ba9dSStephen Wilson     /// Returns the binding attribute of the st_info member.
232*f325ba9dSStephen Wilson     unsigned char getBinding() const { return st_info >> 4; }
233*f325ba9dSStephen Wilson 
234*f325ba9dSStephen Wilson     /// Returns the type attribute of the st_info member.
235*f325ba9dSStephen Wilson     unsigned char getType() const { return st_info & 0x0F; }
236*f325ba9dSStephen Wilson 
237*f325ba9dSStephen Wilson     /// Sets the bining and type of the st_info member.
238*f325ba9dSStephen Wilson     void setBindingAndType(unsigned char binding, unsigned char type) {
239*f325ba9dSStephen Wilson         st_info = (binding << 4) + (type & 0x0F);
240*f325ba9dSStephen Wilson     }
241*f325ba9dSStephen Wilson 
242*f325ba9dSStephen Wilson     /// Parse an ELFSymbol entry from the given DataExtracter starting at
243*f325ba9dSStephen Wilson     /// position \p offset.  The address size of the DataExtracter determines if
244*f325ba9dSStephen Wilson     /// a 32 or 64 bit object is to be parsed.
245*f325ba9dSStephen Wilson     ///
246*f325ba9dSStephen Wilson     /// @param[in] data
247*f325ba9dSStephen Wilson     ///    The DataExtractor to read from.  The address size of the extractor
248*f325ba9dSStephen Wilson     ///    determines if a 32 or 64 bit object should be read.
249*f325ba9dSStephen Wilson     ///
250*f325ba9dSStephen Wilson     /// @param[in,out] offset
251*f325ba9dSStephen Wilson     ///    Pointer to an offset in the data.  On return the offset will be
252*f325ba9dSStephen Wilson     ///    advanced by the number of bytes read.
253*f325ba9dSStephen Wilson     ///
254*f325ba9dSStephen Wilson     /// @return
255*f325ba9dSStephen Wilson     ///    True if the ELFSymbol was successfully read and false otherwise.
256*f325ba9dSStephen Wilson     bool
257*f325ba9dSStephen Wilson     Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
258*f325ba9dSStephen Wilson };
259*f325ba9dSStephen Wilson 
260*f325ba9dSStephen Wilson //------------------------------------------------------------------------------
261*f325ba9dSStephen Wilson /// @class ELFDynamic
262*f325ba9dSStephen Wilson /// @brief Represents an entry in an ELF dynamic table.
263*f325ba9dSStephen Wilson struct ELFDynamic
264*f325ba9dSStephen Wilson {
265*f325ba9dSStephen Wilson     elf_sxword d_tag;           ///< Type of dynamic table entry.
266*f325ba9dSStephen Wilson     union
267*f325ba9dSStephen Wilson     {
268*f325ba9dSStephen Wilson         elf_xword d_val;        ///< Integer value of the table entry.
269*f325ba9dSStephen Wilson         elf_addr  d_ptr;        ///< Pointer value of the table entry.
270*f325ba9dSStephen Wilson     };
271*f325ba9dSStephen Wilson 
272*f325ba9dSStephen Wilson     ELFDynamic();
273*f325ba9dSStephen Wilson 
274*f325ba9dSStephen Wilson     /// Parse an ELFDynamic entry from the given DataExtracter starting at
275*f325ba9dSStephen Wilson     /// position \p offset.  The address size of the DataExtracter determines if
276*f325ba9dSStephen Wilson     /// a 32 or 64 bit object is to be parsed.
277*f325ba9dSStephen Wilson     ///
278*f325ba9dSStephen Wilson     /// @param[in] data
279*f325ba9dSStephen Wilson     ///    The DataExtractor to read from.  The address size of the extractor
280*f325ba9dSStephen Wilson     ///    determines if a 32 or 64 bit object should be read.
281*f325ba9dSStephen Wilson     ///
282*f325ba9dSStephen Wilson     /// @param[in,out] offset
283*f325ba9dSStephen Wilson     ///    Pointer to an offset in the data.  On return the offset will be
284*f325ba9dSStephen Wilson     ///    advanced by the number of bytes read.
285*f325ba9dSStephen Wilson     ///
286*f325ba9dSStephen Wilson     /// @return
287*f325ba9dSStephen Wilson     ///    True if the ELFDynamic entry was successfully read and false
288*f325ba9dSStephen Wilson     ///    otherwise.
289*f325ba9dSStephen Wilson     bool
290*f325ba9dSStephen Wilson     Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
291*f325ba9dSStephen Wilson };
292*f325ba9dSStephen Wilson 
293*f325ba9dSStephen Wilson } // End namespace elf.
294*f325ba9dSStephen Wilson 
295*f325ba9dSStephen Wilson #endif // #ifndef liblldb_ELFHeader_h_
296