1 //===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <cstring>
11 
12 #include "lldb/Core/DataExtractor.h"
13 
14 #include "ELFHeader.h"
15 
16 using namespace elf;
17 using namespace lldb;
18 using namespace llvm::ELF;
19 
20 //------------------------------------------------------------------------------
21 // Static utility functions.
22 //
23 // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
24 // with error handling code and provide for parsing a sequence of values.
25 static bool
26 GetMaxU64(const lldb_private::DataExtractor &data,
27           uint32_t *offset, uint64_t *value, uint32_t byte_size)
28 {
29     const uint32_t saved_offset = *offset;
30     *value = data.GetMaxU64(offset, byte_size);
31     return *offset != saved_offset;
32 }
33 
34 static bool
35 GetMaxU64(const lldb_private::DataExtractor &data,
36           uint32_t *offset, uint64_t *value, uint32_t byte_size,
37           uint32_t count)
38 {
39     uint32_t saved_offset = *offset;
40 
41     for (uint32_t i = 0; i < count; ++i, ++value)
42     {
43         if (GetMaxU64(data, offset, value, byte_size) == false)
44         {
45             *offset = saved_offset;
46             return false;
47         }
48     }
49     return true;
50 }
51 
52 static bool
53 GetMaxS64(const lldb_private::DataExtractor &data,
54           uint32_t *offset, int64_t *value, uint32_t byte_size)
55 {
56     const uint32_t saved_offset = *offset;
57     *value = data.GetMaxS64(offset, byte_size);
58     return *offset != saved_offset;
59 }
60 
61 static bool
62 GetMaxS64(const lldb_private::DataExtractor &data,
63           uint32_t *offset, int64_t *value, uint32_t byte_size,
64           uint32_t count)
65 {
66     uint32_t saved_offset = *offset;
67 
68     for (uint32_t i = 0; i < count; ++i, ++value)
69     {
70         if (GetMaxS64(data, offset, value, byte_size) == false)
71         {
72             *offset = saved_offset;
73             return false;
74         }
75     }
76     return true;
77 }
78 
79 //------------------------------------------------------------------------------
80 // ELFHeader
81 
82 ELFHeader::ELFHeader()
83 {
84     memset(this, 0, sizeof(ELFHeader));
85 }
86 
87 ByteOrder
88 ELFHeader::GetByteOrder() const
89 {
90     if (e_ident[EI_DATA] == ELFDATA2MSB)
91         return eByteOrderBig;
92     if (e_ident[EI_DATA] == ELFDATA2LSB)
93         return eByteOrderLittle;
94     return eByteOrderInvalid;
95 }
96 
97 bool
98 ELFHeader::Parse(lldb_private::DataExtractor &data, uint32_t *offset)
99 {
100     // Read e_ident.  This provides byte order and address size info.
101     if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
102         return false;
103 
104     const unsigned byte_size = Is32Bit() ? 4 : 8;
105     data.SetByteOrder(GetByteOrder());
106     data.SetAddressByteSize(byte_size);
107 
108     // Read e_type and e_machine.
109     if (data.GetU16(offset, &e_type, 2) == NULL)
110         return false;
111 
112     // Read e_version.
113     if (data.GetU32(offset, &e_version, 1) == NULL)
114         return false;
115 
116     // Read e_entry, e_phoff and e_shoff.
117     if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
118         return false;
119 
120     // Read e_flags.
121     if (data.GetU32(offset, &e_flags, 1) == NULL)
122         return false;
123 
124     // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
125     // e_shstrndx.
126     if (data.GetU16(offset, &e_ehsize, 6) == NULL)
127         return false;
128 
129     return true;
130 }
131 
132 bool
133 ELFHeader::MagicBytesMatch(const uint8_t *magic)
134 {
135     return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
136 }
137 
138 unsigned
139 ELFHeader::AddressSizeInBytes(const uint8_t *magic)
140 {
141     unsigned address_size = 0;
142 
143     switch (magic[EI_CLASS])
144     {
145     case ELFCLASS32:
146         address_size = 4;
147         break;
148 
149     case ELFCLASS64:
150         address_size = 8;
151         break;
152     }
153     return address_size;
154 }
155 
156 unsigned
157 ELFHeader::GetRelocationJumpSlotType() const
158 {
159     unsigned slot = 0;
160 
161     switch (e_machine)
162     {
163     default:
164         assert(false && "architecture not supported");
165         break;
166     case EM_386:
167     case EM_486:
168         slot = R_386_JUMP_SLOT;
169         break;
170     case EM_X86_64:
171         slot = R_X86_64_JUMP_SLOT;
172         break;
173     case EM_ARM:
174         slot = R_ARM_JUMP_SLOT;
175         break;
176     case EM_MBLAZE:
177         slot = R_MICROBLAZE_JUMP_SLOT;
178     }
179 
180     return slot;
181 }
182 
183 //------------------------------------------------------------------------------
184 // ELFSectionHeader
185 
186 ELFSectionHeader::ELFSectionHeader()
187 {
188     memset(this, 0, sizeof(ELFSectionHeader));
189 }
190 
191 bool
192 ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
193                         uint32_t *offset)
194 {
195     const unsigned byte_size = data.GetAddressByteSize();
196 
197     // Read sh_name and sh_type.
198     if (data.GetU32(offset, &sh_name, 2) == NULL)
199         return false;
200 
201     // Read sh_flags.
202     if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
203         return false;
204 
205     // Read sh_addr, sh_off and sh_size.
206     if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
207         return false;
208 
209     // Read sh_link and sh_info.
210     if (data.GetU32(offset, &sh_link, 2) == NULL)
211         return false;
212 
213     // Read sh_addralign and sh_entsize.
214     if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
215         return false;
216 
217     return true;
218 }
219 
220 //------------------------------------------------------------------------------
221 // ELFSymbol
222 
223 ELFSymbol::ELFSymbol()
224 {
225     memset(this, 0, sizeof(ELFSymbol));
226 }
227 
228 bool
229 ELFSymbol::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
230 {
231     const unsigned byte_size = data.GetAddressByteSize();
232     const bool parsing_32 = byte_size == 4;
233 
234     // Read st_name.
235     if (data.GetU32(offset, &st_name, 1) == NULL)
236         return false;
237 
238     if (parsing_32)
239     {
240         // Read st_value and st_size.
241         if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
242             return false;
243 
244         // Read st_info and st_other.
245         if (data.GetU8(offset, &st_info, 2) == NULL)
246             return false;
247 
248         // Read st_shndx.
249         if (data.GetU16(offset, &st_shndx, 1) == NULL)
250             return false;
251     }
252     else
253     {
254         // Read st_info and st_other.
255         if (data.GetU8(offset, &st_info, 2) == NULL)
256             return false;
257 
258         // Read st_shndx.
259         if (data.GetU16(offset, &st_shndx, 1) == NULL)
260             return false;
261 
262         // Read st_value and st_size.
263         if (data.GetU64(offset, &st_value, 2) == NULL)
264             return false;
265     }
266     return true;
267 }
268 
269 //------------------------------------------------------------------------------
270 // ELFProgramHeader
271 
272 ELFProgramHeader::ELFProgramHeader()
273 {
274     memset(this, 0, sizeof(ELFProgramHeader));
275 }
276 
277 bool
278 ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
279                         uint32_t *offset)
280 {
281     const uint32_t byte_size = data.GetAddressByteSize();
282     const bool parsing_32 = byte_size == 4;
283 
284     // Read p_type;
285     if (data.GetU32(offset, &p_type, 1) == NULL)
286         return false;
287 
288     if (parsing_32) {
289         // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
290         if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
291             return false;
292 
293         // Read p_flags.
294         if (data.GetU32(offset, &p_flags, 1) == NULL)
295             return false;
296 
297         // Read p_align.
298         if (GetMaxU64(data, offset, &p_align, byte_size) == false)
299             return false;
300     }
301     else {
302         // Read p_flags.
303         if (data.GetU32(offset, &p_flags, 1) == NULL)
304             return false;
305 
306         // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
307         if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
308             return false;
309     }
310 
311     return true;
312 }
313 
314 //------------------------------------------------------------------------------
315 // ELFDynamic
316 
317 ELFDynamic::ELFDynamic()
318 {
319     memset(this, 0, sizeof(ELFDynamic));
320 }
321 
322 bool
323 ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
324 {
325     const unsigned byte_size = data.GetAddressByteSize();
326     return GetMaxS64(data, offset, &d_tag, byte_size, 2);
327 }
328 
329 //------------------------------------------------------------------------------
330 // ELFRel
331 
332 ELFRel::ELFRel()
333 {
334     memset(this, 0, sizeof(ELFRel));
335 }
336 
337 bool
338 ELFRel::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
339 {
340     const unsigned byte_size = data.GetAddressByteSize();
341 
342     // Read r_offset and r_info.
343     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
344         return false;
345 
346     return true;
347 }
348 
349 //------------------------------------------------------------------------------
350 // ELFRela
351 
352 ELFRela::ELFRela()
353 {
354     memset(this, 0, sizeof(ELFRela));
355 }
356 
357 bool
358 ELFRela::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
359 {
360     const unsigned byte_size = data.GetAddressByteSize();
361 
362     // Read r_offset and r_info.
363     if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
364         return false;
365 
366     // Read r_addend;
367     if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
368         return false;
369 
370     return true;
371 }
372 
373 
374