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 //------------------------------------------------------------------------------
157 // ELFSectionHeader
158 
159 ELFSectionHeader::ELFSectionHeader()
160 {
161     memset(this, 0, sizeof(ELFSectionHeader));
162 }
163 
164 bool
165 ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
166                         uint32_t *offset)
167 {
168     const unsigned byte_size = data.GetAddressByteSize();
169 
170     // Read sh_name and sh_type.
171     if (data.GetU32(offset, &sh_name, 2) == NULL)
172         return false;
173 
174     // Read sh_flags.
175     if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
176         return false;
177 
178     // Read sh_addr, sh_off and sh_size.
179     if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
180         return false;
181 
182     // Read sh_link and sh_info.
183     if (data.GetU32(offset, &sh_link, 2) == NULL)
184         return false;
185 
186     // Read sh_addralign and sh_entsize.
187     if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
188         return false;
189 
190     return true;
191 }
192 
193 //------------------------------------------------------------------------------
194 // ELFSymbol
195 
196 ELFSymbol::ELFSymbol()
197 {
198     memset(this, 0, sizeof(ELFSymbol));
199 }
200 
201 bool
202 ELFSymbol::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
203 {
204     const unsigned byte_size = data.GetAddressByteSize();
205     const bool parsing_32 = byte_size == 4;
206 
207     // Read st_name.
208     if (data.GetU32(offset, &st_name, 1) == NULL)
209         return false;
210 
211     if (parsing_32)
212     {
213         // Read st_value and st_size.
214         if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
215             return false;
216 
217         // Read st_info and st_other.
218         if (data.GetU8(offset, &st_info, 2) == NULL)
219             return false;
220 
221         // Read st_shndx.
222         if (data.GetU16(offset, &st_shndx, 1) == NULL)
223             return false;
224     }
225     else
226     {
227         // Read st_info and st_other.
228         if (data.GetU8(offset, &st_info, 2) == NULL)
229             return false;
230 
231         // Read st_shndx.
232         if (data.GetU16(offset, &st_shndx, 1) == NULL)
233             return false;
234 
235         // Read st_value and st_size.
236         if (data.GetU64(offset, &st_value, 2) == NULL)
237             return false;
238     }
239     return true;
240 }
241 
242 //------------------------------------------------------------------------------
243 // ELFProgramHeader
244 
245 ELFProgramHeader::ELFProgramHeader()
246 {
247     memset(this, 0, sizeof(ELFProgramHeader));
248 }
249 
250 bool
251 ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
252                         uint32_t *offset)
253 {
254     const uint32_t byte_size = data.GetAddressByteSize();
255     const bool parsing_32 = byte_size == 4;
256 
257     // Read p_type;
258     if (data.GetU32(offset, &p_type, 1) == NULL)
259         return false;
260 
261     if (parsing_32) {
262         // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
263         if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
264             return false;
265 
266         // Read p_flags.
267         if (data.GetU32(offset, &p_flags, 1) == NULL)
268             return false;
269 
270         // Read p_align.
271         if (GetMaxU64(data, offset, &p_align, byte_size) == false)
272             return false;
273     }
274     else {
275         // Read p_flags.
276         if (data.GetU32(offset, &p_flags, 1) == NULL)
277             return false;
278 
279         // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
280         if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
281             return false;
282     }
283 
284     return true;
285 }
286 
287 //------------------------------------------------------------------------------
288 // ELFDynamic
289 
290 ELFDynamic::ELFDynamic()
291 {
292     memset(this, 0, sizeof(ELFDynamic));
293 }
294 
295 bool
296 ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
297 {
298     const unsigned byte_size = data.GetAddressByteSize();
299     return GetMaxS64(data, offset, &d_tag, byte_size, 2);
300 }
301 
302 
303