1f325ba9dSStephen Wilson //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//
2f325ba9dSStephen Wilson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f325ba9dSStephen Wilson //
7f325ba9dSStephen Wilson //===----------------------------------------------------------------------===//
8f325ba9dSStephen Wilson //
9f05b42e9SAdrian Prantl /// \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 
20*cdc514e4SJonas Devlieghere #ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
21*cdc514e4SJonas Devlieghere #define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_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 
34f05b42e9SAdrian Prantl /// \name ELF type definitions.
35f325ba9dSStephen Wilson ///
36d8f460e8SAdrian Prantl /// Types used to represent the various components of ELF structures.  All
37d8f460e8SAdrian Prantl /// types are signed or unsigned integral types wide enough to hold values
38d8f460e8SAdrian Prantl /// 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 
51f05b42e9SAdrian Prantl /// \class ELFHeader
52d8f460e8SAdrian Prantl /// Generic representation of an ELF file header.
53f325ba9dSStephen Wilson ///
54d8f460e8SAdrian Prantl /// This object is used to identify the general attributes on an ELF file and
55d8f460e8SAdrian Prantl /// to locate additional sections within the file.
56b9c1b51eSKate Stone struct ELFHeader {
57f325ba9dSStephen Wilson   unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
58f325ba9dSStephen Wilson   elf_addr e_entry;     ///< Virtual address program entry point.
59f325ba9dSStephen Wilson   elf_off e_phoff;      ///< File offset of program header table.
60f325ba9dSStephen Wilson   elf_off e_shoff;      ///< File offset of section header table.
61f325ba9dSStephen Wilson   elf_word e_flags;     ///< Processor specific flags.
62f325ba9dSStephen Wilson   elf_word e_version;   ///< Version of object file (always 1).
63f325ba9dSStephen Wilson   elf_half e_type;      ///< Object file type.
64f325ba9dSStephen Wilson   elf_half e_machine;   ///< Target architecture.
65f325ba9dSStephen Wilson   elf_half e_ehsize;    ///< Byte size of the ELF header.
66f325ba9dSStephen Wilson   elf_half e_phentsize; ///< Size of a program header table entry.
6723ccc291SPavel Labath   elf_half e_phnum_hdr; ///< Number of program header entries.
68f325ba9dSStephen Wilson   elf_half e_shentsize; ///< Size of a section header table entry.
6923ccc291SPavel Labath   elf_half e_shnum_hdr; ///< Number of section header entries.
7023ccc291SPavel Labath   elf_half e_shstrndx_hdr; ///< String table section index.
7123ccc291SPavel Labath 
7223ccc291SPavel Labath   // In some cases these numbers do not fit in 16 bits and they are
7323ccc291SPavel Labath   // stored outside of the header in section #0. Here are the actual
7423ccc291SPavel Labath   // values.
7523ccc291SPavel Labath   elf_word e_phnum;     ///< Number of program header entries.
7623ccc291SPavel Labath   elf_word e_shnum;     ///< Number of section header entries.
7723ccc291SPavel Labath   elf_word e_shstrndx;  ///< String table section index.
78f325ba9dSStephen Wilson 
79f325ba9dSStephen Wilson   ELFHeader();
80f325ba9dSStephen Wilson 
81f325ba9dSStephen Wilson   /// Returns true if this is a 32 bit ELF file header.
82f325ba9dSStephen Wilson   ///
83f05b42e9SAdrian Prantl   /// \return
84f325ba9dSStephen Wilson   ///    True if this is a 32 bit ELF file header.
Is32BitELFHeader85f325ba9dSStephen Wilson   bool Is32Bit() const {
86f325ba9dSStephen Wilson     return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
87f325ba9dSStephen Wilson   }
88f325ba9dSStephen Wilson 
89f325ba9dSStephen Wilson   /// Returns true if this is a 64 bit ELF file header.
90f325ba9dSStephen Wilson   ///
91f05b42e9SAdrian Prantl   /// \return
92f325ba9dSStephen Wilson   ///   True if this is a 64 bit ELF file header.
Is64BitELFHeader93f325ba9dSStephen Wilson   bool Is64Bit() const {
94f325ba9dSStephen Wilson     return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
95f325ba9dSStephen Wilson   }
96f325ba9dSStephen Wilson 
97f325ba9dSStephen Wilson   /// The byte order of this ELF file header.
98f325ba9dSStephen Wilson   ///
99f05b42e9SAdrian Prantl   /// \return
100f325ba9dSStephen Wilson   ///    The byte order of this ELF file as described by the header.
101b9c1b51eSKate Stone   lldb::ByteOrder GetByteOrder() const;
102f325ba9dSStephen Wilson 
10343fe645bSStephen Wilson   /// The jump slot relocation type of this ELF.
104b9c1b51eSKate Stone   unsigned GetRelocationJumpSlotType() const;
10543fe645bSStephen Wilson 
10623ccc291SPavel Labath   /// Check if there should be header extension in section header #0
10723ccc291SPavel Labath   ///
108f05b42e9SAdrian Prantl   /// \return
10923ccc291SPavel Labath   ///    True if parsing the ELFHeader requires reading header extension
11023ccc291SPavel Labath   ///    and false otherwise.
11123ccc291SPavel Labath   bool HasHeaderExtension() const;
11223ccc291SPavel Labath 
113d8f460e8SAdrian Prantl   /// Parse an ELFHeader entry starting at position \p offset and update the
114d8f460e8SAdrian Prantl   /// data extractor with the address size and byte order attributes as
115d8f460e8SAdrian Prantl   /// defined by the header.
116f325ba9dSStephen Wilson   ///
117f05b42e9SAdrian Prantl   /// \param[in,out] data
118f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  Updated with the address size and
119f325ba9dSStephen Wilson   ///    byte order attributes appropriate to this header.
120f325ba9dSStephen Wilson   ///
121f05b42e9SAdrian Prantl   /// \param[in,out] offset
122f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
123f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
124f325ba9dSStephen Wilson   ///
125f05b42e9SAdrian Prantl   /// \return
126c836ae7dSMichael Sartain   ///    True if the ELFHeader was successfully read and false
127f325ba9dSStephen Wilson   ///    otherwise.
128b9c1b51eSKate Stone   bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
129f325ba9dSStephen Wilson 
130f325ba9dSStephen Wilson   /// Examines at most EI_NIDENT bytes starting from the given pointer and
131f325ba9dSStephen Wilson   /// determines if the magic ELF identification exists.
132f325ba9dSStephen Wilson   ///
133f05b42e9SAdrian Prantl   /// \return
134f325ba9dSStephen Wilson   ///    True if the given sequence of bytes identifies an ELF file.
135b9c1b51eSKate Stone   static bool MagicBytesMatch(const uint8_t *magic);
136f325ba9dSStephen Wilson 
137f325ba9dSStephen Wilson   /// Examines at most EI_NIDENT bytes starting from the given address and
138f325ba9dSStephen Wilson   /// determines the address size of the underlying ELF file.  This function
139f325ba9dSStephen Wilson   /// should only be called on an pointer for which MagicBytesMatch returns
140f325ba9dSStephen Wilson   /// true.
141f325ba9dSStephen Wilson   ///
142f05b42e9SAdrian Prantl   /// \return
143f325ba9dSStephen Wilson   ///    The number of bytes forming an address in the ELF file (either 4 or
144f325ba9dSStephen Wilson   ///    8), else zero if the address size could not be determined.
145b9c1b51eSKate Stone   static unsigned AddressSizeInBytes(const uint8_t *magic);
14623ccc291SPavel Labath 
14723ccc291SPavel Labath private:
14823ccc291SPavel Labath 
149d8f460e8SAdrian Prantl   /// Parse an ELFHeader header extension entry.  This method is called by
150d8f460e8SAdrian Prantl   /// Parse().
15123ccc291SPavel Labath   ///
152f05b42e9SAdrian Prantl   /// \param[in] data
15323ccc291SPavel Labath   ///    The DataExtractor to read from.
15423ccc291SPavel Labath   void ParseHeaderExtension(lldb_private::DataExtractor &data);
155f325ba9dSStephen Wilson };
156f325ba9dSStephen Wilson 
157f05b42e9SAdrian Prantl /// \class ELFSectionHeader
158d8f460e8SAdrian Prantl /// Generic representation of an ELF section header.
159b9c1b51eSKate Stone struct ELFSectionHeader {
160f325ba9dSStephen Wilson   elf_word sh_name;       ///< Section name string index.
161f325ba9dSStephen Wilson   elf_word sh_type;       ///< Section type.
162f325ba9dSStephen Wilson   elf_xword sh_flags;     ///< Section attributes.
163f325ba9dSStephen Wilson   elf_addr sh_addr;       ///< Virtual address of the section in memory.
164f325ba9dSStephen Wilson   elf_off sh_offset;      ///< Start of section from beginning of file.
165f325ba9dSStephen Wilson   elf_xword sh_size;      ///< Number of bytes occupied in the file.
166f325ba9dSStephen Wilson   elf_word sh_link;       ///< Index of associated section.
167f325ba9dSStephen Wilson   elf_word sh_info;       ///< Extra section info (overloaded).
168f325ba9dSStephen Wilson   elf_xword sh_addralign; ///< Power of two alignment constraint.
169f325ba9dSStephen Wilson   elf_xword sh_entsize;   ///< Byte size of each section entry.
170f325ba9dSStephen Wilson 
171f325ba9dSStephen Wilson   ELFSectionHeader();
172f325ba9dSStephen Wilson 
173f325ba9dSStephen Wilson   /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
174f325ba9dSStephen Wilson   /// position \p offset.
175f325ba9dSStephen Wilson   ///
176f05b42e9SAdrian Prantl   /// \param[in] data
177f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
178f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
179f325ba9dSStephen Wilson   ///
180f05b42e9SAdrian Prantl   /// \param[in,out] offset
181f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
182f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
183f325ba9dSStephen Wilson   ///
184f05b42e9SAdrian Prantl   /// \return
185f325ba9dSStephen Wilson   ///    True if the ELFSectionHeader was successfully read and false
186f325ba9dSStephen Wilson   ///    otherwise.
187b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
188f325ba9dSStephen Wilson };
189f325ba9dSStephen Wilson 
190f05b42e9SAdrian Prantl /// \class ELFProgramHeader
191d8f460e8SAdrian Prantl /// Generic representation of an ELF program header.
192b9c1b51eSKate Stone struct ELFProgramHeader {
193710dd5aeSGreg Clayton   elf_word p_type;    ///< Type of program segment.
194710dd5aeSGreg Clayton   elf_word p_flags;   ///< Segment attributes.
195710dd5aeSGreg Clayton   elf_off p_offset;   ///< Start of segment from beginning of file.
196f325ba9dSStephen Wilson   elf_addr p_vaddr;   ///< Virtual address of segment in memory.
197f325ba9dSStephen Wilson   elf_addr p_paddr;   ///< Physical address (for non-VM systems).
198f325ba9dSStephen Wilson   elf_xword p_filesz; ///< Byte size of the segment in file.
199f325ba9dSStephen Wilson   elf_xword p_memsz;  ///< Byte size of the segment in memory.
200710dd5aeSGreg Clayton   elf_xword p_align;  ///< Segment alignment constraint.
201f325ba9dSStephen Wilson 
202f325ba9dSStephen Wilson   ELFProgramHeader();
203f325ba9dSStephen Wilson 
204710dd5aeSGreg Clayton   /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
205710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
206f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
207f325ba9dSStephen Wilson   ///
208f05b42e9SAdrian Prantl   /// \param[in] data
209f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
210f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
211f325ba9dSStephen Wilson   ///
212f05b42e9SAdrian Prantl   /// \param[in,out] offset
213f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
214f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
215f325ba9dSStephen Wilson   ///
216f05b42e9SAdrian Prantl   /// \return
217f325ba9dSStephen Wilson   ///    True if the ELFProgramHeader was successfully read and false
218f325ba9dSStephen Wilson   ///    otherwise.
219b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
220f325ba9dSStephen Wilson };
221f325ba9dSStephen Wilson 
222f05b42e9SAdrian Prantl /// \class ELFSymbol
223d8f460e8SAdrian Prantl /// Represents a symbol within an ELF symbol table.
224b9c1b51eSKate Stone struct ELFSymbol {
225f325ba9dSStephen Wilson   elf_addr st_value;      ///< Absolute or relocatable address.
226f325ba9dSStephen Wilson   elf_xword st_size;      ///< Size of the symbol or zero.
227f325ba9dSStephen Wilson   elf_word st_name;       ///< Symbol name string index.
228f325ba9dSStephen Wilson   unsigned char st_info;  ///< Symbol type and binding attributes.
229f325ba9dSStephen Wilson   unsigned char st_other; ///< Reserved for future use.
230f325ba9dSStephen Wilson   elf_half st_shndx;      ///< Section to which this symbol applies.
231f325ba9dSStephen Wilson 
232f325ba9dSStephen Wilson   ELFSymbol();
233f325ba9dSStephen Wilson 
234f325ba9dSStephen Wilson   /// Returns the binding attribute of the st_info member.
getBindingELFSymbol235f325ba9dSStephen Wilson   unsigned char getBinding() const { return st_info >> 4; }
236f325ba9dSStephen Wilson 
237f325ba9dSStephen Wilson   /// Returns the type attribute of the st_info member.
getTypeELFSymbol238f325ba9dSStephen Wilson   unsigned char getType() const { return st_info & 0x0F; }
239f325ba9dSStephen Wilson 
240710dd5aeSGreg Clayton   /// Sets the binding and type of the st_info member.
setBindingAndTypeELFSymbol241f325ba9dSStephen Wilson   void setBindingAndType(unsigned char binding, unsigned char type) {
242f325ba9dSStephen Wilson     st_info = (binding << 4) + (type & 0x0F);
243f325ba9dSStephen Wilson   }
244f325ba9dSStephen Wilson 
245b9c1b51eSKate Stone   static const char *bindingToCString(unsigned char binding);
2469594f4c8SGreg Clayton 
247b9c1b51eSKate Stone   static const char *typeToCString(unsigned char type);
2489594f4c8SGreg Clayton 
2499594f4c8SGreg Clayton   static const char *
2509594f4c8SGreg Clayton   sectionIndexToCString(elf_half shndx,
2519594f4c8SGreg Clayton                         const lldb_private::SectionList *section_list);
2529594f4c8SGreg Clayton 
253710dd5aeSGreg Clayton   /// Parse an ELFSymbol entry from the given DataExtractor starting at
254710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
255f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
256f325ba9dSStephen Wilson   ///
257f05b42e9SAdrian Prantl   /// \param[in] data
258f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
259f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
260f325ba9dSStephen Wilson   ///
261f05b42e9SAdrian Prantl   /// \param[in,out] offset
262f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
263f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
264f325ba9dSStephen Wilson   ///
265f05b42e9SAdrian Prantl   /// \return
266f325ba9dSStephen Wilson   ///    True if the ELFSymbol was successfully read and false otherwise.
267b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
2689594f4c8SGreg Clayton 
269b9c1b51eSKate Stone   void Dump(lldb_private::Stream *s, uint32_t idx,
2709594f4c8SGreg Clayton             const lldb_private::DataExtractor *strtab_data,
2719594f4c8SGreg Clayton             const lldb_private::SectionList *section_list);
272f325ba9dSStephen Wilson };
273f325ba9dSStephen Wilson 
274f05b42e9SAdrian Prantl /// \class ELFDynamic
275d8f460e8SAdrian Prantl /// Represents an entry in an ELF dynamic table.
276b9c1b51eSKate Stone struct ELFDynamic {
277f325ba9dSStephen Wilson   elf_sxword d_tag; ///< Type of dynamic table entry.
278b9c1b51eSKate Stone   union {
279f325ba9dSStephen Wilson     elf_xword d_val; ///< Integer value of the table entry.
280f325ba9dSStephen Wilson     elf_addr d_ptr;  ///< Pointer value of the table entry.
281f325ba9dSStephen Wilson   };
282f325ba9dSStephen Wilson 
283f325ba9dSStephen Wilson   ELFDynamic();
284f325ba9dSStephen Wilson 
285710dd5aeSGreg Clayton   /// Parse an ELFDynamic entry from the given DataExtractor starting at
286710dd5aeSGreg Clayton   /// position \p offset.  The address size of the DataExtractor determines if
287f325ba9dSStephen Wilson   /// a 32 or 64 bit object is to be parsed.
288f325ba9dSStephen Wilson   ///
289f05b42e9SAdrian Prantl   /// \param[in] data
290f325ba9dSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
291f325ba9dSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
292f325ba9dSStephen Wilson   ///
293f05b42e9SAdrian Prantl   /// \param[in,out] offset
294f325ba9dSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
295f325ba9dSStephen Wilson   ///    advanced by the number of bytes read.
296f325ba9dSStephen Wilson   ///
297f05b42e9SAdrian Prantl   /// \return
298f325ba9dSStephen Wilson   ///    True if the ELFDynamic entry was successfully read and false
299f325ba9dSStephen Wilson   ///    otherwise.
300b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
301f325ba9dSStephen Wilson };
302f325ba9dSStephen Wilson 
303f05b42e9SAdrian Prantl /// \class ELFRel
304d8f460e8SAdrian Prantl /// Represents a relocation entry with an implicit addend.
305b9c1b51eSKate Stone struct ELFRel {
30643fe645bSStephen Wilson   elf_addr r_offset; ///< Address of reference.
30743fe645bSStephen Wilson   elf_xword r_info;  ///< symbol index and type of relocation.
30843fe645bSStephen Wilson 
30943fe645bSStephen Wilson   ELFRel();
31043fe645bSStephen Wilson 
31143fe645bSStephen Wilson   /// Parse an ELFRel entry from the given DataExtractor starting at position
31243fe645bSStephen Wilson   /// \p offset.  The address size of the DataExtractor determines if a 32 or
31343fe645bSStephen Wilson   /// 64 bit object is to be parsed.
31443fe645bSStephen Wilson   ///
315f05b42e9SAdrian Prantl   /// \param[in] data
31643fe645bSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
31743fe645bSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
31843fe645bSStephen Wilson   ///
319f05b42e9SAdrian Prantl   /// \param[in,out] offset
32043fe645bSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
32143fe645bSStephen Wilson   ///    advanced by the number of bytes read.
32243fe645bSStephen Wilson   ///
323f05b42e9SAdrian Prantl   /// \return
32443fe645bSStephen Wilson   ///    True if the ELFRel entry was successfully read and false otherwise.
325b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
32643fe645bSStephen Wilson 
32743fe645bSStephen Wilson   /// Returns the type when the given entry represents a 32-bit relocation.
RelocType32ELFRel328b9c1b51eSKate Stone   static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }
32943fe645bSStephen Wilson 
33043fe645bSStephen Wilson   /// Returns the type when the given entry represents a 64-bit relocation.
RelocType64ELFRel331b9c1b51eSKate Stone   static unsigned RelocType64(const ELFRel &rel) {
33243fe645bSStephen Wilson     return rel.r_info & 0xffffffff;
33343fe645bSStephen Wilson   }
33443fe645bSStephen Wilson 
33543fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 32-bit
336aaa0ba31SBruce Mitchener   /// relocation.
RelocSymbol32ELFRel337b9c1b51eSKate Stone   static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }
33843fe645bSStephen Wilson 
33943fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 64-bit
340aaa0ba31SBruce Mitchener   /// relocation.
RelocSymbol64ELFRel341b9c1b51eSKate Stone   static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }
34243fe645bSStephen Wilson };
34343fe645bSStephen Wilson 
344f05b42e9SAdrian Prantl /// \class ELFRela
345d8f460e8SAdrian Prantl /// Represents a relocation entry with an explicit addend.
346b9c1b51eSKate Stone struct ELFRela {
34743fe645bSStephen Wilson   elf_addr r_offset;   ///< Address of reference.
34843fe645bSStephen Wilson   elf_xword r_info;    ///< Symbol index and type of relocation.
34943fe645bSStephen Wilson   elf_sxword r_addend; ///< Constant part of expression.
35043fe645bSStephen Wilson 
35143fe645bSStephen Wilson   ELFRela();
35243fe645bSStephen Wilson 
35343fe645bSStephen Wilson   /// Parse an ELFRela entry from the given DataExtractor starting at position
35443fe645bSStephen Wilson   /// \p offset.  The address size of the DataExtractor determines if a 32 or
35543fe645bSStephen Wilson   /// 64 bit object is to be parsed.
35643fe645bSStephen Wilson   ///
357f05b42e9SAdrian Prantl   /// \param[in] data
35843fe645bSStephen Wilson   ///    The DataExtractor to read from.  The address size of the extractor
35943fe645bSStephen Wilson   ///    determines if a 32 or 64 bit object should be read.
36043fe645bSStephen Wilson   ///
361f05b42e9SAdrian Prantl   /// \param[in,out] offset
36243fe645bSStephen Wilson   ///    Pointer to an offset in the data.  On return the offset will be
36343fe645bSStephen Wilson   ///    advanced by the number of bytes read.
36443fe645bSStephen Wilson   ///
365f05b42e9SAdrian Prantl   /// \return
36643fe645bSStephen Wilson   ///    True if the ELFRela entry was successfully read and false otherwise.
367b9c1b51eSKate Stone   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
36843fe645bSStephen Wilson 
36943fe645bSStephen Wilson   /// Returns the type when the given entry represents a 32-bit relocation.
RelocType32ELFRela370b9c1b51eSKate Stone   static unsigned RelocType32(const ELFRela &rela) {
37143fe645bSStephen Wilson     return rela.r_info & 0x0ff;
37243fe645bSStephen Wilson   }
37343fe645bSStephen Wilson 
37443fe645bSStephen Wilson   /// Returns the type when the given entry represents a 64-bit relocation.
RelocType64ELFRela375b9c1b51eSKate Stone   static unsigned RelocType64(const ELFRela &rela) {
37643fe645bSStephen Wilson     return rela.r_info & 0xffffffff;
37743fe645bSStephen Wilson   }
37843fe645bSStephen Wilson 
37943fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 32-bit
380aaa0ba31SBruce Mitchener   /// relocation.
RelocSymbol32ELFRela381b9c1b51eSKate Stone   static unsigned RelocSymbol32(const ELFRela &rela) {
38243fe645bSStephen Wilson     return rela.r_info >> 8;
38343fe645bSStephen Wilson   }
38443fe645bSStephen Wilson 
38543fe645bSStephen Wilson   /// Returns the symbol index when the given entry represents a 64-bit
386aaa0ba31SBruce Mitchener   /// relocation.
RelocSymbol64ELFRela387b9c1b51eSKate Stone   static unsigned RelocSymbol64(const ELFRela &rela) {
38843fe645bSStephen Wilson     return rela.r_info >> 32;
38943fe645bSStephen Wilson   }
39043fe645bSStephen Wilson };
39143fe645bSStephen Wilson 
392f325ba9dSStephen Wilson } // End namespace elf.
393f325ba9dSStephen Wilson 
394*cdc514e4SJonas Devlieghere #endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
395