]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
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 ByteString
= ByteString
.strip()
169 if ByteString
.upper().startswith('0X'):
170 ByteValue
= int(ByteString
, 16)
172 ByteValue
= int(ByteString
)
173 ByteList
[ValueOffset
+ Index
] = ByteValue
% 0x100
175 if Index
>= ValueLength
:
178 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string array." % (ValueString
)
184 for ByteString
in ValueString
[1:-1]:
186 # Reserve zero as string tail
188 if Index
+ 1 >= ValueLength
:
191 # Set string value one by one
193 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
196 # Update new data into input file.
198 if ByteList
!= OrigByteList
:
199 ByteArray
= array
.array('B')
200 ByteArray
.fromlist(ByteList
)
201 FileHandle
= open(FileName
, 'wb')
202 ByteArray
.tofile(FileHandle
)
204 return 0, "Patch Value into File %s successfully." % (FileName
)
206 ## Parse command line options
208 # Using standard Python module optparse to parse command line option of this tool.
210 # @retval Options A optparse.Values object containing the parsed options
211 # @retval InputFile Path of file to be trimmed
215 make_option("-f", "--offset", dest
="PcdOffset", action
="store", type="int",
216 help="Start offset to the image is used to store PCD value."),
217 make_option("-u", "--value", dest
="PcdValue", action
="store",
218 help="PCD value will be updated into the image."),
219 make_option("-t", "--type", dest
="PcdTypeName", action
="store",
220 help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."),
221 make_option("-s", "--maxsize", dest
="PcdMaxSize", action
="store", type="int",
222 help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."),
223 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
224 help="Run verbosely"),
225 make_option("-d", "--debug", dest
="LogLevel", type="int",
226 help="Run with debug information"),
227 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
229 make_option("-?", action
="help", help="show this help message and exit"),
232 # use clearer usage to override default usage message
233 UsageString
= "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>"
235 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
236 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
238 Options
, Args
= Parser
.parse_args()
242 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
=Parser
.get_usage())
244 InputFile
= Args
[len(Args
) - 1]
245 return Options
, InputFile
249 # This method mainly dispatch specific methods per the command line options.
250 # If no error found, return zero value so the caller of this tool can know
251 # if it's executed successfully or not.
253 # @retval 0 Tool was successful
254 # @retval 1 Tool failed
259 # Check input parameter
261 EdkLogger
.Initialize()
262 CommandOptions
, InputFile
= Options()
263 if CommandOptions
.LogLevel
< EdkLogger
.DEBUG_9
:
264 EdkLogger
.SetLevel(CommandOptions
.LogLevel
+ 1)
266 EdkLogger
.SetLevel(CommandOptions
.LogLevel
)
267 if not os
.path
.exists (InputFile
):
268 EdkLogger
.error("PatchPcdValue", FILE_NOT_FOUND
, ExtraData
=InputFile
)
270 if CommandOptions
.PcdOffset
== None or CommandOptions
.PcdValue
== None or CommandOptions
.PcdTypeName
== None:
271 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdOffset or PcdValue of PcdTypeName is not specified.")
273 if CommandOptions
.PcdTypeName
.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]:
274 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
="PCD type %s is not valid." % (CommandOptions
.PcdTypeName
))
276 if CommandOptions
.PcdTypeName
.upper() == "VOID*" and CommandOptions
.PcdMaxSize
== None:
277 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdMaxSize is not specified for VOID* type PCD.")
280 # Patch value into binary image.
282 ReturnValue
, ErrorInfo
= PatchBinaryFile (InputFile
, CommandOptions
.PcdOffset
, CommandOptions
.PcdTypeName
, CommandOptions
.PcdValue
, CommandOptions
.PcdMaxSize
)
284 EdkLogger
.error("PatchPcdValue", ReturnValue
, ExtraData
=ErrorInfo
)
290 if __name__
== '__main__':