1f325ba9dSStephen Wilson //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//
2f325ba9dSStephen Wilson //
3f325ba9dSStephen Wilson //                     The LLVM Compiler Infrastructure
4f325ba9dSStephen Wilson //
5f325ba9dSStephen Wilson // This file is distributed under the University of Illinois Open Source
6f325ba9dSStephen Wilson // License. See LICENSE.TXT for details.
7f325ba9dSStephen Wilson //
8f325ba9dSStephen Wilson //===----------------------------------------------------------------------===//
9f325ba9dSStephen Wilson //
10f325ba9dSStephen Wilson /// @file
11*d8f460e8SAdrian Prantl /// Generic structures and typedefs for ELF files.
12f325ba9dSStephen Wilson ///
13f325ba9dSStephen Wilson /// This file provides definitions for the various entities comprising an ELF
14f325ba9dSStephen Wilson /// file.  The structures are generic in the sense that they do not correspond
15f325ba9dSStephen Wilson /// to the exact binary layout of an ELF, but can be used to hold the
16f325ba9dSStephen Wilson /// information present in both 32 and 64 bit variants of the format.  Each
17*d8f460e8SAdrian Prantl /// entity provides a \c Parse method which is capable of transparently
18*d8f460e8SAdrian Prantl /// reading both 32 and 64 bit instances of the object.
19f325ba9dSStephen Wilson //===----------------------------------------------------------------------===//
20f325ba9dSStephen Wilson 
21f325ba9dSStephen Wilson #ifndef liblldb_ELFHeader_h_
22f325ba9dSStephen Wilson #define liblldb_ELFHeader_h_
23f325ba9dSStephen Wilson 
24264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h"
25f325ba9dSStephen Wilson 
26f325ba9dSStephen Wilson #include "lldb/lldb-enumerations.h"
2723ccc291SPavel Labath #include "lldb/lldb-types.h"
28f325ba9dSStephen Wilson 
29b9c1b51eSKate Stone namespace lldb_private {
30f325ba9dSStephen Wilson class DataExtractor;
31f325ba9dSStephen Wilson } // End namespace lldb_private.
32f325ba9dSStephen Wilson 
33b9c1b51eSKate Stone namespace elf {
34f325ba9dSStephen Wilson 
35f325ba9dSStephen Wilson //------------------------------------------------------------------------------
36f325ba9dSStephen Wilson /// @name ELF type definitions.
37f325ba9dSStephen Wilson ///
38*d8f460e8SAdrian Prantl /// Types used to represent the various components of ELF structures.  All
39*d8f460e8SAdrian Prantl /// types are signed or unsigned integral types wide enough to hold values
40*d8f460e8SAdrian Prantl /// from both
41f325ba9dSStephen Wilson /// 32 and 64 bit ELF variants.
42f325ba9dSStephen Wilson //@{
43f325ba9dSStephen Wilson typedef uint64_t elf_addr;
44f325ba9dSStephen Wilson typedef uint64_t elf_off;
45f325ba9dSStephen Wilson typedef uint16_t elf_half;
46f325ba9dSStephen Wilson typedef uint32_t elf_word;
47f325ba9dSStephen Wilson typedef int32_t elf_sword;
48f325ba9dSStephen Wilson typedef uint64_t elf_size;
49f325ba9dSStephen Wilson typedef uint64_t elf_xword;
50f325ba9dSStephen Wilson typedef int64_t elf_sxword;
51f325ba9dSStephen Wilson //@}
52f325ba9dSStephen Wilson 
53f325ba9dSStephen Wilson //------------------------------------------------------------------------------
54f325ba9dSStephen Wilson /// @class ELFHeader
55*d8f460e8SAdrian Prantl /// Generic representation of an ELF file header.
56f325ba9dSStephen Wilson ///
57*d8f460e8SAdrian Prantl /// This object is used to identify the general attributes on an ELF file and
58*d8f460e8SAdrian Prantl /// to locate additional sections within the file.
59b9c1b51eSKate Stone struct ELFHeader {
60f325ba9dSStephen Wilson   unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
61f325ba9dSStephen Wilson   elf_addr e_entry;     ///< Virtual address program entry point.
62f325ba9dSStephen Wilson   elf_off e_phoff;      ///< File offset of program header table.
63f325ba9dSStephen Wilson   elf_off e_shoff;      ///< File offset of section header table.
64f325ba9dSStephen Wilson   elf_word e_flags;     ///< Processor specific flags.
65f325ba9dSStephen Wilson   elf_word e_version;   ///< Version of object file (always 1).
66f325ba9dSStephen Wilson   elf_half e_type;      ///< Object file type.
67f325ba9dSStephen Wilson   elf_half e_machine;   ///< Target architecture.
68f325ba9dSStephen Wilson   elf_half e_ehsize;    ///< Byte size of the ELF header.
69f325ba9dSStephen Wilson   elf_half e_phentsize; ///< Size of a program header table entry.
7023ccc291SPavel Labath   elf_half e_phnum_hdr; ///< Number of program header entries.
71f325ba9dSStephen Wilson   elf_half e_shentsize; ///< Size of a section header table entry.
7223ccc291SPavel Labath   elf_half e_shnum_hdr; ///< Number of section header entries.
7323ccc291SPavel Labath   elf_half e_shstrndx_hdr; ///< String table section index.
7423ccc291SPavel Labath 
7523ccc291SPavel Labath   // In some cases these numbers do not fit in 16 bits and they are
7623ccc291SPavel Labath   // stored outside of the header in section #0. Here are the actual
7723ccc291SPavel Labath   // values.
7823ccc291SPavel Labath   elf_word e_phnum;     ///< Number of program header entries.
7923ccc291SPavel Labath   elf_word e_shnum;     ///< Number of section header entries.
8023ccc291SPavel Labath   elf_word e_shstrndx;  ///< String table section index.
81f325ba9dSStephen Wilson 
82f325ba9dSStephen Wilson   ELFHeader();
83f325ba9dSStephen Wilson 
84f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
85f325ba9dSStephen Wilson   /// Returns true if this is a 32 bit ELF file header.
86f325ba9dSStephen Wilson   ///
87f325ba9dSStephen Wilson   /// @return
88f325ba9dSStephen Wilson   ///    True if this is a 32 bit ELF file header.
89f325ba9dSStephen Wilson   bool Is32Bit() const {
90f325ba9dSStephen Wilson     return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
91f325ba9dSStephen Wilson   }
92f325ba9dSStephen Wilson 
93f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
94f325ba9dSStephen Wilson   /// Returns true if this is a 64 bit ELF file header.
95f325ba9dSStephen Wilson   ///
96f325ba9dSStephen Wilson   /// @return
97f325ba9dSStephen Wilson   ///   True if this is a 64 bit ELF file header.
98f325ba9dSStephen Wilson   bool Is64Bit() const {
99f325ba9dSStephen Wilson     return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
100f325ba9dSStephen Wilson   }
101f325ba9dSStephen Wilson 
102f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
103f325ba9dSStephen Wilson   /// The byte order of this ELF file header.
104f325ba9dSStephen Wilson   ///
105f325ba9dSStephen Wilson   /// @return
106f325ba9dSStephen Wilson   ///    The byte order of this ELF file as described by the header.
107b9c1b51eSKate Stone   lldb::ByteOrder GetByteOrder() const;
108f325ba9dSStephen Wilson 
109f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
11043fe645bSStephen Wilson   /// The jump slot relocation type of this ELF.
111b9c1b51eSKate Stone   unsigned GetRelocationJumpSlotType() const;
11243fe645bSStephen Wilson 
11343fe645bSStephen Wilson   //--------------------------------------------------------------------------
11423ccc291SPavel Labath   /// Check if there should be header extension in section header #0
11523ccc291SPavel Labath   ///
11623ccc291SPavel Labath   /// @return
11723ccc291SPavel Labath   ///    True if parsing the ELFHeader requires reading header extension
11823ccc291SPavel Labath   ///    and false otherwise.
11923ccc291SPavel Labath   bool HasHeaderExtension() const;
12023ccc291SPavel Labath 
12123ccc291SPavel Labath   //--------------------------------------------------------------------------
122*d8f460e8SAdrian Prantl   /// Parse an ELFHeader entry starting at position \p offset and update the
123*d8f460e8SAdrian Prantl   /// data extractor with the address size and byte order attributes as
124*d8f460e8SAdrian Prantl   /// defined by the header.
125f325ba9dSStephen Wilson   ///
126f325ba9dSStephen Wilson   /// @param[in,out] data
127f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  Updated with the address size and
128f325ba9dSStephen Wilson   ///    byte order attributes appropriate to this header.
129f325ba9dSStephen Wilson   ///
130f325ba9dSStephen Wilson   /// @param[in,out] offset
131f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
132f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
133f325ba9dSStephen Wilson   ///
134f325ba9dSStephen Wilson   /// @return
135c836ae7dSMichael Sartain   ///    True if the ELFHeader was successfully read and false
136f325ba9dSStephen Wilson   ///    otherwise.
137b9c1b51eSKate Stone   bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
138f325ba9dSStephen Wilson 
139f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
140f325ba9dSStephen Wilson   /// Examines at most EI_NIDENT bytes starting from the given pointer and
141f325ba9dSStephen Wilson   /// determines if the magic ELF identification exists.
142f325ba9dSStephen Wilson   ///
143f325ba9dSStephen Wilson   /// @return
144f325ba9dSStephen Wilson   ///    True if the given sequence of bytes identifies an ELF file.
145b9c1b51eSKate Stone   static bool MagicBytesMatch(const uint8_t *magic);
146f325ba9dSStephen Wilson 
147f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
148f325ba9dSStephen Wilson   /// Examines at most EI_NIDENT bytes starting from the given address and
149f325ba9dSStephen Wilson   /// determines the address size of the underlying ELF file.  This function
150f325ba9dSStephen Wilson   /// should only be called on an pointer for which MagicBytesMatch returns
151f325ba9dSStephen Wilson   /// true.
152f325ba9dSStephen Wilson   ///
153f325ba9dSStephen Wilson   /// @return
154f325ba9dSStephen Wilson   ///    The number of bytes forming an address in the ELF file (either 4 or
155f325ba9dSStephen Wilson   ///    8), else zero if the address size could not be determined.
156b9c1b51eSKate Stone   static unsigned AddressSizeInBytes(const uint8_t *magic);
15723ccc291SPavel Labath 
15823ccc291SPavel Labath private:
15923ccc291SPavel Labath 
16023ccc291SPavel Labath   //--------------------------------------------------------------------------
161*d8f460e8SAdrian Prantl   /// Parse an ELFHeader header extension entry.  This method is called by
162*d8f460e8SAdrian Prantl   /// Parse().
16323ccc291SPavel Labath   ///
16423ccc291SPavel Labath   /// @param[in] data
16523ccc291SPavel Labath   ///    The DataExtractor to read from.
16623ccc291SPavel Labath   void ParseHeaderExtension(lldb_private::DataExtractor &data);
167f325ba9dSStephen Wilson };
168f325ba9dSStephen Wilson 
169f325ba9dSStephen Wilson //------------------------------------------------------------------------------
170f325ba9dSStephen Wilson /// @class ELFSectionHeader
171*d8f460e8SAdrian Prantl /// Generic representation of an ELF section header.
172b9c1b51eSKate Stone struct ELFSectionHeader {
173f325ba9dSStephen Wilson   elf_word sh_name;       ///< Section name string index.
174f325ba9dSStephen Wilson   elf_word sh_type;       ///< Section type.
175f325ba9dSStephen Wilson   elf_xword sh_flags;     ///< Section attributes.
176f325ba9dSStephen Wilson   elf_addr sh_addr;       ///< Virtual address of the section in memory.
177f325ba9dSStephen Wilson   elf_off sh_offset;      ///< Start of section from beginning of file.
178f325ba9dSStephen Wilson   elf_xword sh_size;      ///< Number of bytes occupied in the file.
179f325ba9dSStephen Wilson   elf_word sh_link;       ///< Index of associated section.
180f325ba9dSStephen Wilson   elf_word sh_info;       ///< Extra section info (overloaded).
181f325ba9dSStephen Wilson   elf_xword sh_addralign; ///< Power of two alignment constraint.
182f325ba9dSStephen Wilson   elf_xword sh_entsize;   ///< Byte size of each section entry.
183f325ba9dSStephen Wilson 
184f325ba9dSStephen Wilson   ELFSectionHeader();
185f325ba9dSStephen Wilson 
186f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
187f325ba9dSStephen Wilson   /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
188f325ba9dSStephen Wilson   /// position \p offset.
189f325ba9dSStephen Wilson   ///
190f325ba9dSStephen Wilson   /// @param[in] data
191f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
192f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
193f325ba9dSStephen Wilson   ///
194f325ba9dSStephen Wilson   /// @param[in,out] offset
195f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
196f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
197f325ba9dSStephen Wilson   ///
198f325ba9dSStephen Wilson   /// @return
199f325ba9dSStephen Wilson   ///    True if the ELFSectionHeader was successfully read and false
200f325ba9dSStephen Wilson   ///    otherwise.
201b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
202f325ba9dSStephen Wilson };
203f325ba9dSStephen Wilson 
204f325ba9dSStephen Wilson //------------------------------------------------------------------------------
205f325ba9dSStephen Wilson /// @class ELFProgramHeader
206*d8f460e8SAdrian Prantl /// Generic representation of an ELF program header.
207b9c1b51eSKate Stone struct ELFProgramHeader {
208710dd5aeSGreg Clayton   elf_word p_type;    ///< Type of program segment.
209710dd5aeSGreg Clayton   elf_word p_flags;   ///< Segment attributes.
210710dd5aeSGreg Clayton   elf_off p_offset;   ///< Start of segment from beginning of file.
211f325ba9dSStephen Wilson   elf_addr p_vaddr;   ///< Virtual address of segment in memory.
212f325ba9dSStephen Wilson   elf_addr p_paddr;   ///< Physical address (for non-VM systems).
213f325ba9dSStephen Wilson   elf_xword p_filesz; ///< Byte size of the segment in file.
214f325ba9dSStephen Wilson   elf_xword p_memsz;  ///< Byte size of the segment in memory.
215710dd5aeSGreg Clayton   elf_xword p_align;  ///< Segment alignment constraint.
216f325ba9dSStephen Wilson 
217f325ba9dSStephen Wilson   ELFProgramHeader();
218f325ba9dSStephen Wilson 
219710dd5aeSGreg Clayton   /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
220710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
221f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
222f325ba9dSStephen Wilson   ///
223f325ba9dSStephen Wilson   /// @param[in] data
224f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
225f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
226f325ba9dSStephen Wilson   ///
227f325ba9dSStephen Wilson   /// @param[in,out] offset
228f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
229f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
230f325ba9dSStephen Wilson   ///
231f325ba9dSStephen Wilson   /// @return
232f325ba9dSStephen Wilson   ///    True if the ELFProgramHeader was successfully read and false
233f325ba9dSStephen Wilson   ///    otherwise.
234b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
235f325ba9dSStephen Wilson };
236f325ba9dSStephen Wilson 
237f325ba9dSStephen Wilson //------------------------------------------------------------------------------
238f325ba9dSStephen Wilson /// @class ELFSymbol
239*d8f460e8SAdrian Prantl /// Represents a symbol within an ELF symbol table.
240b9c1b51eSKate Stone struct ELFSymbol {
241f325ba9dSStephen Wilson   elf_addr st_value;      ///< Absolute or relocatable address.
242f325ba9dSStephen Wilson   elf_xword st_size;      ///< Size of the symbol or zero.
243f325ba9dSStephen Wilson   elf_word st_name;       ///< Symbol name string index.
244f325ba9dSStephen Wilson   unsigned char st_info;  ///< Symbol type and binding attributes.
245f325ba9dSStephen Wilson   unsigned char st_other; ///< Reserved for future use.
246f325ba9dSStephen Wilson   elf_half st_shndx;      ///< Section to which this symbol applies.
247f325ba9dSStephen Wilson 
248f325ba9dSStephen Wilson   ELFSymbol();
249f325ba9dSStephen Wilson 
250f325ba9dSStephen Wilson   /// Returns the binding attribute of the st_info member.
251f325ba9dSStephen Wilson   unsigned char getBinding() const { return st_info >> 4; }
252f325ba9dSStephen Wilson 
253f325ba9dSStephen Wilson   /// Returns the type attribute of the st_info member.
254f325ba9dSStephen Wilson   unsigned char getType() const { return st_info & 0x0F; }
255f325ba9dSStephen Wilson 
256710dd5aeSGreg Clayton   /// Sets the binding and type of the st_info member.
257f325ba9dSStephen Wilson   void setBindingAndType(unsigned char binding, unsigned char type) {
258f325ba9dSStephen Wilson     st_info = (binding << 4) + (type & 0x0F);
259f325ba9dSStephen Wilson   }
260f325ba9dSStephen Wilson 
261b9c1b51eSKate Stone   static const char *bindingToCString(unsigned char binding);
2629594f4c8SGreg Clayton 
263b9c1b51eSKate Stone   static const char *typeToCString(unsigned char type);
2649594f4c8SGreg Clayton 
2659594f4c8SGreg Clayton   static const char *
2669594f4c8SGreg Clayton   sectionIndexToCString(elf_half shndx,
2679594f4c8SGreg Clayton                         const lldb_private::SectionList *section_list);
2689594f4c8SGreg Clayton 
269710dd5aeSGreg Clayton   /// Parse an ELFSymbol entry from the given DataExtractor starting at
270710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
271f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
272f325ba9dSStephen Wilson   ///
273f325ba9dSStephen Wilson   /// @param[in] data
274f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
275f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
276f325ba9dSStephen Wilson   ///
277f325ba9dSStephen Wilson   /// @param[in,out] offset
278f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
279f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
280f325ba9dSStephen Wilson   ///
281f325ba9dSStephen Wilson   /// @return
282f325ba9dSStephen Wilson   ///    True if the ELFSymbol was successfully read and false otherwise.
283b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
2849594f4c8SGreg Clayton 
285b9c1b51eSKate Stone   void Dump(lldb_private::Stream *s, uint32_t idx,
2869594f4c8SGreg Clayton             const lldb_private::DataExtractor *strtab_data,
2879594f4c8SGreg Clayton             const lldb_private::SectionList *section_list);
288f325ba9dSStephen Wilson };
289f325ba9dSStephen Wilson 
290f325ba9dSStephen Wilson //------------------------------------------------------------------------------
291f325ba9dSStephen Wilson /// @class ELFDynamic
292*d8f460e8SAdrian Prantl /// Represents an entry in an ELF dynamic table.
293b9c1b51eSKate Stone struct ELFDynamic {
294f325ba9dSStephen Wilson   elf_sxword d_tag; ///< Type of dynamic table entry.
295b9c1b51eSKate Stone   union {
296f325ba9dSStephen Wilson     elf_xword d_val; ///< Integer value of the table entry.
297f325ba9dSStephen Wilson     elf_addr d_ptr;  ///< Pointer value of the table entry.
298f325ba9dSStephen Wilson   };
299f325ba9dSStephen Wilson 
300f325ba9dSStephen Wilson   ELFDynamic();
301f325ba9dSStephen Wilson 
302710dd5aeSGreg Clayton   /// Parse an ELFDynamic entry from the given DataExtractor starting at
303710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
304f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
305f325ba9dSStephen Wilson   ///
306f325ba9dSStephen Wilson   /// @param[in] data
307f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
308f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
309f325ba9dSStephen Wilson   ///
310f325ba9dSStephen Wilson   /// @param[in,out] offset
311f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
312f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
313f325ba9dSStephen Wilson   ///
314f325ba9dSStephen Wilson   /// @return
315f325ba9dSStephen Wilson   ///    True if the ELFDynamic entry was successfully read and false
316f325ba9dSStephen Wilson   ///    otherwise.
317b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
318f325ba9dSStephen Wilson };
319f325ba9dSStephen Wilson 
32043fe645bSStephen Wilson //------------------------------------------------------------------------------
32143fe645bSStephen Wilson /// @class ELFRel
322*d8f460e8SAdrian Prantl /// Represents a relocation entry with an implicit addend.
323b9c1b51eSKate Stone struct ELFRel {
32443fe645bSStephen Wilson   elf_addr r_offset; ///< Address of reference.
32543fe645bSStephen Wilson   elf_xword r_info;  ///< symbol index and type of relocation.
32643fe645bSStephen Wilson 
32743fe645bSStephen Wilson   ELFRel();
32843fe645bSStephen Wilson 
32943fe645bSStephen Wilson   /// Parse an ELFRel entry from the given DataExtractor starting at position
33043fe645bSStephen Wilson   /// \p offset.  The address size of the DataExtractor determines if a 32 or
33143fe645bSStephen Wilson   /// 64 bit object is to be parsed.
33243fe645bSStephen Wilson   ///
33343fe645bSStephen Wilson   /// @param[in] data
33443fe645bSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
33543fe645bSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
33643fe645bSStephen Wilson   ///
33743fe645bSStephen Wilson   /// @param[in,out] offset
33843fe645bSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
33943fe645bSStephen Wilson   ///    advanced by the number of bytes read.
34043fe645bSStephen Wilson   ///
34143fe645bSStephen Wilson   /// @return
34243fe645bSStephen Wilson   ///    True if the ELFRel entry was successfully read and false otherwise.
343b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
34443fe645bSStephen Wilson 
34543fe645bSStephen Wilson   /// Returns the type when the given entry represents a 32-bit relocation.
346b9c1b51eSKate Stone   static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }
34743fe645bSStephen Wilson 
34843fe645bSStephen Wilson   /// Returns the type when the given entry represents a 64-bit relocation.
349b9c1b51eSKate Stone   static unsigned RelocType64(const ELFRel &rel) {
35043fe645bSStephen Wilson     return rel.r_info & 0xffffffff;
35143fe645bSStephen Wilson   }
35243fe645bSStephen Wilson 
35343fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 32-bit
354aaa0ba31SBruce Mitchener   /// relocation.
355b9c1b51eSKate Stone   static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }
35643fe645bSStephen Wilson 
35743fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 64-bit
358aaa0ba31SBruce Mitchener   /// relocation.
359b9c1b51eSKate Stone   static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }
36043fe645bSStephen Wilson };
36143fe645bSStephen Wilson 
36243fe645bSStephen Wilson //------------------------------------------------------------------------------
36343fe645bSStephen Wilson /// @class ELFRela
364*d8f460e8SAdrian Prantl /// Represents a relocation entry with an explicit addend.
365b9c1b51eSKate Stone struct ELFRela {
36643fe645bSStephen Wilson   elf_addr r_offset;   ///< Address of reference.
36743fe645bSStephen Wilson   elf_xword r_info;    ///< Symbol index and type of relocation.
36843fe645bSStephen Wilson   elf_sxword r_addend; ///< Constant part of expression.
36943fe645bSStephen Wilson 
37043fe645bSStephen Wilson   ELFRela();
37143fe645bSStephen Wilson 
37243fe645bSStephen Wilson   /// Parse an ELFRela entry from the given DataExtractor starting at position
37343fe645bSStephen Wilson   /// \p offset.  The address size of the DataExtractor determines if a 32 or
37443fe645bSStephen Wilson   /// 64 bit object is to be parsed.
37543fe645bSStephen Wilson   ///
37643fe645bSStephen Wilson   /// @param[in] data
37743fe645bSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
37843fe645bSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
37943fe645bSStephen Wilson   ///
38043fe645bSStephen Wilson   /// @param[in,out] offset
38143fe645bSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
38243fe645bSStephen Wilson   ///    advanced by the number of bytes read.
38343fe645bSStephen Wilson   ///
38443fe645bSStephen Wilson   /// @return
38543fe645bSStephen Wilson   ///    True if the ELFRela entry was successfully read and false otherwise.
386b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
38743fe645bSStephen Wilson 
38843fe645bSStephen Wilson   /// Returns the type when the given entry represents a 32-bit relocation.
389b9c1b51eSKate Stone   static unsigned RelocType32(const ELFRela &rela) {
39043fe645bSStephen Wilson     return rela.r_info & 0x0ff;
39143fe645bSStephen Wilson   }
39243fe645bSStephen Wilson 
39343fe645bSStephen Wilson   /// Returns the type when the given entry represents a 64-bit relocation.
394b9c1b51eSKate Stone   static unsigned RelocType64(const ELFRela &rela) {
39543fe645bSStephen Wilson     return rela.r_info & 0xffffffff;
39643fe645bSStephen Wilson   }
39743fe645bSStephen Wilson 
39843fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 32-bit
399aaa0ba31SBruce Mitchener   /// relocation.
400b9c1b51eSKate Stone   static unsigned RelocSymbol32(const ELFRela &rela) {
40143fe645bSStephen Wilson     return rela.r_info >> 8;
40243fe645bSStephen Wilson   }
40343fe645bSStephen Wilson 
40443fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 64-bit
405aaa0ba31SBruce Mitchener   /// relocation.
406b9c1b51eSKate Stone   static unsigned RelocSymbol64(const ELFRela &rela) {
40743fe645bSStephen Wilson     return rela.r_info >> 32;
40843fe645bSStephen Wilson   }
40943fe645bSStephen Wilson };
41043fe645bSStephen Wilson 
411f325ba9dSStephen Wilson } // End namespace elf.
412f325ba9dSStephen Wilson 
413f325ba9dSStephen Wilson #endif // #ifndef liblldb_ELFHeader_h_
414