]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
882da81930da267e02ba412fe9c4a69feb5b2bd8
2 # Patch value into the binary file.
4 # Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 import Common
.LongFilePathOs
as os
18 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
22 from optparse
import OptionParser
23 from optparse
import make_option
24 from Common
.BuildToolError
import *
25 import Common
.EdkLogger
as EdkLogger
26 from Common
.BuildVersion
import gBUILD_VERSION
29 # Version and Copyright
30 __version_number__
= ("0.10" + " " + gBUILD_VERSION
)
31 __version__
= "%prog Version " + __version_number__
32 __copyright__
= "Copyright (c) 2010, Intel Corporation. All rights reserved."
34 ## PatchBinaryFile method
36 # This method mainly patches the data into binary file.
38 # @param FileName File path of the binary file
39 # @param ValueOffset Offset value
40 # @param TypeName DataType Name
41 # @param Value Value String
42 # @param MaxSize MaxSize value
44 # @retval 0 File is updated successfully.
45 # @retval not 0 File is updated failed.
47 def PatchBinaryFile(FileName
, ValueOffset
, TypeName
, ValueString
, MaxSize
=0):
49 # Length of Binary File
51 FileHandle
= open(FileName
, 'rb')
52 FileHandle
.seek (0, 2)
53 FileLength
= FileHandle
.tell()
56 # Unify string to upper string
58 TypeName
= TypeName
.upper()
60 # Get PCD value data length
63 if TypeName
== 'BOOLEAN':
65 elif TypeName
== 'UINT8':
67 elif TypeName
== 'UINT16':
69 elif TypeName
== 'UINT32':
71 elif TypeName
== 'UINT64':
73 elif TypeName
== 'VOID*':
75 return OPTION_MISSING
, "PcdMaxSize is not specified for VOID* type PCD."
76 ValueLength
= int(MaxSize
)
78 return PARAMETER_INVALID
, "PCD type %s is not valid." % (CommandOptions
.PcdTypeName
)
80 # Check PcdValue is in the input binary file.
82 if ValueOffset
+ ValueLength
> FileLength
:
83 return PARAMETER_INVALID
, "PcdOffset + PcdMaxSize(DataType) is larger than the input file size."
85 # Read binary file into array
87 FileHandle
= open(FileName
, 'rb')
88 ByteArray
= array
.array('B')
89 ByteArray
.fromfile(FileHandle
, FileLength
)
91 OrigByteList
= ByteArray
.tolist()
92 ByteList
= ByteArray
.tolist()
94 # Clear the data in file
96 for Index
in range(ValueLength
):
97 ByteList
[ValueOffset
+ Index
] = 0
99 # Patch value into offset
101 SavedStr
= ValueString
102 ValueString
= ValueString
.upper()
104 if TypeName
== 'BOOLEAN':
106 # Get PCD value for BOOLEAN data type
109 if ValueString
== 'TRUE':
111 elif ValueString
== 'FALSE':
113 elif ValueString
.startswith('0X'):
114 ValueNumber
= int (ValueString
, 16)
116 ValueNumber
= int (ValueString
)
120 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string." % (ValueString
)
122 # Set PCD value into binary data
124 ByteList
[ValueOffset
] = ValueNumber
125 elif TypeName
in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
127 # Get PCD value for UINT* data type
130 if ValueString
.startswith('0X'):
131 ValueNumber
= int (ValueString
, 16)
133 ValueNumber
= int (ValueString
)
135 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string." % (ValueString
)
137 # Set PCD value into binary data
139 for Index
in range(ValueLength
):
140 ByteList
[ValueOffset
+ Index
] = ValueNumber
% 0x100
141 ValueNumber
= ValueNumber
/ 0x100
142 elif TypeName
== 'VOID*':
143 ValueString
= SavedStr
144 if ValueString
.startswith('L"'):
146 # Patch Unicode String
149 for ByteString
in ValueString
[2:-1]:
151 # Reserve zero as unicode tail
153 if Index
+ 2 >= ValueLength
:
156 # Set string value one by one
158 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
160 elif ValueString
.startswith("{") and ValueString
.endswith("}"):
162 # Patch {0x1, 0x2, ...} byte by byte
164 ValueList
= ValueString
[1 : len(ValueString
) - 1].split(', ')
167 for ByteString
in ValueList
:
168 if ByteString
.upper().startswith('0X'):
169 ByteValue
= int(ByteString
, 16)
171 ByteValue
= int(ByteString
)
172 ByteList
[ValueOffset
+ Index
] = ByteValue
% 0x100
174 if Index
>= ValueLength
:
177 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string array." % (ValueString
)
183 for ByteString
in ValueString
[1:-1]:
185 # Reserve zero as string tail
187 if Index
+ 1 >= ValueLength
:
190 # Set string value one by one
192 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
195 # Update new data into input file.
197 if ByteList
!= OrigByteList
:
198 ByteArray
= array
.array('B')
199 ByteArray
.fromlist(ByteList
)
200 FileHandle
= open(FileName
, 'wb')
201 ByteArray
.tofile(FileHandle
)
203 return 0, "Patch Value into File %s successfully." % (FileName
)
205 ## Parse command line options
207 # Using standard Python module optparse to parse command line option of this tool.
209 # @retval Options A optparse.Values object containing the parsed options
210 # @retval InputFile Path of file to be trimmed
214 make_option("-f", "--offset", dest
="PcdOffset", action
="store", type="int",
215 help="Start offset to the image is used to store PCD value."),
216 make_option("-u", "--value", dest
="PcdValue", action
="store",
217 help="PCD value will be updated into the image."),
218 make_option("-t", "--type", dest
="PcdTypeName", action
="store",
219 help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."),
220 make_option("-s", "--maxsize", dest
="PcdMaxSize", action
="store", type="int",
221 help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."),
222 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
223 help="Run verbosely"),
224 make_option("-d", "--debug", dest
="LogLevel", type="int",
225 help="Run with debug information"),
226 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
228 make_option("-?", action
="help", help="show this help message and exit"),
231 # use clearer usage to override default usage message
232 UsageString
= "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>"
234 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
235 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
237 Options
, Args
= Parser
.parse_args()
241 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
=Parser
.get_usage())
243 InputFile
= Args
[len(Args
) - 1]
244 return Options
, InputFile
248 # This method mainly dispatch specific methods per the command line options.
249 # If no error found, return zero value so the caller of this tool can know
250 # if it's executed successfully or not.
252 # @retval 0 Tool was successful
253 # @retval 1 Tool failed
258 # Check input parameter
260 EdkLogger
.Initialize()
261 CommandOptions
, InputFile
= Options()
262 if CommandOptions
.LogLevel
< EdkLogger
.DEBUG_9
:
263 EdkLogger
.SetLevel(CommandOptions
.LogLevel
+ 1)
265 EdkLogger
.SetLevel(CommandOptions
.LogLevel
)
266 if not os
.path
.exists (InputFile
):
267 EdkLogger
.error("PatchPcdValue", FILE_NOT_FOUND
, ExtraData
=InputFile
)
269 if CommandOptions
.PcdOffset
== None or CommandOptions
.PcdValue
== None or CommandOptions
.PcdTypeName
== None:
270 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdOffset or PcdValue of PcdTypeName is not specified.")
272 if CommandOptions
.PcdTypeName
.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]:
273 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
="PCD type %s is not valid." % (CommandOptions
.PcdTypeName
))
275 if CommandOptions
.PcdTypeName
.upper() == "VOID*" and CommandOptions
.PcdMaxSize
== None:
276 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdMaxSize is not specified for VOID* type PCD.")
279 # Patch value into binary image.
281 ReturnValue
, ErrorInfo
= PatchBinaryFile (InputFile
, CommandOptions
.PcdOffset
, CommandOptions
.PcdTypeName
, CommandOptions
.PcdValue
, CommandOptions
.PcdMaxSize
)
283 EdkLogger
.error("PatchPcdValue", ReturnValue
, ExtraData
=ErrorInfo
)
289 if __name__
== '__main__':