1## @ PatchBfv.py
2#
3# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
4# SPDX-License-Identifier: BSD-2-Clause-Patent
5#
6##
7
8import os
9import re
10import sys
11import time
12import shutil
13import struct
14import binascii
15from   ctypes import *
16
17class FileChecker:
18    def __init__(self):
19        self.fdName = ""
20        self.reportFile = ""
21        self.pcd = ["", "", ""]
22
23    def PrintPcd(self):
24        print "PCD: " + self.pcd[0] + "|" + self.pcd[1] + "(" + self.pcd[2] + ")"
25
26    def ProcessReport(self):
27        try :
28            file = open(self.reportFile)
29        except Exception:
30            print "fail to open " + self.reportFile
31            return
32        try:
33            file.seek(0)
34            print "checking - " + self.pcd[0]
35            ValuePair = self.GetPcdFromReport (file, self.pcd[0])
36            self.pcd[1] = ValuePair[0]
37            self.pcd[2] = ValuePair[1]
38        finally:
39            file.close()
40
41        self.PrintPcd()
42
43    def PatchFd(self):
44        fileName = self.fdName
45        print "patching BFV - " + fileName
46
47        try :
48            file = open(fileName, "rb")
49        except Exception:
50            print "fail to open " + fileName
51            return
52        try:
53            buffer = file.read()
54            data = bytearray(buffer)
55            file.close()
56
57            offset = -4
58
59            l = struct.pack("L", int(self.pcd[1],16))
60            print "  [" + hex(offset) + "] " + binascii.hexlify(data[-4:]) + " <= " + binascii.hexlify(l)
61            data[-4:] = l
62
63            file = open(fileName, "wb")
64            file.write(data[0:])
65        finally:
66            file.close()
67
68    def GetPcdFromReport(self, file, pcd):
69        FoundPkg = False
70        pcdSplit = pcd.split(".")
71        TargetPkg = pcdSplit[0]
72        TargetPcd = pcdSplit[1]
73        while 1:
74            line = file.readline()
75            if not line:
76                break
77
78            newline = line[:-1]
79
80            if (cmp (newline, TargetPkg) == 0):
81                FoundPkg = True
82                continue
83
84            if (cmp (newline, "") == 0) or ((cmp (newline[0], " ") != 0) and (cmp (newline[0], "0") != 0)):
85                FoundPkg = False
86
87            if (FoundPkg == True) :
88                newline = newline.strip()
89                splitLine = newline.split(" ", 2)
90                if (cmp (splitLine[0], "*F") == 0) or (cmp (splitLine[0], "*P") == 0) :
91                    if (cmp (splitLine[1], TargetPcd) == 0):
92                        print "found - " + TargetPkg + "." + TargetPcd
93
94                        splitLine = splitLine[2].strip()[1:].strip().split(" ", 1)
95                        if (cmp (splitLine[0], "FIXED") == 0) or (cmp (splitLine[0], "PATCH") == 0):
96                            SplitLine = splitLine[1].strip()[1:].split(")", 1)
97                            Type = SplitLine[0]
98                            Value = SplitLine[1].strip()[1:].strip().split()[0]
99                            print "  Type - (" + Type + "), Value - (" + Value + ")"
100                            return [Value, Type]
101        return ["", ""]
102
103def main():
104    global FileChecker
105
106    fileChecker = FileChecker()
107
108    if (len(sys.argv) != 4) :
109        print "usage: PatchBfv <FdFile> <ReportFile> <BfvPcdName>"
110        return 0
111
112    fileChecker.fdName = sys.argv[1]
113    fileChecker.reportFile = sys.argv[2]
114    fileChecker.pcd[0] = sys.argv[3]
115
116    fileChecker.ProcessReport ()
117    fileChecker.PatchFd ()
118
119if __name__ == '__main__':
120    sys.exit(main())
121