]>
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 ValueNumber
= int (ValueString
, 0)
117 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string." % (ValueString
)
119 # Set PCD value into binary data
121 ByteList
[ValueOffset
] = ValueNumber
122 elif TypeName
in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
124 # Get PCD value for UINT* data type
127 ValueNumber
= int (ValueString
, 0)
129 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string." % (ValueString
)
131 # Set PCD value into binary data
133 for Index
in range(ValueLength
):
134 ByteList
[ValueOffset
+ Index
] = ValueNumber
% 0x100
135 ValueNumber
= ValueNumber
/ 0x100
136 elif TypeName
== 'VOID*':
137 ValueString
= SavedStr
138 if ValueString
.startswith('L"'):
140 # Patch Unicode String
143 for ByteString
in ValueString
[2:-1]:
145 # Reserve zero as unicode tail
147 if Index
+ 2 >= ValueLength
:
150 # Set string value one by one
152 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
154 elif ValueString
.startswith("{") and ValueString
.endswith("}"):
156 # Patch {0x1, 0x2, ...} byte by byte
158 ValueList
= ValueString
[1 : len(ValueString
) - 1].split(',')
161 for ByteString
in ValueList
:
162 ByteString
= ByteString
.strip()
163 if ByteString
.upper().startswith('0X'):
164 ByteValue
= int(ByteString
, 16)
166 ByteValue
= int(ByteString
)
167 ByteList
[ValueOffset
+ Index
] = ByteValue
% 0x100
169 if Index
>= ValueLength
:
172 return PARAMETER_INVALID
, "PCD Value %s is not valid dec or hex string array." % (ValueString
)
178 for ByteString
in ValueString
[1:-1]:
180 # Reserve zero as string tail
182 if Index
+ 1 >= ValueLength
:
185 # Set string value one by one
187 ByteList
[ValueOffset
+ Index
] = ord(ByteString
)
190 # Update new data into input file.
192 if ByteList
!= OrigByteList
:
193 ByteArray
= array
.array('B')
194 ByteArray
.fromlist(ByteList
)
195 FileHandle
= open(FileName
, 'wb')
196 ByteArray
.tofile(FileHandle
)
198 return 0, "Patch Value into File %s successfully." % (FileName
)
200 ## Parse command line options
202 # Using standard Python module optparse to parse command line option of this tool.
204 # @retval Options A optparse.Values object containing the parsed options
205 # @retval InputFile Path of file to be trimmed
209 make_option("-f", "--offset", dest
="PcdOffset", action
="store", type="int",
210 help="Start offset to the image is used to store PCD value."),
211 make_option("-u", "--value", dest
="PcdValue", action
="store",
212 help="PCD value will be updated into the image."),
213 make_option("-t", "--type", dest
="PcdTypeName", action
="store",
214 help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."),
215 make_option("-s", "--maxsize", dest
="PcdMaxSize", action
="store", type="int",
216 help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."),
217 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
218 help="Run verbosely"),
219 make_option("-d", "--debug", dest
="LogLevel", type="int",
220 help="Run with debug information"),
221 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
223 make_option("-?", action
="help", help="show this help message and exit"),
226 # use clearer usage to override default usage message
227 UsageString
= "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>"
229 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
230 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
232 Options
, Args
= Parser
.parse_args()
236 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
=Parser
.get_usage())
238 InputFile
= Args
[len(Args
) - 1]
239 return Options
, InputFile
243 # This method mainly dispatch specific methods per the command line options.
244 # If no error found, return zero value so the caller of this tool can know
245 # if it's executed successfully or not.
247 # @retval 0 Tool was successful
248 # @retval 1 Tool failed
253 # Check input parameter
255 EdkLogger
.Initialize()
256 CommandOptions
, InputFile
= Options()
257 if CommandOptions
.LogLevel
< EdkLogger
.DEBUG_9
:
258 EdkLogger
.SetLevel(CommandOptions
.LogLevel
+ 1)
260 EdkLogger
.SetLevel(CommandOptions
.LogLevel
)
261 if not os
.path
.exists (InputFile
):
262 EdkLogger
.error("PatchPcdValue", FILE_NOT_FOUND
, ExtraData
=InputFile
)
264 if CommandOptions
.PcdOffset
is None or CommandOptions
.PcdValue
is None or CommandOptions
.PcdTypeName
is None:
265 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdOffset or PcdValue of PcdTypeName is not specified.")
267 if CommandOptions
.PcdTypeName
.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]:
268 EdkLogger
.error("PatchPcdValue", PARAMETER_INVALID
, ExtraData
="PCD type %s is not valid." % (CommandOptions
.PcdTypeName
))
270 if CommandOptions
.PcdTypeName
.upper() == "VOID*" and CommandOptions
.PcdMaxSize
is None:
271 EdkLogger
.error("PatchPcdValue", OPTION_MISSING
, ExtraData
="PcdMaxSize is not specified for VOID* type PCD.")
274 # Patch value into binary image.
276 ReturnValue
, ErrorInfo
= PatchBinaryFile (InputFile
, CommandOptions
.PcdOffset
, CommandOptions
.PcdTypeName
, CommandOptions
.PcdValue
, CommandOptions
.PcdMaxSize
)
278 EdkLogger
.error("PatchPcdValue", ReturnValue
, ExtraData
=ErrorInfo
)
284 if __name__
== '__main__':