1f325ba9dSStephen Wilson //===-- ELFHeader.cpp ----------------------------------------- -*- 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 #include <cstring>
11f325ba9dSStephen Wilson 
12f325ba9dSStephen Wilson #include "lldb/Core/DataExtractor.h"
139594f4c8SGreg Clayton #include "lldb/Core/Section.h"
149594f4c8SGreg Clayton #include "lldb/Core/Stream.h"
15f325ba9dSStephen Wilson 
16f325ba9dSStephen Wilson #include "ELFHeader.h"
17f325ba9dSStephen Wilson 
18f325ba9dSStephen Wilson using namespace elf;
19f325ba9dSStephen Wilson using namespace lldb;
20f325ba9dSStephen Wilson using namespace llvm::ELF;
21f325ba9dSStephen Wilson 
22f325ba9dSStephen Wilson //------------------------------------------------------------------------------
23f325ba9dSStephen Wilson // Static utility functions.
24f325ba9dSStephen Wilson //
25f325ba9dSStephen Wilson // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
26f325ba9dSStephen Wilson // with error handling code and provide for parsing a sequence of values.
27f325ba9dSStephen Wilson static bool
28f325ba9dSStephen Wilson GetMaxU64(const lldb_private::DataExtractor &data,
29c7bece56SGreg Clayton           lldb::offset_t *offset,
30c7bece56SGreg Clayton           uint64_t *value,
31c7bece56SGreg Clayton           uint32_t byte_size)
32f325ba9dSStephen Wilson {
33c7bece56SGreg Clayton     const lldb::offset_t saved_offset = *offset;
34f325ba9dSStephen Wilson     *value = data.GetMaxU64(offset, byte_size);
35f325ba9dSStephen Wilson     return *offset != saved_offset;
36f325ba9dSStephen Wilson }
37f325ba9dSStephen Wilson 
38f325ba9dSStephen Wilson static bool
39f325ba9dSStephen Wilson GetMaxU64(const lldb_private::DataExtractor &data,
40c7bece56SGreg Clayton           lldb::offset_t *offset,
41c7bece56SGreg Clayton           uint64_t *value,
42c7bece56SGreg Clayton           uint32_t byte_size,
43f325ba9dSStephen Wilson           uint32_t count)
44f325ba9dSStephen Wilson {
45c7bece56SGreg Clayton     lldb::offset_t saved_offset = *offset;
46f325ba9dSStephen Wilson 
47f325ba9dSStephen Wilson     for (uint32_t i = 0; i < count; ++i, ++value)
48f325ba9dSStephen Wilson     {
49f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, value, byte_size) == false)
50f325ba9dSStephen Wilson         {
51f325ba9dSStephen Wilson             *offset = saved_offset;
52f325ba9dSStephen Wilson             return false;
53f325ba9dSStephen Wilson         }
54f325ba9dSStephen Wilson     }
55f325ba9dSStephen Wilson     return true;
56f325ba9dSStephen Wilson }
57f325ba9dSStephen Wilson 
58f325ba9dSStephen Wilson static bool
59f325ba9dSStephen Wilson GetMaxS64(const lldb_private::DataExtractor &data,
60c7bece56SGreg Clayton           lldb::offset_t *offset,
61c7bece56SGreg Clayton           int64_t *value,
62c7bece56SGreg Clayton           uint32_t byte_size)
63f325ba9dSStephen Wilson {
64c7bece56SGreg Clayton     const lldb::offset_t saved_offset = *offset;
65f325ba9dSStephen Wilson     *value = data.GetMaxS64(offset, byte_size);
66f325ba9dSStephen Wilson     return *offset != saved_offset;
67f325ba9dSStephen Wilson }
68f325ba9dSStephen Wilson 
69f325ba9dSStephen Wilson static bool
70f325ba9dSStephen Wilson GetMaxS64(const lldb_private::DataExtractor &data,
71c7bece56SGreg Clayton           lldb::offset_t *offset,
72c7bece56SGreg Clayton           int64_t *value,
73c7bece56SGreg Clayton           uint32_t byte_size,
74f325ba9dSStephen Wilson           uint32_t count)
75f325ba9dSStephen Wilson {
76c7bece56SGreg Clayton     lldb::offset_t saved_offset = *offset;
77f325ba9dSStephen Wilson 
78f325ba9dSStephen Wilson     for (uint32_t i = 0; i < count; ++i, ++value)
79f325ba9dSStephen Wilson     {
80f325ba9dSStephen Wilson         if (GetMaxS64(data, offset, value, byte_size) == false)
81f325ba9dSStephen Wilson         {
82f325ba9dSStephen Wilson             *offset = saved_offset;
83f325ba9dSStephen Wilson             return false;
84f325ba9dSStephen Wilson         }
85f325ba9dSStephen Wilson     }
86f325ba9dSStephen Wilson     return true;
87f325ba9dSStephen Wilson }
88f325ba9dSStephen Wilson 
89f325ba9dSStephen Wilson //------------------------------------------------------------------------------
90f325ba9dSStephen Wilson // ELFHeader
91f325ba9dSStephen Wilson 
92f325ba9dSStephen Wilson ELFHeader::ELFHeader()
93f325ba9dSStephen Wilson {
94f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFHeader));
95f325ba9dSStephen Wilson }
96f325ba9dSStephen Wilson 
97f325ba9dSStephen Wilson ByteOrder
98f325ba9dSStephen Wilson ELFHeader::GetByteOrder() const
99f325ba9dSStephen Wilson {
100f325ba9dSStephen Wilson     if (e_ident[EI_DATA] == ELFDATA2MSB)
101f325ba9dSStephen Wilson         return eByteOrderBig;
102f325ba9dSStephen Wilson     if (e_ident[EI_DATA] == ELFDATA2LSB)
103f325ba9dSStephen Wilson         return eByteOrderLittle;
104f325ba9dSStephen Wilson     return eByteOrderInvalid;
105f325ba9dSStephen Wilson }
106f325ba9dSStephen Wilson 
107f325ba9dSStephen Wilson bool
108c7bece56SGreg Clayton ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)
109f325ba9dSStephen Wilson {
110f325ba9dSStephen Wilson     // Read e_ident.  This provides byte order and address size info.
111f325ba9dSStephen Wilson     if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
112f325ba9dSStephen Wilson         return false;
113f325ba9dSStephen Wilson 
114f325ba9dSStephen Wilson     const unsigned byte_size = Is32Bit() ? 4 : 8;
115f325ba9dSStephen Wilson     data.SetByteOrder(GetByteOrder());
116f325ba9dSStephen Wilson     data.SetAddressByteSize(byte_size);
117f325ba9dSStephen Wilson 
118f325ba9dSStephen Wilson     // Read e_type and e_machine.
119f325ba9dSStephen Wilson     if (data.GetU16(offset, &e_type, 2) == NULL)
120f325ba9dSStephen Wilson         return false;
121f325ba9dSStephen Wilson 
122f325ba9dSStephen Wilson     // Read e_version.
123f325ba9dSStephen Wilson     if (data.GetU32(offset, &e_version, 1) == NULL)
124f325ba9dSStephen Wilson         return false;
125f325ba9dSStephen Wilson 
126f325ba9dSStephen Wilson     // Read e_entry, e_phoff and e_shoff.
127f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
128f325ba9dSStephen Wilson         return false;
129f325ba9dSStephen Wilson 
130f325ba9dSStephen Wilson     // Read e_flags.
131f325ba9dSStephen Wilson     if (data.GetU32(offset, &e_flags, 1) == NULL)
132f325ba9dSStephen Wilson         return false;
133f325ba9dSStephen Wilson 
134f325ba9dSStephen Wilson     // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
135f325ba9dSStephen Wilson     // e_shstrndx.
136f325ba9dSStephen Wilson     if (data.GetU16(offset, &e_ehsize, 6) == NULL)
137f325ba9dSStephen Wilson         return false;
138f325ba9dSStephen Wilson 
139f325ba9dSStephen Wilson     return true;
140f325ba9dSStephen Wilson }
141f325ba9dSStephen Wilson 
142f325ba9dSStephen Wilson bool
143f325ba9dSStephen Wilson ELFHeader::MagicBytesMatch(const uint8_t *magic)
144f325ba9dSStephen Wilson {
145f325ba9dSStephen Wilson     return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
146f325ba9dSStephen Wilson }
147f325ba9dSStephen Wilson 
148f325ba9dSStephen Wilson unsigned
149f325ba9dSStephen Wilson ELFHeader::AddressSizeInBytes(const uint8_t *magic)
150f325ba9dSStephen Wilson {
151f325ba9dSStephen Wilson     unsigned address_size = 0;
152f325ba9dSStephen Wilson 
153f325ba9dSStephen Wilson     switch (magic[EI_CLASS])
154f325ba9dSStephen Wilson     {
155f325ba9dSStephen Wilson     case ELFCLASS32:
156f325ba9dSStephen Wilson         address_size = 4;
157f325ba9dSStephen Wilson         break;
158f325ba9dSStephen Wilson 
159f325ba9dSStephen Wilson     case ELFCLASS64:
160f325ba9dSStephen Wilson         address_size = 8;
161f325ba9dSStephen Wilson         break;
162f325ba9dSStephen Wilson     }
163f325ba9dSStephen Wilson     return address_size;
164f325ba9dSStephen Wilson }
165f325ba9dSStephen Wilson 
16643fe645bSStephen Wilson unsigned
16743fe645bSStephen Wilson ELFHeader::GetRelocationJumpSlotType() const
16843fe645bSStephen Wilson {
16943fe645bSStephen Wilson     unsigned slot = 0;
17043fe645bSStephen Wilson 
17143fe645bSStephen Wilson     switch (e_machine)
17243fe645bSStephen Wilson     {
17343fe645bSStephen Wilson     default:
17443fe645bSStephen Wilson         assert(false && "architecture not supported");
17543fe645bSStephen Wilson         break;
1766256a0eaSJustin Hibbits     case EM_PPC:
1776256a0eaSJustin Hibbits         slot = R_PPC_JMP_SLOT;
1786256a0eaSJustin Hibbits         break;
1796256a0eaSJustin Hibbits     case EM_PPC64:
1806256a0eaSJustin Hibbits         slot = R_PPC64_JMP_SLOT;
1816256a0eaSJustin Hibbits         break;
18243fe645bSStephen Wilson     case EM_386:
18386f422e1SRafael Espindola     case EM_IAMCU: // FIXME: is this correct?
18443fe645bSStephen Wilson         slot = R_386_JUMP_SLOT;
18543fe645bSStephen Wilson         break;
18643fe645bSStephen Wilson     case EM_X86_64:
18743fe645bSStephen Wilson         slot = R_X86_64_JUMP_SLOT;
18843fe645bSStephen Wilson         break;
18943fe645bSStephen Wilson     case EM_ARM:
19043fe645bSStephen Wilson         slot = R_ARM_JUMP_SLOT;
19143fe645bSStephen Wilson         break;
192ca238a7bSDeepak Panickal     case EM_HEXAGON:
193ca238a7bSDeepak Panickal         slot = R_HEX_JMP_SLOT;
194ca238a7bSDeepak Panickal         break;
19533bba9f4STodd Fiala     case EM_AARCH64:
19633bba9f4STodd Fiala         slot = R_AARCH64_JUMP_SLOT;
19733bba9f4STodd Fiala         break;
198c9335a3fSMohit K. Bhakkad     case EM_MIPS:
199c9335a3fSMohit K. Bhakkad         slot = R_MIPS_JUMP_SLOT;
200c9335a3fSMohit K. Bhakkad         break;
20143fe645bSStephen Wilson     }
20243fe645bSStephen Wilson 
20343fe645bSStephen Wilson     return slot;
20443fe645bSStephen Wilson }
20543fe645bSStephen Wilson 
206f325ba9dSStephen Wilson //------------------------------------------------------------------------------
207f325ba9dSStephen Wilson // ELFSectionHeader
208f325ba9dSStephen Wilson 
209f325ba9dSStephen Wilson ELFSectionHeader::ELFSectionHeader()
210f325ba9dSStephen Wilson {
211f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFSectionHeader));
212f325ba9dSStephen Wilson }
213f325ba9dSStephen Wilson 
214f325ba9dSStephen Wilson bool
215f325ba9dSStephen Wilson ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
216c7bece56SGreg Clayton                         lldb::offset_t *offset)
217f325ba9dSStephen Wilson {
218f325ba9dSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
219f325ba9dSStephen Wilson 
220f325ba9dSStephen Wilson     // Read sh_name and sh_type.
221f325ba9dSStephen Wilson     if (data.GetU32(offset, &sh_name, 2) == NULL)
222f325ba9dSStephen Wilson         return false;
223f325ba9dSStephen Wilson 
224f325ba9dSStephen Wilson     // Read sh_flags.
225f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
226f325ba9dSStephen Wilson         return false;
227f325ba9dSStephen Wilson 
228f325ba9dSStephen Wilson     // Read sh_addr, sh_off and sh_size.
229f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
230f325ba9dSStephen Wilson         return false;
231f325ba9dSStephen Wilson 
232f325ba9dSStephen Wilson     // Read sh_link and sh_info.
233f325ba9dSStephen Wilson     if (data.GetU32(offset, &sh_link, 2) == NULL)
234f325ba9dSStephen Wilson         return false;
235f325ba9dSStephen Wilson 
236f325ba9dSStephen Wilson     // Read sh_addralign and sh_entsize.
237f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
238f325ba9dSStephen Wilson         return false;
239f325ba9dSStephen Wilson 
240f325ba9dSStephen Wilson     return true;
241f325ba9dSStephen Wilson }
242f325ba9dSStephen Wilson 
243f325ba9dSStephen Wilson //------------------------------------------------------------------------------
244f325ba9dSStephen Wilson // ELFSymbol
245f325ba9dSStephen Wilson 
246f325ba9dSStephen Wilson ELFSymbol::ELFSymbol()
247f325ba9dSStephen Wilson {
248f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFSymbol));
249f325ba9dSStephen Wilson }
250f325ba9dSStephen Wilson 
2519594f4c8SGreg Clayton #define ENUM_TO_CSTR(e) case e: return #e
2529594f4c8SGreg Clayton 
2539594f4c8SGreg Clayton const char *
2549594f4c8SGreg Clayton ELFSymbol::bindingToCString(unsigned char binding)
2559594f4c8SGreg Clayton {
2569594f4c8SGreg Clayton     switch (binding)
2579594f4c8SGreg Clayton     {
2589594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_LOCAL);
2599594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_GLOBAL);
2609594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_WEAK);
2619594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_LOOS);
2629594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_HIOS);
2639594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_LOPROC);
2649594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_HIPROC);
2659594f4c8SGreg Clayton     }
2669594f4c8SGreg Clayton     return "";
2679594f4c8SGreg Clayton }
2689594f4c8SGreg Clayton 
2699594f4c8SGreg Clayton const char *
2709594f4c8SGreg Clayton ELFSymbol::typeToCString(unsigned char type)
2719594f4c8SGreg Clayton {
2729594f4c8SGreg Clayton     switch (type)
2739594f4c8SGreg Clayton     {
2749594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_NOTYPE);
2759594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_OBJECT);
2769594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_FUNC);
2779594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_SECTION);
2789594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_FILE);
2799594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_COMMON);
2809594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_TLS);
2819594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_GNU_IFUNC);
282*a6d0dd74SPavel Labath     ENUM_TO_CSTR(STT_HIOS);
2839594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_LOPROC);
2849594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_HIPROC);
2859594f4c8SGreg Clayton     }
2869594f4c8SGreg Clayton     return "";
2879594f4c8SGreg Clayton }
2889594f4c8SGreg Clayton 
2899594f4c8SGreg Clayton const char *
2909594f4c8SGreg Clayton ELFSymbol::sectionIndexToCString (elf_half shndx,
2919594f4c8SGreg Clayton                                   const lldb_private::SectionList *section_list)
2929594f4c8SGreg Clayton {
2939594f4c8SGreg Clayton     switch (shndx)
2949594f4c8SGreg Clayton     {
2959594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_UNDEF);
2969594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_LOPROC);
2979594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_HIPROC);
2989594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_LOOS);
2999594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_HIOS);
3009594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_ABS);
3019594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_COMMON);
3029594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_XINDEX);
3039594f4c8SGreg Clayton     default:
3049594f4c8SGreg Clayton         {
3059594f4c8SGreg Clayton             const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get();
3069594f4c8SGreg Clayton             if (section)
3079594f4c8SGreg Clayton                 return section->GetName().AsCString("");
3089594f4c8SGreg Clayton         }
3099594f4c8SGreg Clayton         break;
3109594f4c8SGreg Clayton     }
3119594f4c8SGreg Clayton     return "";
3129594f4c8SGreg Clayton }
3139594f4c8SGreg Clayton 
3149594f4c8SGreg Clayton void
3159594f4c8SGreg Clayton ELFSymbol::Dump (lldb_private::Stream *s,
3169594f4c8SGreg Clayton                  uint32_t idx,
3179594f4c8SGreg Clayton                  const lldb_private::DataExtractor *strtab_data,
3189594f4c8SGreg Clayton                  const lldb_private::SectionList *section_list)
3199594f4c8SGreg Clayton {
320ef14371dSMatt Kopec     s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n",
3219594f4c8SGreg Clayton               idx,
3229594f4c8SGreg Clayton               st_value,
3239594f4c8SGreg Clayton               st_size,
3249594f4c8SGreg Clayton               st_name,
3259594f4c8SGreg Clayton               st_info,
3269594f4c8SGreg Clayton               bindingToCString (getBinding()),
3279594f4c8SGreg Clayton               typeToCString (getType()),
3289594f4c8SGreg Clayton               st_other,
3299594f4c8SGreg Clayton               st_shndx,
3309594f4c8SGreg Clayton               sectionIndexToCString (st_shndx, section_list),
3319594f4c8SGreg Clayton               strtab_data ? strtab_data->PeekCStr(st_name) : "");
3329594f4c8SGreg Clayton }
3339594f4c8SGreg Clayton 
334f325ba9dSStephen Wilson bool
335c7bece56SGreg Clayton ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
336f325ba9dSStephen Wilson {
337f325ba9dSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
338f325ba9dSStephen Wilson     const bool parsing_32 = byte_size == 4;
339f325ba9dSStephen Wilson 
340f325ba9dSStephen Wilson     // Read st_name.
341f325ba9dSStephen Wilson     if (data.GetU32(offset, &st_name, 1) == NULL)
342f325ba9dSStephen Wilson         return false;
343f325ba9dSStephen Wilson 
344f325ba9dSStephen Wilson     if (parsing_32)
345f325ba9dSStephen Wilson     {
346f325ba9dSStephen Wilson         // Read st_value and st_size.
347f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
348f325ba9dSStephen Wilson             return false;
349f325ba9dSStephen Wilson 
350f325ba9dSStephen Wilson         // Read st_info and st_other.
351f325ba9dSStephen Wilson         if (data.GetU8(offset, &st_info, 2) == NULL)
352f325ba9dSStephen Wilson             return false;
353f325ba9dSStephen Wilson 
354f325ba9dSStephen Wilson         // Read st_shndx.
355f325ba9dSStephen Wilson         if (data.GetU16(offset, &st_shndx, 1) == NULL)
356f325ba9dSStephen Wilson             return false;
357f325ba9dSStephen Wilson     }
358f325ba9dSStephen Wilson     else
359f325ba9dSStephen Wilson     {
360f325ba9dSStephen Wilson         // Read st_info and st_other.
361f325ba9dSStephen Wilson         if (data.GetU8(offset, &st_info, 2) == NULL)
362f325ba9dSStephen Wilson             return false;
363f325ba9dSStephen Wilson 
364f325ba9dSStephen Wilson         // Read st_shndx.
365f325ba9dSStephen Wilson         if (data.GetU16(offset, &st_shndx, 1) == NULL)
366f325ba9dSStephen Wilson             return false;
367f325ba9dSStephen Wilson 
368f325ba9dSStephen Wilson         // Read st_value and st_size.
369f325ba9dSStephen Wilson         if (data.GetU64(offset, &st_value, 2) == NULL)
370f325ba9dSStephen Wilson             return false;
371f325ba9dSStephen Wilson     }
372f325ba9dSStephen Wilson     return true;
373f325ba9dSStephen Wilson }
374f325ba9dSStephen Wilson 
375f325ba9dSStephen Wilson //------------------------------------------------------------------------------
376f325ba9dSStephen Wilson // ELFProgramHeader
377f325ba9dSStephen Wilson 
378f325ba9dSStephen Wilson ELFProgramHeader::ELFProgramHeader()
379f325ba9dSStephen Wilson {
380f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFProgramHeader));
381f325ba9dSStephen Wilson }
382f325ba9dSStephen Wilson 
383f325ba9dSStephen Wilson bool
384f325ba9dSStephen Wilson ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
385c7bece56SGreg Clayton                         lldb::offset_t *offset)
386f325ba9dSStephen Wilson {
387f325ba9dSStephen Wilson     const uint32_t byte_size = data.GetAddressByteSize();
388f325ba9dSStephen Wilson     const bool parsing_32 = byte_size == 4;
389f325ba9dSStephen Wilson 
390f325ba9dSStephen Wilson     // Read p_type;
391f325ba9dSStephen Wilson     if (data.GetU32(offset, &p_type, 1) == NULL)
392f325ba9dSStephen Wilson         return false;
393f325ba9dSStephen Wilson 
394f325ba9dSStephen Wilson     if (parsing_32) {
395f325ba9dSStephen Wilson         // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
396f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
397f325ba9dSStephen Wilson             return false;
398f325ba9dSStephen Wilson 
399f325ba9dSStephen Wilson         // Read p_flags.
400f325ba9dSStephen Wilson         if (data.GetU32(offset, &p_flags, 1) == NULL)
401f325ba9dSStephen Wilson             return false;
402f325ba9dSStephen Wilson 
403f325ba9dSStephen Wilson         // Read p_align.
404f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &p_align, byte_size) == false)
405f325ba9dSStephen Wilson             return false;
406f325ba9dSStephen Wilson     }
407f325ba9dSStephen Wilson     else {
408f325ba9dSStephen Wilson         // Read p_flags.
409f325ba9dSStephen Wilson         if (data.GetU32(offset, &p_flags, 1) == NULL)
410f325ba9dSStephen Wilson             return false;
411f325ba9dSStephen Wilson 
412f325ba9dSStephen Wilson         // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
413f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
414f325ba9dSStephen Wilson             return false;
415f325ba9dSStephen Wilson     }
416f325ba9dSStephen Wilson 
417f325ba9dSStephen Wilson     return true;
418f325ba9dSStephen Wilson }
419f325ba9dSStephen Wilson 
420f325ba9dSStephen Wilson //------------------------------------------------------------------------------
421f325ba9dSStephen Wilson // ELFDynamic
422f325ba9dSStephen Wilson 
423f325ba9dSStephen Wilson ELFDynamic::ELFDynamic()
424f325ba9dSStephen Wilson {
425f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFDynamic));
426f325ba9dSStephen Wilson }
427f325ba9dSStephen Wilson 
428f325ba9dSStephen Wilson bool
429c7bece56SGreg Clayton ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
430f325ba9dSStephen Wilson {
431f325ba9dSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
432f325ba9dSStephen Wilson     return GetMaxS64(data, offset, &d_tag, byte_size, 2);
433f325ba9dSStephen Wilson }
434f325ba9dSStephen Wilson 
43543fe645bSStephen Wilson //------------------------------------------------------------------------------
43643fe645bSStephen Wilson // ELFRel
43743fe645bSStephen Wilson 
43843fe645bSStephen Wilson ELFRel::ELFRel()
43943fe645bSStephen Wilson {
44043fe645bSStephen Wilson     memset(this, 0, sizeof(ELFRel));
44143fe645bSStephen Wilson }
44243fe645bSStephen Wilson 
44343fe645bSStephen Wilson bool
444c7bece56SGreg Clayton ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
44543fe645bSStephen Wilson {
44643fe645bSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
44743fe645bSStephen Wilson 
44843fe645bSStephen Wilson     // Read r_offset and r_info.
44943fe645bSStephen Wilson     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
45043fe645bSStephen Wilson         return false;
45143fe645bSStephen Wilson 
45243fe645bSStephen Wilson     return true;
45343fe645bSStephen Wilson }
45443fe645bSStephen Wilson 
45543fe645bSStephen Wilson //------------------------------------------------------------------------------
45643fe645bSStephen Wilson // ELFRela
45743fe645bSStephen Wilson 
45843fe645bSStephen Wilson ELFRela::ELFRela()
45943fe645bSStephen Wilson {
46043fe645bSStephen Wilson     memset(this, 0, sizeof(ELFRela));
46143fe645bSStephen Wilson }
46243fe645bSStephen Wilson 
46343fe645bSStephen Wilson bool
464c7bece56SGreg Clayton ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
46543fe645bSStephen Wilson {
46643fe645bSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
46743fe645bSStephen Wilson 
46843fe645bSStephen Wilson     // Read r_offset and r_info.
46943fe645bSStephen Wilson     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
47043fe645bSStephen Wilson         return false;
47143fe645bSStephen Wilson 
47243fe645bSStephen Wilson     // Read r_addend;
47343fe645bSStephen Wilson     if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
47443fe645bSStephen Wilson         return false;
47543fe645bSStephen Wilson 
47643fe645bSStephen Wilson     return true;
47743fe645bSStephen Wilson }
47843fe645bSStephen Wilson 
479f325ba9dSStephen Wilson 
480