]>
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, 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.
21 from optparse
import OptionParser
22 from optparse
import make_option
23 from Common
.BuildToolError
import *
24 import Common
.EdkLogger
as EdkLogger
25 from Common
.BuildVersion
import gBUILD_VERSION
28 # Version and Copyright
29 __version_number__
= ("0.10" + " " + gBUILD_VERSION
)
30 __version__
= "%prog Version " + __version_number__
31 __copyright__
= "Copyright (c) 2010, Intel Corporation. All rights reserved."
33 ## PatchBinaryFile method
35 # This method mainly patches the data into binary file.
37 # @param FileName File path of the binary file
38 # @param ValueOffset Offset value
39 # @param TypeName DataType Name
40 # @param Value Value String
41 # @param MaxSize MaxSize value
43 # @retval 0 File is updated successfully.
44 # @retval not 0 File is updated failed.
46 def PatchBinaryFile(FileName
, ValueOffset
, TypeName
, ValueString
, MaxSize
=0):
48 # Length of Binary File
50 FileHandle
= open (FileName
, 'rb')
51 FileHandle
.seek (0, 2)
52 FileLength
= FileHandle
.tell()
55 # Unify string to upper string
57 TypeName
= TypeName
.upper()
59 # Get PCD value data length
62 if TypeName
== 'BOOLEAN':
64 elif TypeName
== 'UINT8':
66 elif TypeName
== 'UINT16':
68 elif TypeName
== 'UINT32':
70 elif TypeName
== 'UINT64':
72 elif TypeName
== 'VOID*':
74 return OPTION_MISSING
, "PcdMaxSize is not specified for VOID* type PCD."
75 ValueLength
= int(MaxSize
)
77 return PARAMETER_INVALID
, "PCD type %s is not valid." %(CommandOptions
.PcdTypeName
)
79 # Check PcdValue is in the input binary file.
81 if ValueOffset
+ ValueLength
> FileLength
:
82 return PARAMETER_INVALID
, "PcdOffset + PcdMaxSize(DataType) is larger than the input file size."
84 # Read binary file into array
86 FileHandle
= open (FileName
, 'rb')
87 ByteArray
= array
.array('B')
88 ByteArray
.fromfile(FileHandle
, FileLength
)
90 OrigByteList
= ByteArray
.tolist()
91 ByteList
= ByteArray
.tolist()
93 # Clear the data in file
95 for Index
in range(ValueLength
):
96 ByteList
[ValueOffset
+ Index
] = 0
98 # Patch value into offset
100 SavedStr
= ValueString
101 ValueString
= ValueString
.upper()
103 if TypeName
== 'BOOLEAN':
105 # Get PCD value for BOOLEAN data type
108 if ValueString
== 'TRUE':
110 elif ValueString
== 'FALSE':
112 elif ValueString
.startswith('0X'):
113 ValueNumber
= int (ValueString
, 16)
115 ValueNumber
= int (ValueString
)
119 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string." %(ValueString)
121 # Set PCD value into binary data
123 ByteList
[ValueOffset
] = ValueNumber
124 elif TypeName
in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
126 # Get PCD value for UINT* data type
129 if ValueString
.startswith('0X'):
130 ValueNumber
= int (ValueString
, 16)
132 ValueNumber
= int (ValueString
)
134 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string." %(ValueString)
136 # Set PCD value into binary data
138 for Index
in range(ValueLength
):
139 ByteList
[ValueOffset
+ Index
] = ValueNumber
% 0x100
140 ValueNumber
= ValueNumber
/ 0x100
141 elif TypeName
== 'VOID*':
142 ValueString
= SavedStr
143 if ValueString
.startswith('L"'):
145 # Patch Unicode String
148 for ByteString
in ValueString
[2:-1]:
150 # Reserve zero as unicode tail
152 if Index
+ 2 >= ValueLength
:
155 # Set string value one by one
157 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
159 elif ValueString
.startswith("{") and ValueString
.endswith("}"):
161 # Patch {0x1, 0x2, ...} byte by byte
163 ValueList
= ValueString
[1 : len(ValueString
) - 1].split(', ')
166 for ByteString
in ValueList
:
167 if ByteString
.upper().startswith('0X'):
168 ByteValue
= int(ByteString
, 16)
170 ByteValue
= int(ByteString
)
171 ByteList
[ValueOffset
+ Index
] = ByteValue
% 0x100
173 if Index
>= ValueLength
:
176 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string array." %(ValueString)
182 for ByteString
in ValueString
[1:-1]:
184 # Reserve zero as string tail
186 if Index
+ 1 >= ValueLength
:
189 # Set string value one by one
191 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
194 # Update new data into input file.
196 if ByteList
!= OrigByteList
:
197 ByteArray
= array
.array('B')
198 ByteArray
.fromlist(ByteList
)
199 FileHandle
= open (FileName
, 'wb')
200 ByteArray
.tofile(FileHandle
)
202 return 0, "Patch Value into File %s successfully." %(FileName)
204 ## Parse command line options
206 # Using standard Python module optparse to parse command line option of this tool.
208 # @retval Options A optparse.Values object containing the parsed options
209 # @retval InputFile Path of file to be trimmed
213 make_option("-f", "--offset", dest
="PcdOffset", action
="store", type="int",
214 help="Start offset to the image is used to store PCD value."),
215 make_option("-u", "--value", dest
="PcdValue", action
="store",
216 help="PCD value will be updated into the image."),
217 make_option("-t", "--type", dest
="PcdTypeName", action
="store",
218 help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."),
219 make_option("-s", "--maxsize", dest
="PcdMaxSize", action
="store", type="int",
220 help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."),
221 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
222 help="Run verbosely"),
223 make_option("-d", "--debug", dest
="LogLevel", type="int",
224 help="Run with debug information"),
225 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
227 make_option("-?", action
="help", help="show this help message and exit"),
230 # use clearer usage to override default usage message
231 UsageString
= "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>"
233 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
234 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
236 Options
, Args
= Parser
.parse_args()
240 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
=Parser
.get_usage())
242 InputFile
= Args
[len(Args
) - 1]
243 return Options
, InputFile
247 # This method mainly dispatch specific methods per the command line options.
248 # If no error found, return zero value so the caller of this tool can know
249 # if it's executed successfully or not.
251 # @retval 0 Tool was successful
252 # @retval 1 Tool failed
257 # Check input parameter
259 EdkLogger
.Initialize()
260 CommandOptions
, InputFile
= Options()
261 if CommandOptions
.LogLevel
< EdkLogger
.DEBUG_9
:
262 EdkLogger
.SetLevel(CommandOptions
.LogLevel
+ 1)
264 EdkLogger
.SetLevel(CommandOptions
.LogLevel
)
265 if not os
.path
.exists (InputFile
):
266 EdkLogger
.error("PatchPcdValue", FILE_NOT_FOUND
, ExtraData
=InputFile
)
268 if CommandOptions
.PcdOffset
== None or CommandOptions
.PcdValue
== None or CommandOptions
.PcdTypeName
== None:
269 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdOffset or PcdValue of PcdTypeName is not specified.")
271 if CommandOptions
.PcdTypeName
.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]:
272 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
="PCD type %s is not valid." %(CommandOptions
.PcdTypeName
))
274 if CommandOptions
.PcdTypeName
.upper() == "VOID*" and CommandOptions
.PcdMaxSize
== None:
275 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdMaxSize is not specified for VOID* type PCD.")
278 # Patch value into binary image.
280 ReturnValue
, ErrorInfo
= PatchBinaryFile (InputFile
, CommandOptions
.PcdOffset
, CommandOptions
.PcdTypeName
, CommandOptions
.PcdValue
, CommandOptions
.PcdMaxSize
)
282 EdkLogger
.error("PatchPcdValue", ReturnValue
, ExtraData
=ErrorInfo
)
288 if __name__
== '__main__':