]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py
ca4440f9a2ddb5bb6a761190f81d86c3f48a21ba
2 # Generate PCD table for 'Patchable In Module' type PCD with given .map file.
3 # The Patch PCD table like:
5 # PCD Name Offset in binary
6 # ======== ================
8 # Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
9 # This program and the accompanying materials
10 # are licensed and made available under the terms and conditions of the BSD License
11 # which accompanies this distribution. The full text of the license may be found at
12 # http://opensource.org/licenses/bsd-license.php
14 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #====================================== External Libraries ========================================
25 from Common
.BuildToolError
import *
26 import Common
.EdkLogger
as EdkLogger
27 from Common
.Misc
import PeImageClass
28 from Common
.BuildVersion
import gBUILD_VERSION
30 # Version and Copyright
31 __version_number__
= ("0.10" + " " + gBUILD_VERSION
)
32 __version__
= "%prog Version " + __version_number__
33 __copyright__
= "Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved."
35 #====================================== Internal Libraries ========================================
37 #============================================== Code ===============================================
38 secRe
= re
.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\da-fA-F]+)[Hh]? +([.\w\$]+) +(\w+)', re
.UNICODE
)
39 symRe
= re
.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\.:\\\\\w\?@\$]+) +([\da-fA-F]+)', re
.UNICODE
)
41 def parsePcdInfoFromMapFile(mapfilepath
, efifilepath
):
42 """ Parse map file to get binary patch pcd information
43 @param path Map file absolution path
45 @return a list which element hold (PcdName, Offset, SectionName)
49 f
= open(mapfilepath
, 'r')
55 if len(lines
) == 0: return None
56 if lines
[0].strip().find("Archive member included because of file (symbol)") != -1:
57 return _parseForGCC(lines
)
58 return _parseGeneral(lines
, efifilepath
)
60 def _parseForGCC(lines
):
61 """ Parse map file generated by GCC linker """
64 lastSectionName
= None
68 # status machine transection
69 if status
== 0 and line
== "Linker script and memory map":
72 elif status
== 1 and line
== 'START GROUP':
78 m
= re
.match('^[\da-fA-FxhH]+ +__image_base__ += +([\da-fA-FhxH]+)', line
)
80 imageBase
= int(m
.groups(0)[0], 16)
82 m
= re
.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)', line
)
84 lastSectionName
= m
.groups(0)[0]
86 m
= re
.match("^([\da-fA-Fx]+) +[_]+gPcd_BinaryPatch_([\w_\d]+)", line
)
88 assert imageBase
!= -1, "Fail to get Binary PCD offsest for unknown image base address"
89 pcds
.append((m
.groups(0)[1], int(m
.groups(0)[0], 16) - imageBase
, lastSectionName
))
92 def _parseGeneral(lines
, efifilepath
):
93 """ For MSFT, ICC, EBC
94 @param lines line array for map file
96 @return a list which element hold (PcdName, Offset, SectionName)
98 status
= 0 #0 - beginning of file; 1 - PE section definition; 2 - symbol table
99 secs
= [] # key = section name
105 if re
.match("^Start[' ']+Length[' ']+Name[' ']+Class", line
):
108 if re
.match("^Address[' ']+Publics by Value[' ']+Rva\+Base", line
):
111 if re
.match("^entry point at", line
):
114 if status
== 1 and len(line
) != 0:
115 m
= secRe
.match(line
)
116 assert m
!= None, "Fail to parse the section in map file , line is %s" % line
117 sec_no
, sec_start
, sec_length
, sec_name
, sec_class
= m
.groups(0)
118 secs
.append([int(sec_no
, 16), int(sec_start
, 16), int(sec_length
, 16), sec_name
, sec_class
])
119 if status
== 2 and len(line
) != 0:
120 m
= symRe
.match(line
)
121 assert m
!= None, "Fail to parse the symbol in map file, line is %s" % line
122 sec_no
, sym_offset
, sym_name
, vir_addr
= m
.groups(0)
123 sec_no
= int(sec_no
, 16)
124 sym_offset
= int(sym_offset
, 16)
125 vir_addr
= int(vir_addr
, 16)
126 m2
= re
.match('^[_]+gPcd_BinaryPatch_([\w]+)', sym_name
)
128 # fond a binary pcd entry in map file
130 if sec
[0] == sec_no
and (sym_offset
>= sec
[1] and sym_offset
< sec
[1] + sec
[2]):
131 bPcds
.append([m2
.groups(0)[0], sec
[3], sym_offset
, vir_addr
, sec_no
])
133 if len(bPcds
) == 0: return None
135 # get section information from efi file
136 efisecs
= PeImageClass(efifilepath
).SectionHeaderList
137 if efisecs
== None or len(efisecs
) == 0:
143 for efisec
in efisecs
:
145 if pcd
[1].strip() == efisec
[0].strip():
146 pcds
.append([pcd
[0], efisec
[2] + pcd
[2], efisec
[0]])
147 elif pcd
[4] == index
:
148 pcds
.append([pcd
[0], efisec
[2] + pcd
[2], efisec
[0]])
151 def generatePcdTable(list, pcdpath
):
153 f
= open(pcdpath
, 'w')
157 f
.write('PCD Name Offset Section Name\r\n')
160 f
.write('%-30s 0x%-08X %-6s\r\n' % (pcditem
[0], pcditem
[1], pcditem
[2]))
163 #print 'Success to generate Binary Patch PCD table at %s!' % pcdpath
165 if __name__
== '__main__':
166 UsageString
= "%prog -m <MapFile> -e <EfiFile> -o <OutFile>"
167 AdditionalNotes
= "\nPCD table is generated in file name with .BinaryPcdTable.txt postfix"
168 parser
= optparse
.OptionParser(description
=__copyright__
, version
=__version__
, usage
=UsageString
)
169 parser
.add_option('-m', '--mapfile', action
='store', dest
='mapfile',
170 help='Absolute path of module map file.')
171 parser
.add_option('-e', '--efifile', action
='store', dest
='efifile',
172 help='Absolute path of EFI binary file.')
173 parser
.add_option('-o', '--outputfile', action
='store', dest
='outfile',
174 help='Absolute path of output file to store the got patchable PCD table.')
176 (options
, args
) = parser
.parse_args()
178 if options
.mapfile
== None or options
.efifile
== None:
179 print parser
.get_usage()
180 elif os
.path
.exists(options
.mapfile
) and os
.path
.exists(options
.efifile
):
181 list = parsePcdInfoFromMapFile(options
.mapfile
, options
.efifile
)
183 if options
.outfile
!= None:
184 generatePcdTable(list, options
.outfile
)
186 generatePcdTable(list, options
.mapfile
.replace('.map', '.BinaryPcdTable.txt'))
188 print 'Fail to generate Patch PCD Table based on map file and efi file'
190 print 'Fail to generate Patch PCD Table for fail to find map file or efi file!'