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
11f325ba9dSStephen Wilson /// @brief 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
17f325ba9dSStephen Wilson /// entity provides a \c Parse method which is capable of transparently reading
18f325ba9dSStephen Wilson /// 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 
24f325ba9dSStephen Wilson #include "llvm/Support/ELF.h"
25f325ba9dSStephen Wilson 
26f325ba9dSStephen Wilson #include "lldb/lldb-enumerations.h"
27f325ba9dSStephen Wilson 
28*b9c1b51eSKate Stone namespace lldb_private {
29f325ba9dSStephen Wilson class DataExtractor;
30f325ba9dSStephen Wilson } // End namespace lldb_private.
31f325ba9dSStephen Wilson 
32*b9c1b51eSKate Stone namespace elf {
33f325ba9dSStephen Wilson 
34f325ba9dSStephen Wilson //------------------------------------------------------------------------------
35f325ba9dSStephen Wilson /// @name ELF type definitions.
36f325ba9dSStephen Wilson ///
37f325ba9dSStephen Wilson /// Types used to represent the various components of ELF structures.  All types
38f325ba9dSStephen Wilson /// are signed or unsigned integral types wide enough to hold values from both
39f325ba9dSStephen Wilson /// 32 and 64 bit ELF variants.
40f325ba9dSStephen Wilson //@{
41f325ba9dSStephen Wilson typedef uint64_t elf_addr;
42f325ba9dSStephen Wilson typedef uint64_t elf_off;
43f325ba9dSStephen Wilson typedef uint16_t elf_half;
44f325ba9dSStephen Wilson typedef uint32_t elf_word;
45f325ba9dSStephen Wilson typedef int32_t elf_sword;
46f325ba9dSStephen Wilson typedef uint64_t elf_size;
47f325ba9dSStephen Wilson typedef uint64_t elf_xword;
48f325ba9dSStephen Wilson typedef int64_t elf_sxword;
49f325ba9dSStephen Wilson //@}
50f325ba9dSStephen Wilson 
51f325ba9dSStephen Wilson //------------------------------------------------------------------------------
52f325ba9dSStephen Wilson /// @class ELFHeader
53f325ba9dSStephen Wilson /// @brief Generic representation of an ELF file header.
54f325ba9dSStephen Wilson ///
55f325ba9dSStephen Wilson /// This object is used to identify the general attributes on an ELF file and to
56f325ba9dSStephen Wilson /// locate additional sections within the file.
57*b9c1b51eSKate Stone struct ELFHeader {
58f325ba9dSStephen Wilson   unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
59f325ba9dSStephen Wilson   elf_addr e_entry;     ///< Virtual address program entry point.
60f325ba9dSStephen Wilson   elf_off e_phoff;      ///< File offset of program header table.
61f325ba9dSStephen Wilson   elf_off e_shoff;      ///< File offset of section header table.
62f325ba9dSStephen Wilson   elf_word e_flags;     ///< Processor specific flags.
63f325ba9dSStephen Wilson   elf_word e_version;   ///< Version of object file (always 1).
64f325ba9dSStephen Wilson   elf_half e_type;      ///< Object file type.
65f325ba9dSStephen Wilson   elf_half e_machine;   ///< Target architecture.
66f325ba9dSStephen Wilson   elf_half e_ehsize;    ///< Byte size of the ELF header.
67f325ba9dSStephen Wilson   elf_half e_phentsize; ///< Size of a program header table entry.
68710dd5aeSGreg Clayton   elf_half e_phnum;     ///< Number of program header entries.
69f325ba9dSStephen Wilson   elf_half e_shentsize; ///< Size of a section header table entry.
70710dd5aeSGreg Clayton   elf_half e_shnum;     ///< Number of section header entries.
71f325ba9dSStephen Wilson   elf_half e_shstrndx;  ///< String table section index.
72f325ba9dSStephen Wilson 
73f325ba9dSStephen Wilson   ELFHeader();
74f325ba9dSStephen Wilson 
75f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
76f325ba9dSStephen Wilson   /// Returns true if this is a 32 bit ELF file header.
77f325ba9dSStephen Wilson   ///
78f325ba9dSStephen Wilson   /// @return
79f325ba9dSStephen Wilson   ///    True if this is a 32 bit ELF file header.
80f325ba9dSStephen Wilson   bool Is32Bit() const {
81f325ba9dSStephen Wilson     return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
82f325ba9dSStephen Wilson   }
83f325ba9dSStephen Wilson 
84f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
85f325ba9dSStephen Wilson   /// Returns true if this is a 64 bit ELF file header.
86f325ba9dSStephen Wilson   ///
87f325ba9dSStephen Wilson   /// @return
88f325ba9dSStephen Wilson   ///   True if this is a 64 bit ELF file header.
89f325ba9dSStephen Wilson   bool Is64Bit() const {
90f325ba9dSStephen Wilson     return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
91f325ba9dSStephen Wilson   }
92f325ba9dSStephen Wilson 
93f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
94f325ba9dSStephen Wilson   /// The byte order of this ELF file header.
95f325ba9dSStephen Wilson   ///
96f325ba9dSStephen Wilson   /// @return
97f325ba9dSStephen Wilson   ///    The byte order of this ELF file as described by the header.
98*b9c1b51eSKate Stone   lldb::ByteOrder GetByteOrder() const;
99f325ba9dSStephen Wilson 
100f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
10143fe645bSStephen Wilson   /// The jump slot relocation type of this ELF.
102*b9c1b51eSKate Stone   unsigned GetRelocationJumpSlotType() const;
10343fe645bSStephen Wilson 
10443fe645bSStephen Wilson   //--------------------------------------------------------------------------
105c836ae7dSMichael Sartain   /// Parse an ELFHeader entry starting at position \p offset and
106f325ba9dSStephen Wilson   /// update the data extractor with the address size and byte order
107f325ba9dSStephen Wilson   /// attributes as defined by the header.
108f325ba9dSStephen Wilson   ///
109f325ba9dSStephen Wilson   /// @param[in,out] data
110f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  Updated with the address size and
111f325ba9dSStephen Wilson   ///    byte order attributes appropriate to this header.
112f325ba9dSStephen Wilson   ///
113f325ba9dSStephen Wilson   /// @param[in,out] offset
114f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
115f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
116f325ba9dSStephen Wilson   ///
117f325ba9dSStephen Wilson   /// @return
118c836ae7dSMichael Sartain   ///    True if the ELFHeader was successfully read and false
119f325ba9dSStephen Wilson   ///    otherwise.
120*b9c1b51eSKate Stone   bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
121f325ba9dSStephen Wilson 
122f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
123f325ba9dSStephen Wilson   /// Examines at most EI_NIDENT bytes starting from the given pointer and
124f325ba9dSStephen Wilson   /// determines if the magic ELF identification exists.
125f325ba9dSStephen Wilson   ///
126f325ba9dSStephen Wilson   /// @return
127f325ba9dSStephen Wilson   ///    True if the given sequence of bytes identifies an ELF file.
128*b9c1b51eSKate Stone   static bool MagicBytesMatch(const uint8_t *magic);
129f325ba9dSStephen Wilson 
130f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
131f325ba9dSStephen Wilson   /// Examines at most EI_NIDENT bytes starting from the given address and
132f325ba9dSStephen Wilson   /// determines the address size of the underlying ELF file.  This function
133f325ba9dSStephen Wilson   /// should only be called on an pointer for which MagicBytesMatch returns
134f325ba9dSStephen Wilson   /// true.
135f325ba9dSStephen Wilson   ///
136f325ba9dSStephen Wilson   /// @return
137f325ba9dSStephen Wilson   ///    The number of bytes forming an address in the ELF file (either 4 or
138f325ba9dSStephen Wilson   ///    8), else zero if the address size could not be determined.
139*b9c1b51eSKate Stone   static unsigned AddressSizeInBytes(const uint8_t *magic);
140f325ba9dSStephen Wilson };
141f325ba9dSStephen Wilson 
142f325ba9dSStephen Wilson //------------------------------------------------------------------------------
143f325ba9dSStephen Wilson /// @class ELFSectionHeader
144f325ba9dSStephen Wilson /// @brief Generic representation of an ELF section header.
145*b9c1b51eSKate Stone struct ELFSectionHeader {
146f325ba9dSStephen Wilson   elf_word sh_name;       ///< Section name string index.
147f325ba9dSStephen Wilson   elf_word sh_type;       ///< Section type.
148f325ba9dSStephen Wilson   elf_xword sh_flags;     ///< Section attributes.
149f325ba9dSStephen Wilson   elf_addr sh_addr;       ///< Virtual address of the section in memory.
150f325ba9dSStephen Wilson   elf_off sh_offset;      ///< Start of section from beginning of file.
151f325ba9dSStephen Wilson   elf_xword sh_size;      ///< Number of bytes occupied in the file.
152f325ba9dSStephen Wilson   elf_word sh_link;       ///< Index of associated section.
153f325ba9dSStephen Wilson   elf_word sh_info;       ///< Extra section info (overloaded).
154f325ba9dSStephen Wilson   elf_xword sh_addralign; ///< Power of two alignment constraint.
155f325ba9dSStephen Wilson   elf_xword sh_entsize;   ///< Byte size of each section entry.
156f325ba9dSStephen Wilson 
157f325ba9dSStephen Wilson   ELFSectionHeader();
158f325ba9dSStephen Wilson 
159f325ba9dSStephen Wilson   //--------------------------------------------------------------------------
160f325ba9dSStephen Wilson   /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
161f325ba9dSStephen Wilson   /// position \p offset.
162f325ba9dSStephen Wilson   ///
163f325ba9dSStephen Wilson   /// @param[in] data
164f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
165f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
166f325ba9dSStephen Wilson   ///
167f325ba9dSStephen Wilson   /// @param[in,out] offset
168f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
169f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
170f325ba9dSStephen Wilson   ///
171f325ba9dSStephen Wilson   /// @return
172f325ba9dSStephen Wilson   ///    True if the ELFSectionHeader was successfully read and false
173f325ba9dSStephen Wilson   ///    otherwise.
174*b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
175f325ba9dSStephen Wilson };
176f325ba9dSStephen Wilson 
177f325ba9dSStephen Wilson //------------------------------------------------------------------------------
178f325ba9dSStephen Wilson /// @class ELFProgramHeader
179f325ba9dSStephen Wilson /// @brief Generic representation of an ELF program header.
180*b9c1b51eSKate Stone struct ELFProgramHeader {
181710dd5aeSGreg Clayton   elf_word p_type;    ///< Type of program segment.
182710dd5aeSGreg Clayton   elf_word p_flags;   ///< Segment attributes.
183710dd5aeSGreg Clayton   elf_off p_offset;   ///< Start of segment from beginning of file.
184f325ba9dSStephen Wilson   elf_addr p_vaddr;   ///< Virtual address of segment in memory.
185f325ba9dSStephen Wilson   elf_addr p_paddr;   ///< Physical address (for non-VM systems).
186f325ba9dSStephen Wilson   elf_xword p_filesz; ///< Byte size of the segment in file.
187f325ba9dSStephen Wilson   elf_xword p_memsz;  ///< Byte size of the segment in memory.
188710dd5aeSGreg Clayton   elf_xword p_align;  ///< Segment alignment constraint.
189f325ba9dSStephen Wilson 
190f325ba9dSStephen Wilson   ELFProgramHeader();
191f325ba9dSStephen Wilson 
192710dd5aeSGreg Clayton   /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
193710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
194f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
195f325ba9dSStephen Wilson   ///
196f325ba9dSStephen Wilson   /// @param[in] data
197f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
198f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
199f325ba9dSStephen Wilson   ///
200f325ba9dSStephen Wilson   /// @param[in,out] offset
201f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
202f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
203f325ba9dSStephen Wilson   ///
204f325ba9dSStephen Wilson   /// @return
205f325ba9dSStephen Wilson   ///    True if the ELFProgramHeader was successfully read and false
206f325ba9dSStephen Wilson   ///    otherwise.
207*b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
208f325ba9dSStephen Wilson };
209f325ba9dSStephen Wilson 
210f325ba9dSStephen Wilson //------------------------------------------------------------------------------
211f325ba9dSStephen Wilson /// @class ELFSymbol
212f325ba9dSStephen Wilson /// @brief Represents a symbol within an ELF symbol table.
213*b9c1b51eSKate Stone struct ELFSymbol {
214f325ba9dSStephen Wilson   elf_addr st_value;      ///< Absolute or relocatable address.
215f325ba9dSStephen Wilson   elf_xword st_size;      ///< Size of the symbol or zero.
216f325ba9dSStephen Wilson   elf_word st_name;       ///< Symbol name string index.
217f325ba9dSStephen Wilson   unsigned char st_info;  ///< Symbol type and binding attributes.
218f325ba9dSStephen Wilson   unsigned char st_other; ///< Reserved for future use.
219f325ba9dSStephen Wilson   elf_half st_shndx;      ///< Section to which this symbol applies.
220f325ba9dSStephen Wilson 
221f325ba9dSStephen Wilson   ELFSymbol();
222f325ba9dSStephen Wilson 
223f325ba9dSStephen Wilson   /// Returns the binding attribute of the st_info member.
224f325ba9dSStephen Wilson   unsigned char getBinding() const { return st_info >> 4; }
225f325ba9dSStephen Wilson 
226f325ba9dSStephen Wilson   /// Returns the type attribute of the st_info member.
227f325ba9dSStephen Wilson   unsigned char getType() const { return st_info & 0x0F; }
228f325ba9dSStephen Wilson 
229710dd5aeSGreg Clayton   /// Sets the binding and type of the st_info member.
230f325ba9dSStephen Wilson   void setBindingAndType(unsigned char binding, unsigned char type) {
231f325ba9dSStephen Wilson     st_info = (binding << 4) + (type & 0x0F);
232f325ba9dSStephen Wilson   }
233f325ba9dSStephen Wilson 
234*b9c1b51eSKate Stone   static const char *bindingToCString(unsigned char binding);
2359594f4c8SGreg Clayton 
236*b9c1b51eSKate Stone   static const char *typeToCString(unsigned char type);
2379594f4c8SGreg Clayton 
2389594f4c8SGreg Clayton   static const char *
2399594f4c8SGreg Clayton   sectionIndexToCString(elf_half shndx,
2409594f4c8SGreg Clayton                         const lldb_private::SectionList *section_list);
2419594f4c8SGreg Clayton 
242710dd5aeSGreg Clayton   /// Parse an ELFSymbol entry from the given DataExtractor starting at
243710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
244f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
245f325ba9dSStephen Wilson   ///
246f325ba9dSStephen Wilson   /// @param[in] data
247f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
248f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
249f325ba9dSStephen Wilson   ///
250f325ba9dSStephen Wilson   /// @param[in,out] offset
251f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
252f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
253f325ba9dSStephen Wilson   ///
254f325ba9dSStephen Wilson   /// @return
255f325ba9dSStephen Wilson   ///    True if the ELFSymbol was successfully read and false otherwise.
256*b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
2579594f4c8SGreg Clayton 
258*b9c1b51eSKate Stone   void Dump(lldb_private::Stream *s, uint32_t idx,
2599594f4c8SGreg Clayton             const lldb_private::DataExtractor *strtab_data,
2609594f4c8SGreg Clayton             const lldb_private::SectionList *section_list);
261f325ba9dSStephen Wilson };
262f325ba9dSStephen Wilson 
263f325ba9dSStephen Wilson //------------------------------------------------------------------------------
264f325ba9dSStephen Wilson /// @class ELFDynamic
265f325ba9dSStephen Wilson /// @brief Represents an entry in an ELF dynamic table.
266*b9c1b51eSKate Stone struct ELFDynamic {
267f325ba9dSStephen Wilson   elf_sxword d_tag; ///< Type of dynamic table entry.
268*b9c1b51eSKate Stone   union {
269f325ba9dSStephen Wilson     elf_xword d_val; ///< Integer value of the table entry.
270f325ba9dSStephen Wilson     elf_addr d_ptr;  ///< Pointer value of the table entry.
271f325ba9dSStephen Wilson   };
272f325ba9dSStephen Wilson 
273f325ba9dSStephen Wilson   ELFDynamic();
274f325ba9dSStephen Wilson 
275710dd5aeSGreg Clayton   /// Parse an ELFDynamic entry from the given DataExtractor starting at
276710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
277f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
278f325ba9dSStephen Wilson   ///
279f325ba9dSStephen Wilson   /// @param[in] data
280f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
281f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
282f325ba9dSStephen Wilson   ///
283f325ba9dSStephen Wilson   /// @param[in,out] offset
284f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
285f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
286f325ba9dSStephen Wilson   ///
287f325ba9dSStephen Wilson   /// @return
288f325ba9dSStephen Wilson   ///    True if the ELFDynamic entry was successfully read and false
289f325ba9dSStephen Wilson   ///    otherwise.
290*b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
291f325ba9dSStephen Wilson };
292f325ba9dSStephen Wilson 
29343fe645bSStephen Wilson //------------------------------------------------------------------------------
29443fe645bSStephen Wilson /// @class ELFRel
29543fe645bSStephen Wilson /// @brief Represents a relocation entry with an implicit addend.
296*b9c1b51eSKate Stone struct ELFRel {
29743fe645bSStephen Wilson   elf_addr r_offset; ///< Address of reference.
29843fe645bSStephen Wilson   elf_xword r_info;  ///< symbol index and type of relocation.
29943fe645bSStephen Wilson 
30043fe645bSStephen Wilson   ELFRel();
30143fe645bSStephen Wilson 
30243fe645bSStephen Wilson   /// Parse an ELFRel entry from the given DataExtractor starting at position
30343fe645bSStephen Wilson   /// \p offset.  The address size of the DataExtractor determines if a 32 or
30443fe645bSStephen Wilson   /// 64 bit object is to be parsed.
30543fe645bSStephen Wilson   ///
30643fe645bSStephen Wilson   /// @param[in] data
30743fe645bSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
30843fe645bSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
30943fe645bSStephen Wilson   ///
31043fe645bSStephen Wilson   /// @param[in,out] offset
31143fe645bSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
31243fe645bSStephen Wilson   ///    advanced by the number of bytes read.
31343fe645bSStephen Wilson   ///
31443fe645bSStephen Wilson   /// @return
31543fe645bSStephen Wilson   ///    True if the ELFRel entry was successfully read and false otherwise.
316*b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
31743fe645bSStephen Wilson 
31843fe645bSStephen Wilson   /// Returns the type when the given entry represents a 32-bit relocation.
319*b9c1b51eSKate Stone   static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }
32043fe645bSStephen Wilson 
32143fe645bSStephen Wilson   /// Returns the type when the given entry represents a 64-bit relocation.
322*b9c1b51eSKate Stone   static unsigned RelocType64(const ELFRel &rel) {
32343fe645bSStephen Wilson     return rel.r_info & 0xffffffff;
32443fe645bSStephen Wilson   }
32543fe645bSStephen Wilson 
32643fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 32-bit
327aaa0ba31SBruce Mitchener   /// relocation.
328*b9c1b51eSKate Stone   static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }
32943fe645bSStephen Wilson 
33043fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 64-bit
331aaa0ba31SBruce Mitchener   /// relocation.
332*b9c1b51eSKate Stone   static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }
33343fe645bSStephen Wilson };
33443fe645bSStephen Wilson 
33543fe645bSStephen Wilson //------------------------------------------------------------------------------
33643fe645bSStephen Wilson /// @class ELFRela
33743fe645bSStephen Wilson /// @brief Represents a relocation entry with an explicit addend.
338*b9c1b51eSKate Stone struct ELFRela {
33943fe645bSStephen Wilson   elf_addr r_offset;   ///< Address of reference.
34043fe645bSStephen Wilson   elf_xword r_info;    ///< Symbol index and type of relocation.
34143fe645bSStephen Wilson   elf_sxword r_addend; ///< Constant part of expression.
34243fe645bSStephen Wilson 
34343fe645bSStephen Wilson   ELFRela();
34443fe645bSStephen Wilson 
34543fe645bSStephen Wilson   /// Parse an ELFRela entry from the given DataExtractor starting at position
34643fe645bSStephen Wilson   /// \p offset.  The address size of the DataExtractor determines if a 32 or
34743fe645bSStephen Wilson   /// 64 bit object is to be parsed.
34843fe645bSStephen Wilson   ///
34943fe645bSStephen Wilson   /// @param[in] data
35043fe645bSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
35143fe645bSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
35243fe645bSStephen Wilson   ///
35343fe645bSStephen Wilson   /// @param[in,out] offset
35443fe645bSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
35543fe645bSStephen Wilson   ///    advanced by the number of bytes read.
35643fe645bSStephen Wilson   ///
35743fe645bSStephen Wilson   /// @return
35843fe645bSStephen Wilson   ///    True if the ELFRela entry was successfully read and false otherwise.
359*b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
36043fe645bSStephen Wilson 
36143fe645bSStephen Wilson   /// Returns the type when the given entry represents a 32-bit relocation.
362*b9c1b51eSKate Stone   static unsigned RelocType32(const ELFRela &rela) {
36343fe645bSStephen Wilson     return rela.r_info & 0x0ff;
36443fe645bSStephen Wilson   }
36543fe645bSStephen Wilson 
36643fe645bSStephen Wilson   /// Returns the type when the given entry represents a 64-bit relocation.
367*b9c1b51eSKate Stone   static unsigned RelocType64(const ELFRela &rela) {
36843fe645bSStephen Wilson     return rela.r_info & 0xffffffff;
36943fe645bSStephen Wilson   }
37043fe645bSStephen Wilson 
37143fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 32-bit
372aaa0ba31SBruce Mitchener   /// relocation.
373*b9c1b51eSKate Stone   static unsigned RelocSymbol32(const ELFRela &rela) {
37443fe645bSStephen Wilson     return rela.r_info >> 8;
37543fe645bSStephen Wilson   }
37643fe645bSStephen Wilson 
37743fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 64-bit
378aaa0ba31SBruce Mitchener   /// relocation.
379*b9c1b51eSKate Stone   static unsigned RelocSymbol64(const ELFRela &rela) {
38043fe645bSStephen Wilson     return rela.r_info >> 32;
38143fe645bSStephen Wilson   }
38243fe645bSStephen Wilson };
38343fe645bSStephen Wilson 
384f325ba9dSStephen Wilson } // End namespace elf.
385f325ba9dSStephen Wilson 
386f325ba9dSStephen Wilson #endif // #ifndef liblldb_ELFHeader_h_
387