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