+ raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")\r
+\r
+ def ParseFsp(self):\r
+ flen = 0\r
+ for idx, fv in enumerate(self.FvList):\r
+ # Check if this FV contains FSP header\r
+ if flen == 0:\r
+ if len(fv.FfsList) == 0:\r
+ continue\r
+ ffs = fv.FfsList[0]\r
+ if len(ffs.SecList) == 0:\r
+ continue\r
+ sec = ffs.SecList[0]\r
+ if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:\r
+ continue\r
+ fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)\r
+ fspoffset = fv.Offset\r
+ offset = fspoffset + fihoffset\r
+ fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)\r
+ if 'FSPH' != fih.Signature:\r
+ continue\r
+\r
+ offset += fih.HeaderLength\r
+ offset = AlignPtr(offset, 4)\r
+ plist = []\r
+ while True:\r
+ fch = FSP_COMMON_HEADER.from_buffer (self.FdData, offset)\r
+ if 'FSPP' != fch.Signature:\r
+ offset += fch.HeaderLength\r
+ offset = AlignPtr(offset, 4)\r
+ else:\r
+ fspp = FSP_PATCH_TABLE.from_buffer (self.FdData, offset)\r
+ offset += sizeof(fspp)\r
+ pdata = (c_uint32 * fspp.PatchEntryNum).from_buffer(self.FdData, offset)\r
+ plist = list(pdata)\r
+ break\r
+\r
+ fsp = FspImage (fspoffset, fih, fihoffset, plist)\r
+ fsp.AppendFv (idx)\r
+ self.FspList.append(fsp)\r
+ flen = fsp.Fih.ImageSize - fv.FvHdr.FvLength\r
+ else:\r
+ fsp.AppendFv (idx)\r
+ flen -= fv.FvHdr.FvLength\r
+ if flen < 0:\r
+ raise Exception("ERROR: Incorrect FV size in image !")\r
+ self.CheckFsp ()\r
+\r
+class TeImage:\r
+ def __init__(self, offset, tedata):\r
+ self.Offset = offset\r
+ self.TeHdr = EFI_TE_IMAGE_HEADER.from_buffer (tedata, 0)\r
+ self.TeData = tedata\r
+ self.RelocList = []\r
+\r
+ def ParseReloc(self):\r
+ rsize = self.TeHdr.DataDirectoryBaseReloc.Size\r
+ roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress\r
+ alignment = 4\r
+ offset = roffset\r
+ while offset < roffset + rsize:\r
+ offset = AlignPtr(offset, 4)\r
+ blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.TeData, offset)\r
+ offset += sizeof(blkhdr)\r
+ # Read relocation type,offset pairs\r
+ rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)\r
+ rnum = rlen/sizeof(c_uint16)\r
+ rdata = (c_uint16 * rnum).from_buffer(self.TeData, offset)\r
+ for each in rdata:\r
+ roff = each & 0xfff\r
+ rtype = each >> 12\r
+ if rtype == 0: # IMAGE_REL_BASED.ABSOLUTE:\r
+ continue\r
+ if rtype != 3: # IMAGE_REL_BASED_HIGHLOW\r
+ raise Exception("ERROR: Unsupported relocation type %d!" % rtype)\r
+ # Calculate the offset of the relocation\r
+ aoff = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + blkhdr.PageRVA + roff\r
+ self.RelocList.append((rtype, aoff))\r
+ offset += sizeof(rdata)\r
+\r
+ def Rebase(self, delta, fdbin):\r
+ count = 0\r
+ if delta == 0:\r
+ return count\r
+\r
+ for (rtype, roff) in self.RelocList:\r
+ if rtype == 0x03: # HIGHLOW\r
+ offset = roff + self.Offset\r
+ value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])\r
+ value += delta\r
+ fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))\r
+ count += 1\r
+ else:\r
+ raise Exception('ERROR: Unknown relocation type %d !' % rtype)\r
+\r
+ tehdr = self.TeHdr\r
+ tehdr.ImageBase += delta\r
+ offset = self.Offset\r
+ fdbin[offset:offset+sizeof(tehdr)] = bytearray(tehdr)\r
+\r
+ return count\r