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