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