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.
Is32BitELFHeader83     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.
Is64BitELFHeader92     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.
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, lldb::offset_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, lldb::offset_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.
getBindingELFSymbol237     unsigned char getBinding() const { return st_info >> 4; }
238 
239     /// Returns the type attribute of the st_info member.
getTypeELFSymbol240     unsigned char getType() const { return st_info & 0x0F; }
241 
242     /// Sets the binding and type of the st_info member.
setBindingAndTypeELFSymbol243     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.
284 struct 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.
317 struct 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
RelocType32ELFRel343     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
RelocType64ELFRel350     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
RelocSymbol32ELFRel358     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
RelocSymbol64ELFRel366     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.
375 struct 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
RelocType32ELFRela402     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
RelocType64ELFRela409     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
RelocSymbol32ELFRela417     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
RelocSymbol64ELFRela425     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