]>
Commit | Line | Data |
---|---|---|
7ccc9c95 YZ |
1 | ## @file\r |
2 | #\r | |
3 | # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r | |
4 | #\r | |
2e351cbe | 5 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r |
7ccc9c95 YZ |
6 | #\r |
7 | \r | |
1ccc4d89 | 8 | from __future__ import print_function\r |
7ccc9c95 YZ |
9 | import array\r |
10 | import uuid\r | |
11 | import re\r | |
12 | import os\r | |
13 | import logging\r | |
14 | import core.pe as pe\r | |
15 | \r | |
16 | def GetLogger():\r | |
17 | return logging.getLogger('EFI Binary File')\r | |
18 | \r | |
19 | class EFIBinaryError(Exception):\r | |
20 | def __init__(self, message):\r | |
21 | Exception.__init__(self)\r | |
22 | self._message = message\r | |
23 | \r | |
24 | def GetMessage(self):\r | |
25 | return self._message\r | |
26 | \r | |
27 | class EfiFd(object):\r | |
28 | EFI_FV_HEADER_SIZE = 0x48\r | |
29 | \r | |
30 | def __init__(self):\r | |
31 | self._fvs = []\r | |
32 | \r | |
33 | def Load(self, fd, size):\r | |
34 | index = fd.tell()\r | |
35 | while (index + self.EFI_FV_HEADER_SIZE < size):\r | |
36 | fv = EfiFv(self)\r | |
37 | fv.Load(fd)\r | |
38 | self._fvs.append(fv)\r | |
39 | index += fv.GetHeader().GetFvLength()\r | |
40 | index = align(index, 8)\r | |
41 | fd.seek(index)\r | |
42 | \r | |
43 | def GetFvs(self):\r | |
44 | return self._fvs\r | |
45 | \r | |
46 | class EfiFv(object):\r | |
47 | FILE_SYSTEM_GUID = uuid.UUID('{8c8ce578-8a3d-4f1c-9935-896185c32dd3}')\r | |
48 | \r | |
49 | def __init__(self, parent=None):\r | |
50 | self._size = 0\r | |
51 | self._filename = None\r | |
52 | self._fvheader = None\r | |
53 | self._blockentries = []\r | |
54 | self._ffs = []\r | |
55 | \r | |
56 | # following field is for FV in FD\r | |
57 | self._parent = parent\r | |
58 | self._offset = 0\r | |
59 | self._raw = array.array('B')\r | |
60 | \r | |
61 | def Load(self, fd):\r | |
62 | self._offset = fd.tell()\r | |
63 | self._filename = fd.name\r | |
64 | \r | |
65 | # get file header\r | |
66 | self._fvheader = EfiFirmwareVolumeHeader.Read(fd)\r | |
67 | #self._fvheader.Dump()\r | |
68 | \r | |
69 | self._size = self._fvheader.GetFvLength()\r | |
70 | \r | |
71 | if self._fvheader.GetFileSystemGuid() != self.FILE_SYSTEM_GUID:\r | |
72 | fd.seek(self._offset)\r | |
73 | self._raw.fromfile(fd, self.GetHeader().GetFvLength())\r | |
74 | return\r | |
75 | \r | |
76 | # read block map\r | |
77 | blockentry = BlockMapEntry.Read(fd)\r | |
78 | self._blockentries.append(blockentry)\r | |
79 | while (blockentry.GetNumberBlocks() != 0 and blockentry.GetLength() != 0):\r | |
80 | self._blockentries.append(blockentry)\r | |
81 | blockentry = BlockMapEntry.Read(fd)\r | |
82 | \r | |
83 | \r | |
84 | if self._fvheader.GetSize() + (len(self._blockentries)) * 8 != \\r | |
85 | self._fvheader.GetHeaderLength():\r | |
86 | raise EFIBinaryError("Volume Header length not consistent with block map!")\r | |
87 | \r | |
88 | index = align(fd.tell(), 8)\r | |
89 | count = 0\r | |
90 | while ((index + EfiFfs.FFS_HEADER_SIZE) < self._size):\r | |
91 | ffs = EfiFfs.Read(fd, self)\r | |
92 | if not isValidGuid(ffs.GetNameGuid()):\r | |
93 | break\r | |
94 | self._ffs.append(ffs)\r | |
95 | count += 1\r | |
96 | index = align(fd.tell(), 8)\r | |
97 | \r | |
98 | fd.seek(self._offset)\r | |
99 | self._raw.fromfile(fd, self.GetHeader().GetFvLength())\r | |
100 | \r | |
101 | def GetFfs(self):\r | |
102 | return self._ffs\r | |
103 | \r | |
104 | def GetHeader(self):\r | |
105 | return self._fvheader\r | |
106 | \r | |
107 | def GetBlockEntries(self):\r | |
108 | return self._blockentries\r | |
109 | \r | |
110 | def GetHeaderRawData(self):\r | |
111 | ret = []\r | |
112 | ret += self._fvheader.GetRawData()\r | |
113 | for block in self._blockentries:\r | |
114 | ret += block.GetRawData()\r | |
115 | return ret\r | |
116 | \r | |
117 | def GetOffset(self):\r | |
118 | return 0\r | |
119 | \r | |
120 | def GetRawData(self):\r | |
121 | return self._raw.tolist()\r | |
122 | \r | |
123 | class BinaryItem(object):\r | |
124 | def __init__(self, parent=None):\r | |
125 | self._size = 0\r | |
126 | self._arr = array.array('B')\r | |
127 | self._parent = parent\r | |
128 | \r | |
129 | @classmethod\r | |
130 | def Read(cls, fd, parent=None):\r | |
131 | item = cls(parent)\r | |
132 | item.fromfile(fd)\r | |
133 | return item\r | |
134 | \r | |
135 | def Load(self, fd):\r | |
136 | self.fromfile(fd)\r | |
137 | \r | |
138 | def GetSize(self):\r | |
139 | """should be implemented by inherited class"""\r | |
140 | \r | |
141 | def fromfile(self, fd):\r | |
142 | self._arr.fromfile(fd, self.GetSize())\r | |
143 | \r | |
144 | def GetParent(self):\r | |
145 | return self._parent\r | |
146 | \r | |
147 | class EfiFirmwareVolumeHeader(BinaryItem):\r | |
148 | def GetSize(self):\r | |
149 | return 56\r | |
150 | \r | |
151 | def GetSigunature(self):\r | |
152 | list = self._arr.tolist()\r | |
153 | sig = ''\r | |
154 | for x in list[40:44]:\r | |
155 | sig += chr(x)\r | |
156 | return sig\r | |
157 | \r | |
158 | def GetAttribute(self):\r | |
159 | return list2int(self._arr.tolist()[44:48])\r | |
160 | \r | |
161 | def GetErasePolarity(self):\r | |
162 | list = self.GetAttrStrings()\r | |
163 | if 'EFI_FVB2_ERASE_POLARITY' in list:\r | |
164 | return True\r | |
165 | return False\r | |
166 | \r | |
167 | def GetAttrStrings(self):\r | |
168 | list = []\r | |
169 | value = self.GetAttribute()\r | |
170 | if (value & 0x01) != 0:\r | |
171 | list.append('EFI_FVB2_READ_DISABLED_CAP')\r | |
172 | if (value & 0x02) != 0:\r | |
173 | list.append('EFI_FVB2_READ_ENABLED_CAP')\r | |
174 | if (value & 0x04) != 0:\r | |
175 | list.append('EFI_FVB2_READ_STATUS')\r | |
176 | if (value & 0x08) != 0:\r | |
177 | list.append('EFI_FVB2_WRITE_DISABLED_CAP')\r | |
178 | if (value & 0x10) != 0:\r | |
179 | list.append('EFI_FVB2_WRITE_ENABLED_CAP')\r | |
180 | if (value & 0x20) != 0:\r | |
181 | list.append('EFI_FVB2_WRITE_STATUS')\r | |
182 | if (value & 0x40) != 0:\r | |
183 | list.append('EFI_FVB2_LOCK_CAP')\r | |
184 | if (value & 0x80) != 0:\r | |
185 | list.append('EFI_FVB2_LOCK_STATUS')\r | |
186 | if (value & 0x200) != 0:\r | |
187 | list.append('EFI_FVB2_STICKY_WRITE')\r | |
188 | if (value & 0x400) != 0:\r | |
189 | list.append('EFI_FVB2_MEMORY_MAPPED')\r | |
190 | if (value & 0x800) != 0:\r | |
191 | list.append('EFI_FVB2_ERASE_POLARITY')\r | |
192 | if (value & 0x1000) != 0:\r | |
193 | list.append('EFI_FVB2_READ_LOCK_CAP')\r | |
194 | if (value & 0x00002000) != 0:\r | |
195 | list.append('EFI_FVB2_READ_LOCK_STATUS')\r | |
196 | if (value & 0x00004000) != 0:\r | |
197 | list.append('EFI_FVB2_WRITE_LOCK_CAP')\r | |
198 | if (value & 0x00008000) != 0:\r | |
199 | list.append('EFI_FVB2_WRITE_LOCK_STATUS')\r | |
200 | \r | |
201 | if (value == 0):\r | |
202 | list.append('EFI_FVB2_ALIGNMENT_1')\r | |
203 | if (value & 0x001F0000) == 0x00010000:\r | |
204 | list.append('EFI_FVB2_ALIGNMENT_2')\r | |
205 | if (value & 0x001F0000) == 0x00020000:\r | |
206 | list.append('EFI_FVB2_ALIGNMENT_4')\r | |
207 | if (value & 0x001F0000) == 0x00030000:\r | |
208 | list.append('EFI_FVB2_ALIGNMENT_8')\r | |
209 | if (value & 0x001F0000) == 0x00040000:\r | |
210 | list.append('EFI_FVB2_ALIGNMENT_16')\r | |
211 | if (value & 0x001F0000) == 0x00050000:\r | |
212 | list.append('EFI_FVB2_ALIGNMENT_32')\r | |
213 | if (value & 0x001F0000) == 0x00060000:\r | |
214 | list.append('EFI_FVB2_ALIGNMENT_64')\r | |
215 | if (value & 0x001F0000) == 0x00070000:\r | |
216 | list.append('EFI_FVB2_ALIGNMENT_128')\r | |
217 | if (value & 0x001F0000) == 0x00080000:\r | |
218 | list.append('EFI_FVB2_ALIGNMENT_256')\r | |
219 | if (value & 0x001F0000) == 0x00090000:\r | |
220 | list.append('EFI_FVB2_ALIGNMENT_512')\r | |
221 | if (value & 0x001F0000) == 0x000A0000:\r | |
222 | list.append('EFI_FVB2_ALIGNMENT_1K')\r | |
223 | if (value & 0x001F0000) == 0x000B0000:\r | |
224 | list.append('EFI_FVB2_ALIGNMENT_2K')\r | |
225 | if (value & 0x001F0000) == 0x000C0000:\r | |
226 | list.append('EFI_FVB2_ALIGNMENT_4K')\r | |
227 | if (value & 0x001F0000) == 0x000D0000:\r | |
228 | list.append('EFI_FVB2_ALIGNMENT_8K')\r | |
229 | if (value & 0x001F0000) == 0x000E0000:\r | |
230 | list.append('EFI_FVB2_ALIGNMENT_16K')\r | |
231 | if (value & 0x001F0000) == 0x000F0000:\r | |
232 | list.append('EFI_FVB2_ALIGNMENT_32K')\r | |
233 | if (value & 0x001F0000) == 0x00100000:\r | |
234 | list.append('EFI_FVB2_ALIGNMENT_64K')\r | |
235 | if (value & 0x001F0000) == 0x00110000:\r | |
236 | list.append('EFI_FVB2_ALIGNMENT_128K')\r | |
237 | if (value & 0x001F0000) == 0x00120000:\r | |
238 | list.append('EFI_FVB2_ALIGNMENT_256K')\r | |
239 | if (value & 0x001F0000) == 0x00130000:\r | |
240 | list.append('EFI_FVB2_ALIGNMENT_512K')\r | |
241 | \r | |
242 | return list\r | |
243 | \r | |
244 | def GetHeaderLength(self):\r | |
245 | return list2int(self._arr.tolist()[48:50])\r | |
246 | \r | |
247 | def Dump(self):\r | |
72443dd2 GL |
248 | print('Signature: %s' % self.GetSigunature())\r |
249 | print('Attribute: 0x%X' % self.GetAttribute())\r | |
250 | print('Header Length: 0x%X' % self.GetHeaderLength())\r | |
251 | print('File system Guid: ', self.GetFileSystemGuid())\r | |
252 | print('Revision: 0x%X' % self.GetRevision())\r | |
253 | print('FvLength: 0x%X' % self.GetFvLength())\r | |
7ccc9c95 YZ |
254 | \r |
255 | def GetFileSystemGuid(self):\r | |
256 | list = self._arr.tolist()\r | |
257 | return list2guid(list[16:32])\r | |
258 | \r | |
259 | def GetRevision(self):\r | |
260 | list = self._arr.tolist()\r | |
261 | return int(list[55])\r | |
262 | \r | |
263 | def GetFvLength(self):\r | |
264 | list = self._arr.tolist()\r | |
265 | return list2int(list[32:40])\r | |
266 | \r | |
267 | def GetRawData(self):\r | |
268 | return self._arr.tolist()\r | |
269 | \r | |
270 | class BlockMapEntry(BinaryItem):\r | |
271 | def GetSize(self):\r | |
272 | return 8\r | |
273 | \r | |
274 | def GetNumberBlocks(self):\r | |
275 | list = self._arr.tolist()\r | |
276 | return list2int(list[0:4])\r | |
277 | \r | |
278 | def GetLength(self):\r | |
279 | list = self._arr.tolist()\r | |
280 | return list2int(list[4:8])\r | |
281 | \r | |
282 | def GetRawData(self):\r | |
283 | return self._arr.tolist()\r | |
284 | \r | |
285 | def __str__(self):\r | |
286 | return '[BlockEntry] Number = 0x%X, length=0x%X' % (self.GetNumberBlocks(), self.GetLength())\r | |
287 | \r | |
288 | class EfiFfs(object):\r | |
289 | FFS_HEADER_SIZE = 24\r | |
290 | \r | |
291 | def __init__(self, parent=None):\r | |
292 | self._header = None\r | |
293 | \r | |
294 | # following field is for FFS in FV file.\r | |
295 | self._parent = parent\r | |
296 | self._offset = 0\r | |
297 | self._sections = []\r | |
298 | \r | |
299 | def Load(self, fd):\r | |
300 | self._offset = align(fd.tell(), 8)\r | |
301 | \r | |
302 | self._header = EfiFfsHeader.Read(fd, self)\r | |
303 | \r | |
304 | if not isValidGuid(self.GetNameGuid()):\r | |
305 | return\r | |
306 | \r | |
307 | index = self._offset\r | |
308 | fileend = self._offset + self.GetSize()\r | |
309 | while (index + EfiSection.EFI_SECTION_HEADER_SIZE < fileend):\r | |
310 | section = EfiSection(self)\r | |
311 | section.Load(fd)\r | |
312 | if section.GetSize() == 0 and section.GetHeader().GetType() == 0:\r | |
313 | break\r | |
314 | self._sections.append(section)\r | |
315 | index = fd.tell()\r | |
316 | \r | |
317 | # rebase file pointer to next ffs file\r | |
318 | index = self._offset + self._header.GetFfsSize()\r | |
319 | index = align(index, 8)\r | |
320 | fd.seek(index)\r | |
321 | \r | |
322 | def GetOffset(self):\r | |
323 | return self._offset\r | |
324 | \r | |
325 | def GetSize(self):\r | |
326 | return self._header.GetFfsSize()\r | |
327 | \r | |
328 | @classmethod\r | |
329 | def Read(cls, fd, parent=None):\r | |
330 | item = cls(parent)\r | |
331 | item.Load(fd)\r | |
332 | return item\r | |
333 | \r | |
334 | def GetNameGuid(self):\r | |
335 | return self._header.GetNameGuid()\r | |
336 | \r | |
337 | def DumpContent(self):\r | |
338 | list = self._content.tolist()\r | |
339 | line = []\r | |
340 | count = 0\r | |
341 | for item in list:\r | |
342 | if count < 32:\r | |
343 | line.append('0x%X' % int(item))\r | |
344 | count += 1\r | |
345 | else:\r | |
72443dd2 | 346 | print(' '.join(line))\r |
7ccc9c95 YZ |
347 | count = 0\r |
348 | line = []\r | |
349 | line.append('0x%X' % int(item))\r | |
350 | count += 1\r | |
351 | \r | |
352 | def GetHeader(self):\r | |
353 | return self._header\r | |
354 | \r | |
355 | def GetParent(self):\r | |
356 | return self._parent\r | |
357 | \r | |
358 | def GetSections(self):\r | |
359 | return self._sections\r | |
360 | \r | |
361 | class EfiFfsHeader(BinaryItem):\r | |
362 | ffs_state_map = {0x01:'EFI_FILE_HEADER_CONSTRUCTION',\r | |
363 | 0x02:'EFI_FILE_HEADER_VALID',\r | |
364 | 0x04:'EFI_FILE_DATA_VALID',\r | |
365 | 0x08:'EFI_FILE_MARKED_FOR_UPDATE',\r | |
366 | 0x10:'EFI_FILE_DELETED',\r | |
367 | 0x20:'EFI_FILE_HEADER_INVALID'}\r | |
368 | \r | |
369 | def GetSize(self):\r | |
370 | return 24\r | |
371 | \r | |
372 | def GetNameGuid(self):\r | |
373 | list = self._arr.tolist()\r | |
374 | return list2guid(list[0:16])\r | |
375 | \r | |
376 | def GetType(self):\r | |
377 | list = self._arr.tolist()\r | |
378 | return int(list[18])\r | |
379 | \r | |
380 | \r | |
381 | def GetTypeString(self):\r | |
382 | value = self.GetType()\r | |
383 | if value == 0x01:\r | |
384 | return 'EFI_FV_FILETYPE_RAW'\r | |
385 | if value == 0x02:\r | |
386 | return 'EFI_FV_FILETYPE_FREEFORM'\r | |
387 | if value == 0x03:\r | |
388 | return 'EFI_FV_FILETYPE_SECURITY_CORE'\r | |
389 | if value == 0x04:\r | |
390 | return 'EFI_FV_FILETYPE_PEI_CORE'\r | |
391 | if value == 0x05:\r | |
392 | return 'EFI_FV_FILETYPE_DXE_CORE'\r | |
393 | if value == 0x06:\r | |
394 | return 'EFI_FV_FILETYPE_PEIM'\r | |
395 | if value == 0x07:\r | |
396 | return 'EFI_FV_FILETYPE_DRIVER'\r | |
397 | if value == 0x08:\r | |
398 | return 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER'\r | |
399 | if value == 0x09:\r | |
400 | return 'EFI_FV_FILETYPE_APPLICATION'\r | |
401 | if value == 0x0B:\r | |
402 | return 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE'\r | |
403 | if value == 0xc0:\r | |
404 | return 'EFI_FV_FILETYPE_OEM_MIN'\r | |
405 | if value == 0xdf:\r | |
406 | return 'EFI_FV_FILETYPE_OEM_MAX'\r | |
407 | if value == 0xe0:\r | |
408 | return 'EFI_FV_FILETYPE_DEBUG_MIN'\r | |
409 | if value == 0xef:\r | |
410 | return 'EFI_FV_FILETYPE_DEBUG_MAX'\r | |
411 | if value == 0xf0:\r | |
412 | return 'EFI_FV_FILETYPE_FFS_PAD'\r | |
413 | if value == 0xff:\r | |
414 | return 'EFI_FV_FILETYPE_FFS_MAX'\r | |
415 | return 'Unknown FFS Type'\r | |
416 | \r | |
417 | def GetAttributes(self):\r | |
418 | list = self._arr.tolist()\r | |
419 | return int(list[19])\r | |
420 | \r | |
421 | def GetFfsSize(self):\r | |
422 | list = self._arr.tolist()\r | |
423 | return list2int(list[20:23])\r | |
424 | \r | |
425 | def GetState(self):\r | |
426 | list = self._arr.tolist()\r | |
427 | state = int(list[23])\r | |
428 | polarity = self.GetParent().GetParent().GetHeader().GetErasePolarity()\r | |
429 | if polarity:\r | |
430 | state = (~state) & 0xFF\r | |
431 | HighestBit = 0x80\r | |
432 | while (HighestBit != 0) and (HighestBit & state) == 0:\r | |
433 | HighestBit = HighestBit >> 1\r | |
434 | return HighestBit\r | |
435 | \r | |
436 | def GetStateString(self):\r | |
437 | state = self.GetState()\r | |
438 | if state in self.ffs_state_map.keys():\r | |
439 | return self.ffs_state_map[state]\r | |
440 | return 'Unknown Ffs State'\r | |
441 | \r | |
442 | def Dump(self):\r | |
72443dd2 GL |
443 | print("FFS name: ", self.GetNameGuid())\r |
444 | print("FFS type: ", self.GetType())\r | |
445 | print("FFS attr: 0x%X" % self.GetAttributes())\r | |
446 | print("FFS size: 0x%X" % self.GetFfsSize())\r | |
447 | print("FFS state: 0x%X" % self.GetState())\r | |
7ccc9c95 YZ |
448 | \r |
449 | def GetRawData(self):\r | |
450 | return self._arr.tolist()\r | |
451 | \r | |
452 | \r | |
453 | class EfiSection(object):\r | |
454 | EFI_SECTION_HEADER_SIZE = 4\r | |
455 | \r | |
456 | def __init__(self, parent=None):\r | |
457 | self._size = 0\r | |
458 | self._parent = parent\r | |
459 | self._offset = 0\r | |
460 | self._contents = array.array('B')\r | |
461 | \r | |
462 | def Load(self, fd):\r | |
463 | self._offset = align(fd.tell(), 4)\r | |
464 | \r | |
465 | self._header = EfiSectionHeader.Read(fd, self)\r | |
466 | \r | |
467 | if self._header.GetTypeString() == "EFI_SECTION_PE32":\r | |
468 | pefile = pe.PEFile(self)\r | |
469 | pefile.Load(fd, self.GetContentSize())\r | |
470 | \r | |
471 | fd.seek(self._offset)\r | |
472 | self._contents.fromfile(fd, self.GetContentSize())\r | |
473 | \r | |
474 | # rebase file pointer to next section\r | |
475 | index = self._offset + self.GetSize()\r | |
476 | index = align(index, 4)\r | |
477 | fd.seek(index)\r | |
478 | \r | |
479 | def GetContentSize(self):\r | |
480 | return self.GetSize() - self.EFI_SECTION_HEADER_SIZE\r | |
481 | \r | |
482 | def GetContent(self):\r | |
483 | return self._contents.tolist()\r | |
484 | \r | |
485 | def GetSize(self):\r | |
486 | return self._header.GetSectionSize()\r | |
487 | \r | |
488 | def GetHeader(self):\r | |
489 | return self._header\r | |
490 | \r | |
491 | def GetSectionOffset(self):\r | |
492 | return self._offset + self.EFI_SECTION_HEADER_SIZE\r | |
493 | \r | |
494 | class EfiSectionHeader(BinaryItem):\r | |
495 | section_type_map = {0x01: 'EFI_SECTION_COMPRESSION',\r | |
496 | 0x02: 'EFI_SECTION_GUID_DEFINED',\r | |
497 | 0x10: 'EFI_SECTION_PE32',\r | |
498 | 0x11: 'EFI_SECTION_PIC',\r | |
499 | 0x12: 'EFI_SECTION_TE',\r | |
500 | 0x13: 'EFI_SECTION_DXE_DEPEX',\r | |
501 | 0x14: 'EFI_SECTION_VERSION',\r | |
502 | 0x15: 'EFI_SECTION_USER_INTERFACE',\r | |
503 | 0x16: 'EFI_SECTION_COMPATIBILITY16',\r | |
504 | 0x17: 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',\r | |
505 | 0x18: 'EFI_SECTION_FREEFORM_SUBTYPE_GUID',\r | |
506 | 0x19: 'EFI_SECTION_RAW',\r | |
507 | 0x1B: 'EFI_SECTION_PEI_DEPEX'}\r | |
508 | def GetSize(self):\r | |
509 | return 4\r | |
510 | \r | |
511 | def GetSectionSize(self):\r | |
512 | list = self._arr.tolist()\r | |
513 | return list2int(list[0:3])\r | |
514 | \r | |
515 | def GetType(self):\r | |
516 | list = self._arr.tolist()\r | |
517 | return int(list[3])\r | |
518 | \r | |
519 | def GetTypeString(self):\r | |
520 | type = self.GetType()\r | |
521 | if type not in self.section_type_map.keys():\r | |
522 | return 'Unknown Section Type'\r | |
523 | return self.section_type_map[type]\r | |
524 | \r | |
525 | def Dump(self):\r | |
72443dd2 GL |
526 | print('size = 0x%X' % self.GetSectionSize())\r |
527 | print('type = 0x%X' % self.GetType())\r | |
7ccc9c95 YZ |
528 | \r |
529 | \r | |
530 | \r | |
531 | rMapEntry = re.compile('^(\w+)[ \(\w\)]* \(BaseAddress=([0-9a-fA-F]+), EntryPoint=([0-9a-fA-F]+), GUID=([0-9a-fA-F\-]+)')\r | |
532 | class EfiFvMapFile(object):\r | |
533 | def __init__(self):\r | |
534 | self._mapentries = {}\r | |
535 | \r | |
536 | def Load(self, path):\r | |
537 | if not os.path.exists(path):\r | |
538 | return False\r | |
539 | \r | |
540 | try:\r | |
541 | file = open(path, 'r')\r | |
542 | lines = file.readlines()\r | |
543 | file.close()\r | |
544 | except:\r | |
545 | return False\r | |
546 | \r | |
547 | for line in lines:\r | |
548 | if line[0] != ' ':\r | |
549 | # new entry\r | |
550 | ret = rMapEntry.match(line)\r | |
4231a819 | 551 | if ret is not None:\r |
7ccc9c95 YZ |
552 | name = ret.groups()[0]\r |
553 | baseaddr = int(ret.groups()[1], 16)\r | |
554 | entry = int(ret.groups()[2], 16)\r | |
555 | guidstr = '{' + ret.groups()[3] + '}'\r | |
556 | guid = uuid.UUID(guidstr)\r | |
557 | self._mapentries[guid] = EfiFvMapFileEntry(name, baseaddr, entry, guid)\r | |
558 | return True\r | |
559 | \r | |
560 | def GetEntry(self, guid):\r | |
561 | if guid in self._mapentries.keys():\r | |
562 | return self._mapentries[guid]\r | |
563 | return None\r | |
564 | \r | |
565 | class EfiFvMapFileEntry(object):\r | |
566 | def __init__(self, name, baseaddr, entry, guid):\r | |
567 | self._name = name\r | |
568 | self._baseaddr = baseaddr\r | |
569 | self._entry = entry\r | |
570 | self._guid = guid\r | |
571 | \r | |
572 | def GetName(self):\r | |
573 | return self._name\r | |
574 | \r | |
575 | def GetBaseAddress(self):\r | |
576 | return self._baseaddr\r | |
577 | \r | |
578 | def GetEntryPoint(self):\r | |
579 | return self._entry\r | |
580 | \r | |
581 | def list2guid(list):\r | |
582 | val1 = list2int(list[0:4])\r | |
583 | val2 = list2int(list[4:6])\r | |
584 | val3 = list2int(list[6:8])\r | |
585 | val4 = 0\r | |
586 | for item in list[8:16]:\r | |
587 | val4 = (val4 << 8) | int(item)\r | |
588 | \r | |
589 | val = val1 << 12 * 8 | val2 << 10 * 8 | val3 << 8 * 8 | val4\r | |
590 | guid = uuid.UUID(int=val)\r | |
591 | return guid\r | |
592 | \r | |
593 | def list2int(list):\r | |
594 | val = 0\r | |
595 | for index in range(len(list) - 1, -1, -1):\r | |
596 | val = (val << 8) | int(list[index])\r | |
597 | return val\r | |
598 | \r | |
599 | def align(value, alignment):\r | |
600 | return (value + ((alignment - value) & (alignment - 1)))\r | |
601 | \r | |
602 | gInvalidGuid = uuid.UUID(int=0xffffffffffffffffffffffffffffffff)\r | |
603 | def isValidGuid(guid):\r | |
604 | if guid == gInvalidGuid:\r | |
605 | return False\r | |
606 | return True\r |