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;
17643fe645bSStephen Wilson     case EM_386:
17743fe645bSStephen Wilson     case EM_486:
17843fe645bSStephen Wilson         slot = R_386_JUMP_SLOT;
17943fe645bSStephen Wilson         break;
18043fe645bSStephen Wilson     case EM_X86_64:
18143fe645bSStephen Wilson         slot = R_X86_64_JUMP_SLOT;
18243fe645bSStephen Wilson         break;
18343fe645bSStephen Wilson     case EM_ARM:
18443fe645bSStephen Wilson         slot = R_ARM_JUMP_SLOT;
18543fe645bSStephen Wilson         break;
186*ca238a7bSDeepak Panickal     case EM_HEXAGON:
187*ca238a7bSDeepak Panickal         slot = R_HEX_JMP_SLOT;
188*ca238a7bSDeepak Panickal         break;
18943fe645bSStephen Wilson     }
19043fe645bSStephen Wilson 
19143fe645bSStephen Wilson     return slot;
19243fe645bSStephen Wilson }
19343fe645bSStephen Wilson 
194f325ba9dSStephen Wilson //------------------------------------------------------------------------------
195f325ba9dSStephen Wilson // ELFSectionHeader
196f325ba9dSStephen Wilson 
197f325ba9dSStephen Wilson ELFSectionHeader::ELFSectionHeader()
198f325ba9dSStephen Wilson {
199f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFSectionHeader));
200f325ba9dSStephen Wilson }
201f325ba9dSStephen Wilson 
202f325ba9dSStephen Wilson bool
203f325ba9dSStephen Wilson ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
204c7bece56SGreg Clayton                         lldb::offset_t *offset)
205f325ba9dSStephen Wilson {
206f325ba9dSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
207f325ba9dSStephen Wilson 
208f325ba9dSStephen Wilson     // Read sh_name and sh_type.
209f325ba9dSStephen Wilson     if (data.GetU32(offset, &sh_name, 2) == NULL)
210f325ba9dSStephen Wilson         return false;
211f325ba9dSStephen Wilson 
212f325ba9dSStephen Wilson     // Read sh_flags.
213f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
214f325ba9dSStephen Wilson         return false;
215f325ba9dSStephen Wilson 
216f325ba9dSStephen Wilson     // Read sh_addr, sh_off and sh_size.
217f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
218f325ba9dSStephen Wilson         return false;
219f325ba9dSStephen Wilson 
220f325ba9dSStephen Wilson     // Read sh_link and sh_info.
221f325ba9dSStephen Wilson     if (data.GetU32(offset, &sh_link, 2) == NULL)
222f325ba9dSStephen Wilson         return false;
223f325ba9dSStephen Wilson 
224f325ba9dSStephen Wilson     // Read sh_addralign and sh_entsize.
225f325ba9dSStephen Wilson     if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
226f325ba9dSStephen Wilson         return false;
227f325ba9dSStephen Wilson 
228f325ba9dSStephen Wilson     return true;
229f325ba9dSStephen Wilson }
230f325ba9dSStephen Wilson 
231f325ba9dSStephen Wilson //------------------------------------------------------------------------------
232f325ba9dSStephen Wilson // ELFSymbol
233f325ba9dSStephen Wilson 
234f325ba9dSStephen Wilson ELFSymbol::ELFSymbol()
235f325ba9dSStephen Wilson {
236f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFSymbol));
237f325ba9dSStephen Wilson }
238f325ba9dSStephen Wilson 
2399594f4c8SGreg Clayton #define ENUM_TO_CSTR(e) case e: return #e
2409594f4c8SGreg Clayton 
2419594f4c8SGreg Clayton const char *
2429594f4c8SGreg Clayton ELFSymbol::bindingToCString(unsigned char binding)
2439594f4c8SGreg Clayton {
2449594f4c8SGreg Clayton     switch (binding)
2459594f4c8SGreg Clayton     {
2469594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_LOCAL);
2479594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_GLOBAL);
2489594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_WEAK);
2499594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_LOOS);
2509594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_HIOS);
2519594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_LOPROC);
2529594f4c8SGreg Clayton     ENUM_TO_CSTR(STB_HIPROC);
2539594f4c8SGreg Clayton     }
2549594f4c8SGreg Clayton     return "";
2559594f4c8SGreg Clayton }
2569594f4c8SGreg Clayton 
2579594f4c8SGreg Clayton const char *
2589594f4c8SGreg Clayton ELFSymbol::typeToCString(unsigned char type)
2599594f4c8SGreg Clayton {
2609594f4c8SGreg Clayton     switch (type)
2619594f4c8SGreg Clayton     {
2629594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_NOTYPE);
2639594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_OBJECT);
2649594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_FUNC);
2659594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_SECTION);
2669594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_FILE);
2679594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_COMMON);
2689594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_TLS);
2699594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_LOOS);
2709594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_HIOS);
2719594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_GNU_IFUNC);
2729594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_LOPROC);
2739594f4c8SGreg Clayton     ENUM_TO_CSTR(STT_HIPROC);
2749594f4c8SGreg Clayton     }
2759594f4c8SGreg Clayton     return "";
2769594f4c8SGreg Clayton }
2779594f4c8SGreg Clayton 
2789594f4c8SGreg Clayton const char *
2799594f4c8SGreg Clayton ELFSymbol::sectionIndexToCString (elf_half shndx,
2809594f4c8SGreg Clayton                                   const lldb_private::SectionList *section_list)
2819594f4c8SGreg Clayton {
2829594f4c8SGreg Clayton     switch (shndx)
2839594f4c8SGreg Clayton     {
2849594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_UNDEF);
2859594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_LOPROC);
2869594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_HIPROC);
2879594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_LOOS);
2889594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_HIOS);
2899594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_ABS);
2909594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_COMMON);
2919594f4c8SGreg Clayton     ENUM_TO_CSTR(SHN_XINDEX);
2929594f4c8SGreg Clayton     default:
2939594f4c8SGreg Clayton         {
2949594f4c8SGreg Clayton             const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get();
2959594f4c8SGreg Clayton             if (section)
2969594f4c8SGreg Clayton                 return section->GetName().AsCString("");
2979594f4c8SGreg Clayton         }
2989594f4c8SGreg Clayton         break;
2999594f4c8SGreg Clayton     }
3009594f4c8SGreg Clayton     return "";
3019594f4c8SGreg Clayton }
3029594f4c8SGreg Clayton 
3039594f4c8SGreg Clayton void
3049594f4c8SGreg Clayton ELFSymbol::Dump (lldb_private::Stream *s,
3059594f4c8SGreg Clayton                  uint32_t idx,
3069594f4c8SGreg Clayton                  const lldb_private::DataExtractor *strtab_data,
3079594f4c8SGreg Clayton                  const lldb_private::SectionList *section_list)
3089594f4c8SGreg Clayton {
309ef14371dSMatt 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",
3109594f4c8SGreg Clayton               idx,
3119594f4c8SGreg Clayton               st_value,
3129594f4c8SGreg Clayton               st_size,
3139594f4c8SGreg Clayton               st_name,
3149594f4c8SGreg Clayton               st_info,
3159594f4c8SGreg Clayton               bindingToCString (getBinding()),
3169594f4c8SGreg Clayton               typeToCString (getType()),
3179594f4c8SGreg Clayton               st_other,
3189594f4c8SGreg Clayton               st_shndx,
3199594f4c8SGreg Clayton               sectionIndexToCString (st_shndx, section_list),
3209594f4c8SGreg Clayton               strtab_data ? strtab_data->PeekCStr(st_name) : "");
3219594f4c8SGreg Clayton }
3229594f4c8SGreg Clayton 
323f325ba9dSStephen Wilson bool
324c7bece56SGreg Clayton ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
325f325ba9dSStephen Wilson {
326f325ba9dSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
327f325ba9dSStephen Wilson     const bool parsing_32 = byte_size == 4;
328f325ba9dSStephen Wilson 
329f325ba9dSStephen Wilson     // Read st_name.
330f325ba9dSStephen Wilson     if (data.GetU32(offset, &st_name, 1) == NULL)
331f325ba9dSStephen Wilson         return false;
332f325ba9dSStephen Wilson 
333f325ba9dSStephen Wilson     if (parsing_32)
334f325ba9dSStephen Wilson     {
335f325ba9dSStephen Wilson         // Read st_value and st_size.
336f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
337f325ba9dSStephen Wilson             return false;
338f325ba9dSStephen Wilson 
339f325ba9dSStephen Wilson         // Read st_info and st_other.
340f325ba9dSStephen Wilson         if (data.GetU8(offset, &st_info, 2) == NULL)
341f325ba9dSStephen Wilson             return false;
342f325ba9dSStephen Wilson 
343f325ba9dSStephen Wilson         // Read st_shndx.
344f325ba9dSStephen Wilson         if (data.GetU16(offset, &st_shndx, 1) == NULL)
345f325ba9dSStephen Wilson             return false;
346f325ba9dSStephen Wilson     }
347f325ba9dSStephen Wilson     else
348f325ba9dSStephen Wilson     {
349f325ba9dSStephen Wilson         // Read st_info and st_other.
350f325ba9dSStephen Wilson         if (data.GetU8(offset, &st_info, 2) == NULL)
351f325ba9dSStephen Wilson             return false;
352f325ba9dSStephen Wilson 
353f325ba9dSStephen Wilson         // Read st_shndx.
354f325ba9dSStephen Wilson         if (data.GetU16(offset, &st_shndx, 1) == NULL)
355f325ba9dSStephen Wilson             return false;
356f325ba9dSStephen Wilson 
357f325ba9dSStephen Wilson         // Read st_value and st_size.
358f325ba9dSStephen Wilson         if (data.GetU64(offset, &st_value, 2) == NULL)
359f325ba9dSStephen Wilson             return false;
360f325ba9dSStephen Wilson     }
361f325ba9dSStephen Wilson     return true;
362f325ba9dSStephen Wilson }
363f325ba9dSStephen Wilson 
364f325ba9dSStephen Wilson //------------------------------------------------------------------------------
365f325ba9dSStephen Wilson // ELFProgramHeader
366f325ba9dSStephen Wilson 
367f325ba9dSStephen Wilson ELFProgramHeader::ELFProgramHeader()
368f325ba9dSStephen Wilson {
369f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFProgramHeader));
370f325ba9dSStephen Wilson }
371f325ba9dSStephen Wilson 
372f325ba9dSStephen Wilson bool
373f325ba9dSStephen Wilson ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
374c7bece56SGreg Clayton                         lldb::offset_t *offset)
375f325ba9dSStephen Wilson {
376f325ba9dSStephen Wilson     const uint32_t byte_size = data.GetAddressByteSize();
377f325ba9dSStephen Wilson     const bool parsing_32 = byte_size == 4;
378f325ba9dSStephen Wilson 
379f325ba9dSStephen Wilson     // Read p_type;
380f325ba9dSStephen Wilson     if (data.GetU32(offset, &p_type, 1) == NULL)
381f325ba9dSStephen Wilson         return false;
382f325ba9dSStephen Wilson 
383f325ba9dSStephen Wilson     if (parsing_32) {
384f325ba9dSStephen Wilson         // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
385f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
386f325ba9dSStephen Wilson             return false;
387f325ba9dSStephen Wilson 
388f325ba9dSStephen Wilson         // Read p_flags.
389f325ba9dSStephen Wilson         if (data.GetU32(offset, &p_flags, 1) == NULL)
390f325ba9dSStephen Wilson             return false;
391f325ba9dSStephen Wilson 
392f325ba9dSStephen Wilson         // Read p_align.
393f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &p_align, byte_size) == false)
394f325ba9dSStephen Wilson             return false;
395f325ba9dSStephen Wilson     }
396f325ba9dSStephen Wilson     else {
397f325ba9dSStephen Wilson         // Read p_flags.
398f325ba9dSStephen Wilson         if (data.GetU32(offset, &p_flags, 1) == NULL)
399f325ba9dSStephen Wilson             return false;
400f325ba9dSStephen Wilson 
401f325ba9dSStephen Wilson         // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
402f325ba9dSStephen Wilson         if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
403f325ba9dSStephen Wilson             return false;
404f325ba9dSStephen Wilson     }
405f325ba9dSStephen Wilson 
406f325ba9dSStephen Wilson     return true;
407f325ba9dSStephen Wilson }
408f325ba9dSStephen Wilson 
409f325ba9dSStephen Wilson //------------------------------------------------------------------------------
410f325ba9dSStephen Wilson // ELFDynamic
411f325ba9dSStephen Wilson 
412f325ba9dSStephen Wilson ELFDynamic::ELFDynamic()
413f325ba9dSStephen Wilson {
414f325ba9dSStephen Wilson     memset(this, 0, sizeof(ELFDynamic));
415f325ba9dSStephen Wilson }
416f325ba9dSStephen Wilson 
417f325ba9dSStephen Wilson bool
418c7bece56SGreg Clayton ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
419f325ba9dSStephen Wilson {
420f325ba9dSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
421f325ba9dSStephen Wilson     return GetMaxS64(data, offset, &d_tag, byte_size, 2);
422f325ba9dSStephen Wilson }
423f325ba9dSStephen Wilson 
42443fe645bSStephen Wilson //------------------------------------------------------------------------------
42543fe645bSStephen Wilson // ELFRel
42643fe645bSStephen Wilson 
42743fe645bSStephen Wilson ELFRel::ELFRel()
42843fe645bSStephen Wilson {
42943fe645bSStephen Wilson     memset(this, 0, sizeof(ELFRel));
43043fe645bSStephen Wilson }
43143fe645bSStephen Wilson 
43243fe645bSStephen Wilson bool
433c7bece56SGreg Clayton ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
43443fe645bSStephen Wilson {
43543fe645bSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
43643fe645bSStephen Wilson 
43743fe645bSStephen Wilson     // Read r_offset and r_info.
43843fe645bSStephen Wilson     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
43943fe645bSStephen Wilson         return false;
44043fe645bSStephen Wilson 
44143fe645bSStephen Wilson     return true;
44243fe645bSStephen Wilson }
44343fe645bSStephen Wilson 
44443fe645bSStephen Wilson //------------------------------------------------------------------------------
44543fe645bSStephen Wilson // ELFRela
44643fe645bSStephen Wilson 
44743fe645bSStephen Wilson ELFRela::ELFRela()
44843fe645bSStephen Wilson {
44943fe645bSStephen Wilson     memset(this, 0, sizeof(ELFRela));
45043fe645bSStephen Wilson }
45143fe645bSStephen Wilson 
45243fe645bSStephen Wilson bool
453c7bece56SGreg Clayton ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
45443fe645bSStephen Wilson {
45543fe645bSStephen Wilson     const unsigned byte_size = data.GetAddressByteSize();
45643fe645bSStephen Wilson 
45743fe645bSStephen Wilson     // Read r_offset and r_info.
45843fe645bSStephen Wilson     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
45943fe645bSStephen Wilson         return false;
46043fe645bSStephen Wilson 
46143fe645bSStephen Wilson     // Read r_addend;
46243fe645bSStephen Wilson     if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
46343fe645bSStephen Wilson         return false;
46443fe645bSStephen Wilson 
46543fe645bSStephen Wilson     return true;
46643fe645bSStephen Wilson }
46743fe645bSStephen Wilson 
468f325ba9dSStephen Wilson 
469