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