Accepting request 244672 from home:gary_lin:branches:Virtualization
- Amend the spec file to package the debug files for the source level debugging - Add gdb_uefi.py.in: the helper script to load the debug symbols - Update to R15801 and openssl 0.9.8za - Refresh OVMF-correct-debug-path.patch OBS-URL: https://build.opensuse.org/request/show/244672 OBS-URL: https://build.opensuse.org/package/show/Virtualization/ovmf?expand=0&rev=3
This commit is contained in:
parent
0b4a304504
commit
4fbbe447f6
365
gdb_uefi.py.in
Normal file
365
gdb_uefi.py.in
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
"""
|
||||||
|
Allows loading TianoCore symbols into a GDB session attached to EFI
|
||||||
|
Firmware.
|
||||||
|
|
||||||
|
This is how it works: build GdbSyms - it's a dummy binary that
|
||||||
|
contains the relevant symbols needed to find and load image symbols.
|
||||||
|
|
||||||
|
$ gdb
|
||||||
|
(gdb) taget remote ....
|
||||||
|
(gdb) source Scripts/gdb_uefi.py
|
||||||
|
(gdb) reload-uefi -o /path/to/GdbSyms.dll
|
||||||
|
|
||||||
|
The -o option should be used if you've debugging EFI, where the PE
|
||||||
|
images were converted from MACH-O or ELF binaries.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import array
|
||||||
|
import getopt
|
||||||
|
import binascii
|
||||||
|
import re
|
||||||
|
|
||||||
|
__license__ = "BSD"
|
||||||
|
__version = "1.0.0"
|
||||||
|
__maintainer__ = "Andrei Warkentin"
|
||||||
|
__email__ = "andrey.warkentin@gmail.com"
|
||||||
|
__status__ = "Works"
|
||||||
|
|
||||||
|
|
||||||
|
# FOR RPM PACKAGE replace the strings in the spec file
|
||||||
|
build_path="__BUILD_PATH__"
|
||||||
|
source_path="__SOURCE_PATH__"
|
||||||
|
gdb_src_path="__GDB_SRC_PATH__"
|
||||||
|
flavor="__FLAVOR__"
|
||||||
|
|
||||||
|
class ReloadUefi (gdb.Command):
|
||||||
|
"""Reload UEFI symbols"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# Various constants.
|
||||||
|
#
|
||||||
|
|
||||||
|
EINVAL = 0xffffffff
|
||||||
|
CV_NB10 = 0x3031424E
|
||||||
|
CV_RSDS = 0x53445352
|
||||||
|
CV_MTOC = 0x434F544D
|
||||||
|
DOS_MAGIC = 0x5A4D
|
||||||
|
PE32PLUS_MAGIC = 0x20b
|
||||||
|
EST_SIGNATURE = 0x5453595320494249L
|
||||||
|
DEBUG_GUID = [0x49152E77, 0x1ADA, 0x4764,
|
||||||
|
[0xB7,0xA2,0x7A,0xFE,
|
||||||
|
0xFE,0xD9,0x5E, 0x8B]]
|
||||||
|
DEBUG_IS_UPDATING = 0x1
|
||||||
|
|
||||||
|
#
|
||||||
|
# If the images were built as ELF/MACH-O and then converted to PE,
|
||||||
|
# then the base address needs to be offset by PE headers.
|
||||||
|
#
|
||||||
|
|
||||||
|
offset_by_headers = False
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
super (ReloadUefi, self).__init__ ("reload-uefi", gdb.COMMAND_OBSCURE)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns gdb.Type for a type.
|
||||||
|
#
|
||||||
|
|
||||||
|
def type (self, typename):
|
||||||
|
return gdb.lookup_type (typename)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns gdb.Type for a pointer to a type.
|
||||||
|
#
|
||||||
|
|
||||||
|
def ptype (self, typename):
|
||||||
|
return gdb.lookup_type (typename).pointer ()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Computes CRC32 on an array of data.
|
||||||
|
#
|
||||||
|
|
||||||
|
def crc32 (self, data):
|
||||||
|
return binascii.crc32 (data) & 0xFFFFFFFF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sets a field in a struct to a value, i.e.
|
||||||
|
# value->field_name = data.
|
||||||
|
#
|
||||||
|
# Newer Py bindings to Gdb provide access to the inferior
|
||||||
|
# memory, but not all, so have to do it this awkward way.
|
||||||
|
#
|
||||||
|
|
||||||
|
def set_field (self, value, field_name, data):
|
||||||
|
gdb.execute ("set *(%s *) 0x%x = 0x%x" % \
|
||||||
|
(str (value[field_name].type), \
|
||||||
|
long (value[field_name].address), \
|
||||||
|
data))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns data backing a gdb.Value as an array.
|
||||||
|
# Same comment as above regarding newer Py bindings...
|
||||||
|
#
|
||||||
|
|
||||||
|
def value_data (self, value, bytes=0):
|
||||||
|
value_address = gdb.Value (value.address)
|
||||||
|
array_t = self.ptype ('UINT8')
|
||||||
|
value_array = value_address.cast (array_t)
|
||||||
|
if bytes == 0:
|
||||||
|
bytes = value.type.sizeof
|
||||||
|
data = array.array ('B')
|
||||||
|
for i in range (0, bytes):
|
||||||
|
data.append (value_array[i])
|
||||||
|
return data
|
||||||
|
|
||||||
|
#
|
||||||
|
# Locates the EFI_SYSTEM_TABLE as per UEFI spec 17.4.
|
||||||
|
# Returns base address or -1.
|
||||||
|
#
|
||||||
|
|
||||||
|
def search_est (self):
|
||||||
|
address = 0
|
||||||
|
estp_t = self.ptype ('EFI_SYSTEM_TABLE_POINTER')
|
||||||
|
while True:
|
||||||
|
estp = gdb.Value(address).cast(estp_t)
|
||||||
|
if estp['Signature'] == self.EST_SIGNATURE:
|
||||||
|
oldcrc = long (estp['Crc32'])
|
||||||
|
self.set_field (estp, 'Crc32', 0)
|
||||||
|
newcrc = self.crc32 (self.value_data (estp.dereference (), 0))
|
||||||
|
self.set_field (estp, 'Crc32', long (oldcrc))
|
||||||
|
if newcrc == oldcrc:
|
||||||
|
return estp['EfiSystemTableBase']
|
||||||
|
|
||||||
|
address = address + 4*1024*1024
|
||||||
|
if long (address) == 0:
|
||||||
|
return gdb.Value(self.EINVAL)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Searches for a vendor-specific configuration table (in EST),
|
||||||
|
# given a vendor-specific table GUID. GUID is a list like -
|
||||||
|
# [32-bit, 16-bit, 16-bit, [8 bytes]]
|
||||||
|
#
|
||||||
|
|
||||||
|
def search_config (self, cfg_table, count, guid):
|
||||||
|
index = 0
|
||||||
|
while index != count:
|
||||||
|
cfg_entry = cfg_table[index]['VendorGuid']
|
||||||
|
if cfg_entry['Data1'] == guid[0] and \
|
||||||
|
cfg_entry['Data2'] == guid[1] and \
|
||||||
|
cfg_entry['Data3'] == guid[2] and \
|
||||||
|
self.value_data (cfg_entry['Data4']).tolist () == guid[3]:
|
||||||
|
return cfg_table[index]['VendorTable']
|
||||||
|
index = index + 1
|
||||||
|
return gdb.Value(self.EINVAL)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns a UTF16 string corresponding to a (CHAR16 *) value in EFI.
|
||||||
|
#
|
||||||
|
|
||||||
|
def parse_utf16 (self, value):
|
||||||
|
index = 0
|
||||||
|
data = array.array ('H')
|
||||||
|
while value[index] != 0:
|
||||||
|
data.append (value[index])
|
||||||
|
index = index + 1
|
||||||
|
return data.tostring ().decode ('utf-16')
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns offset of a field within structure. Useful
|
||||||
|
# for getting container of a structure.
|
||||||
|
#
|
||||||
|
|
||||||
|
def offsetof (self, typename, field):
|
||||||
|
t = gdb.Value (0).cast (self.ptype (typename))
|
||||||
|
return long (t[field].address)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns sizeof of a type.
|
||||||
|
#
|
||||||
|
|
||||||
|
def sizeof (self, typename):
|
||||||
|
return self.type (typename).sizeof
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the EFI_IMAGE_NT_HEADERS32 pointer, given
|
||||||
|
# an ImageBase address as a gdb.Value.
|
||||||
|
#
|
||||||
|
|
||||||
|
def pe_headers (self, imagebase):
|
||||||
|
dosh_t = self.ptype ('EFI_IMAGE_DOS_HEADER')
|
||||||
|
head_t = self.ptype ('EFI_IMAGE_OPTIONAL_HEADER_UNION')
|
||||||
|
dosh = imagebase.cast(dosh_t)
|
||||||
|
h_addr = imagebase
|
||||||
|
if dosh['e_magic'] == self.DOS_MAGIC:
|
||||||
|
h_addr = h_addr + dosh['e_lfanew']
|
||||||
|
return gdb.Value(h_addr).cast (head_t)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns True if pe_headers refer to a PE32+ image.
|
||||||
|
#
|
||||||
|
|
||||||
|
def pe_is_64 (self, pe_headers):
|
||||||
|
if pe_headers['Pe32']['OptionalHeader']['Magic'] == self.PE32PLUS_MAGIC:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the PE (not so) optional header.
|
||||||
|
#
|
||||||
|
|
||||||
|
def pe_optional (self, pe):
|
||||||
|
if self.pe_is_64 (pe):
|
||||||
|
return pe['Pe32Plus']['OptionalHeader']
|
||||||
|
else:
|
||||||
|
return pe['Pe32']['OptionalHeader']
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the symbol file name for a PE image.
|
||||||
|
#
|
||||||
|
|
||||||
|
def pe_parse_debug (self, pe):
|
||||||
|
opt = self.pe_optional (pe)
|
||||||
|
debug_dir_entry = opt['DataDirectory'][6]
|
||||||
|
dep = debug_dir_entry['VirtualAddress'] + opt['ImageBase']
|
||||||
|
dep = dep.cast (self.ptype ('EFI_IMAGE_DEBUG_DIRECTORY_ENTRY'))
|
||||||
|
cvp = dep.dereference ()['RVA'] + opt['ImageBase']
|
||||||
|
cvv = cvp.cast(self.ptype ('UINT32')).dereference ()
|
||||||
|
if cvv == self.CV_NB10:
|
||||||
|
return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY')
|
||||||
|
elif cvv == self.CV_RSDS:
|
||||||
|
return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY')
|
||||||
|
elif cvv == self.CV_MTOC:
|
||||||
|
return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY')
|
||||||
|
return gdb.Value(self.EINVAL)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parses an EFI_LOADED_IMAGE_PROTOCOL, figuring out the symbol file name.
|
||||||
|
# This file name is then appended to list of loaded symbols.
|
||||||
|
#
|
||||||
|
# TBD: Support TE images.
|
||||||
|
#
|
||||||
|
|
||||||
|
def parse_image (self, image, syms):
|
||||||
|
base = image['ImageBase']
|
||||||
|
pe = self.pe_headers (base)
|
||||||
|
opt = self.pe_optional (pe)
|
||||||
|
sym_name = self.pe_parse_debug (pe)
|
||||||
|
|
||||||
|
# For ELF and Mach-O-derived images...
|
||||||
|
if self.offset_by_headers:
|
||||||
|
base = base + opt['SizeOfHeaders']
|
||||||
|
if sym_name != self.EINVAL:
|
||||||
|
sym_name = sym_name.cast (self.ptype('CHAR8')).string ()
|
||||||
|
# Ignore the driver from qemu
|
||||||
|
if re.search (r"\.efidrv$", sym_name):
|
||||||
|
return
|
||||||
|
# FOR RPM PACKAGE substitute the build path
|
||||||
|
sym_name = re.sub(r"^"+re.escape(build_path), "/usr/lib/debug/"+flavor, sym_name)
|
||||||
|
sym_name = re.sub(r"\.dll$", ".debug", sym_name)
|
||||||
|
syms.append ("add-symbol-file %s 0x%x" % \
|
||||||
|
(sym_name,
|
||||||
|
long (base)))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parses table EFI_DEBUG_IMAGE_INFO structures, builds
|
||||||
|
# a list of add-symbol-file commands, and reloads debugger
|
||||||
|
# symbols.
|
||||||
|
#
|
||||||
|
|
||||||
|
def parse_edii (self, edii, count):
|
||||||
|
index = 0
|
||||||
|
syms = []
|
||||||
|
while index != count:
|
||||||
|
entry = edii[index]
|
||||||
|
if entry['ImageInfoType'].dereference () == 1:
|
||||||
|
entry = entry['NormalImage']
|
||||||
|
self.parse_image(entry['LoadedImageProtocolInstance'], syms)
|
||||||
|
else:
|
||||||
|
print "Skipping unknown EFI_DEBUG_IMAGE_INFO (Type 0x%x)" % \
|
||||||
|
entry['ImageInfoType'].dereference ()
|
||||||
|
index = index + 1
|
||||||
|
gdb.execute ("symbol-file")
|
||||||
|
print "Loading new symbols..."
|
||||||
|
for sym in syms:
|
||||||
|
print sym
|
||||||
|
gdb.execute (sym)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parses EFI_DEBUG_IMAGE_INFO_TABLE_HEADER, in order to load
|
||||||
|
# image symbols.
|
||||||
|
#
|
||||||
|
|
||||||
|
def parse_dh (self, dh):
|
||||||
|
dh_t = self.ptype ('EFI_DEBUG_IMAGE_INFO_TABLE_HEADER')
|
||||||
|
dh = dh.cast (dh_t)
|
||||||
|
print "DebugImageInfoTable @ 0x%x, 0x%x entries" \
|
||||||
|
% (long (dh['EfiDebugImageInfoTable']), dh['TableSize'])
|
||||||
|
if dh['UpdateStatus'] & self.DEBUG_IS_UPDATING:
|
||||||
|
print "EfiDebugImageInfoTable update in progress, retry later"
|
||||||
|
return
|
||||||
|
self.parse_edii (dh['EfiDebugImageInfoTable'], dh['TableSize'])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parses EFI_SYSTEM_TABLE, in order to load image symbols.
|
||||||
|
#
|
||||||
|
|
||||||
|
def parse_est (self, est):
|
||||||
|
est_t = self.ptype ('EFI_SYSTEM_TABLE')
|
||||||
|
est = est.cast (est_t)
|
||||||
|
print "Connected to %s (Rev. 0x%x)" % \
|
||||||
|
(self.parse_utf16 (est['FirmwareVendor']), \
|
||||||
|
long (est['FirmwareRevision']))
|
||||||
|
print "ConfigurationTable @ 0x%x, 0x%x entries" \
|
||||||
|
% (long (est['ConfigurationTable']), est['NumberOfTableEntries'])
|
||||||
|
|
||||||
|
dh = self.search_config(est['ConfigurationTable'],
|
||||||
|
est['NumberOfTableEntries'],
|
||||||
|
self.DEBUG_GUID)
|
||||||
|
if dh == self.EINVAL:
|
||||||
|
print "No EFI_DEBUG_IMAGE_INFO_TABLE_HEADER"
|
||||||
|
return
|
||||||
|
self.parse_dh (dh)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Usage information.
|
||||||
|
#
|
||||||
|
|
||||||
|
def usage (self):
|
||||||
|
print "Usage: reload-uefi [-o] /path/to/GdbSyms.dll"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Handler for reload-uefi.
|
||||||
|
#
|
||||||
|
|
||||||
|
def invoke (self, arg, from_tty):
|
||||||
|
args = arg.split(' ')
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(args, "o", ["offset-by-headers"])
|
||||||
|
except getopt.GetoptError, err:
|
||||||
|
self.usage ()
|
||||||
|
return
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt == "-o":
|
||||||
|
self.offset_by_headers = True
|
||||||
|
|
||||||
|
if len(args) < 1:
|
||||||
|
self.usage ()
|
||||||
|
return
|
||||||
|
|
||||||
|
# FOR RPM PACKAGE substitute the path of the source code
|
||||||
|
gdb.execute ("set substitute-path "+source_path+" "+gdb_src_path)
|
||||||
|
|
||||||
|
gdb.execute ("symbol-file")
|
||||||
|
gdb.execute ("symbol-file %s" % args[0])
|
||||||
|
est = self.search_est ()
|
||||||
|
if est == self.EINVAL:
|
||||||
|
print "No EFI_SYSTEM_TABLE..."
|
||||||
|
return
|
||||||
|
|
||||||
|
print "EFI_SYSTEM_TABLE @ 0x%x" % est
|
||||||
|
self.parse_est (est)
|
||||||
|
|
||||||
|
ReloadUefi ()
|
||||||
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:537411fe2cfe249a8a5b98b3f809a07ed5f913b94a216b3c510fd353318e4593
|
|
||||||
size 3782900
|
|
3
openssl-0.9.8za.tar.gz
Normal file
3
openssl-0.9.8za.tar.gz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:cdcb98d0fbc026ca798b17919334310271d3a593554ffd6a59659b9222fd4e48
|
||||||
|
size 3787508
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:7ce2f79593b29c3454c33b3cb19c4443bfbdfbdfeb21171dd0d354164522e985
|
|
||||||
size 21682516
|
|
3
ovmf-0.1+svn15801.tar.xz
Normal file
3
ovmf-0.1+svn15801.tar.xz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:65d58bf3a837e77229ec8f86f8d6434395a42eb5d3dde9db7497cc095f9891fc
|
||||||
|
size 21773372
|
@ -1,8 +1,10 @@
|
|||||||
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
|
---
|
||||||
index 06e7d65..5bd10f4 100644
|
BaseTools/Conf/tools_def.template | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
--- a/BaseTools/Conf/tools_def.template
|
--- a/BaseTools/Conf/tools_def.template
|
||||||
+++ b/BaseTools/Conf/tools_def.template
|
+++ b/BaseTools/Conf/tools_def.template
|
||||||
@@ -3120,7 +3120,7 @@ NOOPT_DDK3790xASL_IPF_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /LTCG /DLL /OPT:REF
|
@@ -3125,7 +3125,7 @@ NOOPT_DDK3790xASL_IPF_DLINK_FLAGS = /
|
||||||
*_*_*_OBJCOPY_FLAGS = objcopy not needed for
|
*_*_*_OBJCOPY_FLAGS = objcopy not needed for
|
||||||
*_*_*_SYMRENAME_PATH = echo
|
*_*_*_SYMRENAME_PATH = echo
|
||||||
*_*_*_SYMRENAME_FLAGS = Symbol renaming not needed for
|
*_*_*_SYMRENAME_FLAGS = Symbol renaming not needed for
|
||||||
@ -10,4 +12,4 @@ index 06e7d65..5bd10f4 100644
|
|||||||
+DEBUG_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink=$(DEBUG_DIR)/$(MODULE_NAME).debug
|
+DEBUG_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink=$(DEBUG_DIR)/$(MODULE_NAME).debug
|
||||||
RELEASE_*_*_OBJCOPY_ADDDEBUGFLAG =
|
RELEASE_*_*_OBJCOPY_ADDDEBUGFLAG =
|
||||||
|
|
||||||
DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -Wno-array-bounds -c -include AutoGen.h
|
DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -c -include AutoGen.h
|
||||||
|
544
ovmf-gdb-symbols.patch
Normal file
544
ovmf-gdb-symbols.patch
Normal file
@ -0,0 +1,544 @@
|
|||||||
|
diff --git a/DebugPkg/DebugPkg.dec b/DebugPkg/DebugPkg.dec
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e12401d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/DebugPkg/DebugPkg.dec
|
||||||
|
@@ -0,0 +1,34 @@
|
||||||
|
+## @file
|
||||||
|
+# Debug package - various useful stuff for debugging.
|
||||||
|
+#
|
||||||
|
+# Copyright (c) 2006 - 2011, Andrei Warkentin <andreiw@motorola.com>
|
||||||
|
+#
|
||||||
|
+# This program and the accompanying materials
|
||||||
|
+# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
+# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
+# http://opensource.org/licenses/bsd-license.php
|
||||||
|
+#
|
||||||
|
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
+#
|
||||||
|
+##
|
||||||
|
+
|
||||||
|
+[Defines]
|
||||||
|
+ DEC_VERSION = 0x00010005
|
||||||
|
+ PACKAGE_NAME = DebugPkg
|
||||||
|
+ PACKAGE_GUID = 2d234f34-50e5-4b9d-b8e3-5562334d87e5
|
||||||
|
+ PACKAGE_VERSION = 0.1
|
||||||
|
+
|
||||||
|
+[Includes]
|
||||||
|
+ Include
|
||||||
|
+
|
||||||
|
+[Guids]
|
||||||
|
+
|
||||||
|
+[Protocols]
|
||||||
|
+
|
||||||
|
+[PcdsFixedAtBuild]
|
||||||
|
+
|
||||||
|
+[PcdsDynamic]
|
||||||
|
+
|
||||||
|
+[LibraryClasses]
|
||||||
|
+
|
||||||
|
diff --git a/DebugPkg/GdbSyms/GdbSyms.c b/DebugPkg/GdbSyms/GdbSyms.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..2551dfa
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/DebugPkg/GdbSyms/GdbSyms.c
|
||||||
|
@@ -0,0 +1,70 @@
|
||||||
|
+/** @file
|
||||||
|
+
|
||||||
|
+ Bare-minimum GDB symbols needed for reloading symbols.
|
||||||
|
+
|
||||||
|
+ This is not a "driver" and should not be placed in a FD.
|
||||||
|
+
|
||||||
|
+ Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
|
||||||
|
+
|
||||||
|
+ This program and the accompanying materials
|
||||||
|
+ are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
+ which accompanies this distribution. The full text of the license may be found at
|
||||||
|
+ http://opensource.org/licenses/bsd-license.php
|
||||||
|
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#include "PiDxe.h"
|
||||||
|
+
|
||||||
|
+#include <Library/UefiLib.h>
|
||||||
|
+#include <Library/UefiDriverEntryPoint.h>
|
||||||
|
+#include <Library/BaseLib.h>
|
||||||
|
+#include <Library/UefiRuntimeLib.h>
|
||||||
|
+#include <Library/DebugLib.h>
|
||||||
|
+#include <Library/BaseMemoryLib.h>
|
||||||
|
+#include <Library/MemoryAllocationLib.h>
|
||||||
|
+#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
+#include <Library/DevicePathLib.h>
|
||||||
|
+#include <Library/PcdLib.h>
|
||||||
|
+#include <Guid/DebugImageInfoTable.h>
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Main entry point.
|
||||||
|
+
|
||||||
|
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||||
|
+ @param[in] SystemTable A pointer to the EFI System Table.
|
||||||
|
+
|
||||||
|
+ @retval EFI_SUCCESS Successfully initialized.
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+EFI_STATUS
|
||||||
|
+EFIAPI
|
||||||
|
+Initialize (
|
||||||
|
+ IN EFI_HANDLE ImageHandle,
|
||||||
|
+ IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ EFI_SYSTEM_TABLE_POINTER ESTP;
|
||||||
|
+ EFI_DEBUG_IMAGE_INFO_TABLE_HEADER EDIITH;
|
||||||
|
+ EFI_IMAGE_DOS_HEADER EIDH;
|
||||||
|
+ EFI_IMAGE_OPTIONAL_HEADER_UNION EIOHU;
|
||||||
|
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY EIDDE;
|
||||||
|
+ EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY EIDCNE;
|
||||||
|
+ EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY EIDCRE;
|
||||||
|
+ EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY EIDCME;
|
||||||
|
+ UINTN Dummy =
|
||||||
|
+ (UINTN) &ESTP |
|
||||||
|
+ (UINTN) &EDIITH |
|
||||||
|
+ (UINTN) &EIDH |
|
||||||
|
+ (UINTN) &EIOHU |
|
||||||
|
+ (UINTN) &EIDDE |
|
||||||
|
+ (UINTN) &EIDCNE |
|
||||||
|
+ (UINTN) &EIDCRE |
|
||||||
|
+ (UINTN) &EIDCME |
|
||||||
|
+ 1
|
||||||
|
+ ;
|
||||||
|
+ return !!Dummy & EFI_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
diff --git a/DebugPkg/GdbSyms/GdbSyms.inf b/DebugPkg/GdbSyms/GdbSyms.inf
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..afb7887
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/DebugPkg/GdbSyms/GdbSyms.inf
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+## @file
|
||||||
|
+#
|
||||||
|
+# Bare-minimum GDB symbols needed for reloading symbols.
|
||||||
|
+#
|
||||||
|
+# This is not a "driver" and should not be placed in a FD.
|
||||||
|
+#
|
||||||
|
+# Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
|
||||||
|
+#
|
||||||
|
+# This program and the accompanying materials
|
||||||
|
+# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
+# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
+# http://opensource.org/licenses/bsd-license.php
|
||||||
|
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
+#
|
||||||
|
+##
|
||||||
|
+
|
||||||
|
+[Defines]
|
||||||
|
+ INF_VERSION = 0x00010005
|
||||||
|
+ BASE_NAME = GdbSyms
|
||||||
|
+ FILE_GUID = 22abcb60-fb40-42ac-b01f-3ab1fad9aad8
|
||||||
|
+ MODULE_TYPE = DXE_DRIVER
|
||||||
|
+ VERSION_STRING = 1.0
|
||||||
|
+ ENTRY_POINT = Initialize
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# The following information is for reference only and not required by the build tools.
|
||||||
|
+#
|
||||||
|
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+[Sources]
|
||||||
|
+ GdbSyms.c
|
||||||
|
+
|
||||||
|
+[Packages]
|
||||||
|
+ MdePkg/MdePkg.dec
|
||||||
|
+ MdeModulePkg/MdeModulePkg.dec
|
||||||
|
+
|
||||||
|
+[LibraryClasses]
|
||||||
|
+ BaseLib
|
||||||
|
+ BaseMemoryLib
|
||||||
|
+ DebugLib
|
||||||
|
+ DxeServicesTableLib
|
||||||
|
+ HobLib
|
||||||
|
+ MemoryAllocationLib
|
||||||
|
+ PcdLib
|
||||||
|
+ UefiBootServicesTableLib
|
||||||
|
+ UefiDriverEntryPoint
|
||||||
|
+ UefiLib
|
||||||
|
+
|
||||||
|
+[Guids]
|
||||||
|
+
|
||||||
|
+[Protocols]
|
||||||
|
+
|
||||||
|
+[Depex]
|
||||||
|
+ TRUE
|
||||||
|
+
|
||||||
|
diff --git a/DebugPkg/Scripts/gdb_uefi.py b/DebugPkg/Scripts/gdb_uefi.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3db87a4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/DebugPkg/Scripts/gdb_uefi.py
|
||||||
|
@@ -0,0 +1,350 @@
|
||||||
|
+"""
|
||||||
|
+Allows loading TianoCore symbols into a GDB session attached to EFI
|
||||||
|
+Firmware.
|
||||||
|
+
|
||||||
|
+This is how it works: build GdbSyms - it's a dummy binary that
|
||||||
|
+contains the relevant symbols needed to find and load image symbols.
|
||||||
|
+
|
||||||
|
+$ gdb
|
||||||
|
+(gdb) taget remote ....
|
||||||
|
+(gdb) source Scripts/gdb_uefi.py
|
||||||
|
+(gdb) reload-uefi -o /path/to/GdbSyms.dll
|
||||||
|
+
|
||||||
|
+The -o option should be used if you've debugging EFI, where the PE
|
||||||
|
+images were converted from MACH-O or ELF binaries.
|
||||||
|
+
|
||||||
|
+"""
|
||||||
|
+
|
||||||
|
+import array
|
||||||
|
+import getopt
|
||||||
|
+import binascii
|
||||||
|
+import re
|
||||||
|
+
|
||||||
|
+__license__ = "BSD"
|
||||||
|
+__version = "1.0.0"
|
||||||
|
+__maintainer__ = "Andrei Warkentin"
|
||||||
|
+__email__ = "andrey.warkentin@gmail.com"
|
||||||
|
+__status__ = "Works"
|
||||||
|
+
|
||||||
|
+class ReloadUefi (gdb.Command):
|
||||||
|
+ """Reload UEFI symbols"""
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Various constants.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ EINVAL = 0xffffffff
|
||||||
|
+ CV_NB10 = 0x3031424E
|
||||||
|
+ CV_RSDS = 0x53445352
|
||||||
|
+ CV_MTOC = 0x434F544D
|
||||||
|
+ DOS_MAGIC = 0x5A4D
|
||||||
|
+ PE32PLUS_MAGIC = 0x20b
|
||||||
|
+ EST_SIGNATURE = 0x5453595320494249L
|
||||||
|
+ DEBUG_GUID = [0x49152E77, 0x1ADA, 0x4764,
|
||||||
|
+ [0xB7,0xA2,0x7A,0xFE,
|
||||||
|
+ 0xFE,0xD9,0x5E, 0x8B]]
|
||||||
|
+ DEBUG_IS_UPDATING = 0x1
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # If the images were built as ELF/MACH-O and then converted to PE,
|
||||||
|
+ # then the base address needs to be offset by PE headers.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ offset_by_headers = False
|
||||||
|
+
|
||||||
|
+ def __init__ (self):
|
||||||
|
+ super (ReloadUefi, self).__init__ ("reload-uefi", gdb.COMMAND_OBSCURE)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns gdb.Type for a type.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def type (self, typename):
|
||||||
|
+ return gdb.lookup_type (typename)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns gdb.Type for a pointer to a type.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def ptype (self, typename):
|
||||||
|
+ return gdb.lookup_type (typename).pointer ()
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Computes CRC32 on an array of data.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def crc32 (self, data):
|
||||||
|
+ return binascii.crc32 (data) & 0xFFFFFFFF
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Sets a field in a struct to a value, i.e.
|
||||||
|
+ # value->field_name = data.
|
||||||
|
+ #
|
||||||
|
+ # Newer Py bindings to Gdb provide access to the inferior
|
||||||
|
+ # memory, but not all, so have to do it this awkward way.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def set_field (self, value, field_name, data):
|
||||||
|
+ gdb.execute ("set *(%s *) 0x%x = 0x%x" % \
|
||||||
|
+ (str (value[field_name].type), \
|
||||||
|
+ long (value[field_name].address), \
|
||||||
|
+ data))
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns data backing a gdb.Value as an array.
|
||||||
|
+ # Same comment as above regarding newer Py bindings...
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def value_data (self, value, bytes=0):
|
||||||
|
+ value_address = gdb.Value (value.address)
|
||||||
|
+ array_t = self.ptype ('UINT8')
|
||||||
|
+ value_array = value_address.cast (array_t)
|
||||||
|
+ if bytes == 0:
|
||||||
|
+ bytes = value.type.sizeof
|
||||||
|
+ data = array.array ('B')
|
||||||
|
+ for i in range (0, bytes):
|
||||||
|
+ data.append (value_array[i])
|
||||||
|
+ return data
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Locates the EFI_SYSTEM_TABLE as per UEFI spec 17.4.
|
||||||
|
+ # Returns base address or -1.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def search_est (self):
|
||||||
|
+ address = 0
|
||||||
|
+ estp_t = self.ptype ('EFI_SYSTEM_TABLE_POINTER')
|
||||||
|
+ while True:
|
||||||
|
+ estp = gdb.Value(address).cast(estp_t)
|
||||||
|
+ if estp['Signature'] == self.EST_SIGNATURE:
|
||||||
|
+ oldcrc = long (estp['Crc32'])
|
||||||
|
+ self.set_field (estp, 'Crc32', 0)
|
||||||
|
+ newcrc = self.crc32 (self.value_data (estp.dereference (), 0))
|
||||||
|
+ self.set_field (estp, 'Crc32', long (oldcrc))
|
||||||
|
+ if newcrc == oldcrc:
|
||||||
|
+ return estp['EfiSystemTableBase']
|
||||||
|
+
|
||||||
|
+ address = address + 4*1024*1024
|
||||||
|
+ if long (address) == 0:
|
||||||
|
+ return gdb.Value(self.EINVAL)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Searches for a vendor-specific configuration table (in EST),
|
||||||
|
+ # given a vendor-specific table GUID. GUID is a list like -
|
||||||
|
+ # [32-bit, 16-bit, 16-bit, [8 bytes]]
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def search_config (self, cfg_table, count, guid):
|
||||||
|
+ index = 0
|
||||||
|
+ while index != count:
|
||||||
|
+ cfg_entry = cfg_table[index]['VendorGuid']
|
||||||
|
+ if cfg_entry['Data1'] == guid[0] and \
|
||||||
|
+ cfg_entry['Data2'] == guid[1] and \
|
||||||
|
+ cfg_entry['Data3'] == guid[2] and \
|
||||||
|
+ self.value_data (cfg_entry['Data4']).tolist () == guid[3]:
|
||||||
|
+ return cfg_table[index]['VendorTable']
|
||||||
|
+ index = index + 1
|
||||||
|
+ return gdb.Value(self.EINVAL)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns a UTF16 string corresponding to a (CHAR16 *) value in EFI.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def parse_utf16 (self, value):
|
||||||
|
+ index = 0
|
||||||
|
+ data = array.array ('H')
|
||||||
|
+ while value[index] != 0:
|
||||||
|
+ data.append (value[index])
|
||||||
|
+ index = index + 1
|
||||||
|
+ return data.tostring ().decode ('utf-16')
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns offset of a field within structure. Useful
|
||||||
|
+ # for getting container of a structure.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def offsetof (self, typename, field):
|
||||||
|
+ t = gdb.Value (0).cast (self.ptype (typename))
|
||||||
|
+ return long (t[field].address)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns sizeof of a type.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def sizeof (self, typename):
|
||||||
|
+ return self.type (typename).sizeof
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns the EFI_IMAGE_NT_HEADERS32 pointer, given
|
||||||
|
+ # an ImageBase address as a gdb.Value.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def pe_headers (self, imagebase):
|
||||||
|
+ dosh_t = self.ptype ('EFI_IMAGE_DOS_HEADER')
|
||||||
|
+ head_t = self.ptype ('EFI_IMAGE_OPTIONAL_HEADER_UNION')
|
||||||
|
+ dosh = imagebase.cast(dosh_t)
|
||||||
|
+ h_addr = imagebase
|
||||||
|
+ if dosh['e_magic'] == self.DOS_MAGIC:
|
||||||
|
+ h_addr = h_addr + dosh['e_lfanew']
|
||||||
|
+ return gdb.Value(h_addr).cast (head_t)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns True if pe_headers refer to a PE32+ image.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def pe_is_64 (self, pe_headers):
|
||||||
|
+ if pe_headers['Pe32']['OptionalHeader']['Magic'] == self.PE32PLUS_MAGIC:
|
||||||
|
+ return True
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns the PE (not so) optional header.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def pe_optional (self, pe):
|
||||||
|
+ if self.pe_is_64 (pe):
|
||||||
|
+ return pe['Pe32Plus']['OptionalHeader']
|
||||||
|
+ else:
|
||||||
|
+ return pe['Pe32']['OptionalHeader']
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Returns the symbol file name for a PE image.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def pe_parse_debug (self, pe):
|
||||||
|
+ opt = self.pe_optional (pe)
|
||||||
|
+ debug_dir_entry = opt['DataDirectory'][6]
|
||||||
|
+ dep = debug_dir_entry['VirtualAddress'] + opt['ImageBase']
|
||||||
|
+ dep = dep.cast (self.ptype ('EFI_IMAGE_DEBUG_DIRECTORY_ENTRY'))
|
||||||
|
+ cvp = dep.dereference ()['RVA'] + opt['ImageBase']
|
||||||
|
+ cvv = cvp.cast(self.ptype ('UINT32')).dereference ()
|
||||||
|
+ if cvv == self.CV_NB10:
|
||||||
|
+ return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY')
|
||||||
|
+ elif cvv == self.CV_RSDS:
|
||||||
|
+ return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY')
|
||||||
|
+ elif cvv == self.CV_MTOC:
|
||||||
|
+ return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY')
|
||||||
|
+ return gdb.Value(self.EINVAL)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Parses an EFI_LOADED_IMAGE_PROTOCOL, figuring out the symbol file name.
|
||||||
|
+ # This file name is then appended to list of loaded symbols.
|
||||||
|
+ #
|
||||||
|
+ # TBD: Support TE images.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def parse_image (self, image, syms):
|
||||||
|
+ base = image['ImageBase']
|
||||||
|
+ pe = self.pe_headers (base)
|
||||||
|
+ opt = self.pe_optional (pe)
|
||||||
|
+ sym_name = self.pe_parse_debug (pe)
|
||||||
|
+
|
||||||
|
+ # For ELF and Mach-O-derived images...
|
||||||
|
+ if self.offset_by_headers:
|
||||||
|
+ base = base + opt['SizeOfHeaders']
|
||||||
|
+ if sym_name != self.EINVAL:
|
||||||
|
+ sym_name = sym_name.cast (self.ptype('CHAR8')).string ()
|
||||||
|
+ sym_name = re.sub(r"\.dll$", ".debug", sym_name)
|
||||||
|
+ syms.append ("add-symbol-file %s 0x%x" % \
|
||||||
|
+ (sym_name,
|
||||||
|
+ long (base)))
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Parses table EFI_DEBUG_IMAGE_INFO structures, builds
|
||||||
|
+ # a list of add-symbol-file commands, and reloads debugger
|
||||||
|
+ # symbols.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def parse_edii (self, edii, count):
|
||||||
|
+ index = 0
|
||||||
|
+ syms = []
|
||||||
|
+ while index != count:
|
||||||
|
+ entry = edii[index]
|
||||||
|
+ if entry['ImageInfoType'].dereference () == 1:
|
||||||
|
+ entry = entry['NormalImage']
|
||||||
|
+ self.parse_image(entry['LoadedImageProtocolInstance'], syms)
|
||||||
|
+ else:
|
||||||
|
+ print "Skipping unknown EFI_DEBUG_IMAGE_INFO (Type 0x%x)" % \
|
||||||
|
+ entry['ImageInfoType'].dereference ()
|
||||||
|
+ index = index + 1
|
||||||
|
+ gdb.execute ("symbol-file")
|
||||||
|
+ print "Loading new symbols..."
|
||||||
|
+ for sym in syms:
|
||||||
|
+ print sym
|
||||||
|
+ gdb.execute (sym)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Parses EFI_DEBUG_IMAGE_INFO_TABLE_HEADER, in order to load
|
||||||
|
+ # image symbols.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def parse_dh (self, dh):
|
||||||
|
+ dh_t = self.ptype ('EFI_DEBUG_IMAGE_INFO_TABLE_HEADER')
|
||||||
|
+ dh = dh.cast (dh_t)
|
||||||
|
+ print "DebugImageInfoTable @ 0x%x, 0x%x entries" \
|
||||||
|
+ % (long (dh['EfiDebugImageInfoTable']), dh['TableSize'])
|
||||||
|
+ if dh['UpdateStatus'] & self.DEBUG_IS_UPDATING:
|
||||||
|
+ print "EfiDebugImageInfoTable update in progress, retry later"
|
||||||
|
+ return
|
||||||
|
+ self.parse_edii (dh['EfiDebugImageInfoTable'], dh['TableSize'])
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Parses EFI_SYSTEM_TABLE, in order to load image symbols.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def parse_est (self, est):
|
||||||
|
+ est_t = self.ptype ('EFI_SYSTEM_TABLE')
|
||||||
|
+ est = est.cast (est_t)
|
||||||
|
+ print "Connected to %s (Rev. 0x%x)" % \
|
||||||
|
+ (self.parse_utf16 (est['FirmwareVendor']), \
|
||||||
|
+ long (est['FirmwareRevision']))
|
||||||
|
+ print "ConfigurationTable @ 0x%x, 0x%x entries" \
|
||||||
|
+ % (long (est['ConfigurationTable']), est['NumberOfTableEntries'])
|
||||||
|
+
|
||||||
|
+ dh = self.search_config(est['ConfigurationTable'],
|
||||||
|
+ est['NumberOfTableEntries'],
|
||||||
|
+ self.DEBUG_GUID)
|
||||||
|
+ if dh == self.EINVAL:
|
||||||
|
+ print "No EFI_DEBUG_IMAGE_INFO_TABLE_HEADER"
|
||||||
|
+ return
|
||||||
|
+ self.parse_dh (dh)
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Usage information.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def usage (self):
|
||||||
|
+ print "Usage: reload-uefi [-o] /path/to/GdbSyms.dll"
|
||||||
|
+
|
||||||
|
+ #
|
||||||
|
+ # Handler for reload-uefi.
|
||||||
|
+ #
|
||||||
|
+
|
||||||
|
+ def invoke (self, arg, from_tty):
|
||||||
|
+ args = arg.split(' ')
|
||||||
|
+ try:
|
||||||
|
+ opts, args = getopt.getopt(args, "o", ["offset-by-headers"])
|
||||||
|
+ except getopt.GetoptError, err:
|
||||||
|
+ self.usage ()
|
||||||
|
+ return
|
||||||
|
+ for opt, arg in opts:
|
||||||
|
+ if opt == "-o":
|
||||||
|
+ self.offset_by_headers = True
|
||||||
|
+
|
||||||
|
+ if len(args) < 1:
|
||||||
|
+ self.usage ()
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ gdb.execute ("symbol-file")
|
||||||
|
+ gdb.execute ("symbol-file %s" % args[0])
|
||||||
|
+ est = self.search_est ()
|
||||||
|
+ if est == self.EINVAL:
|
||||||
|
+ print "No EFI_SYSTEM_TABLE..."
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ print "EFI_SYSTEM_TABLE @ 0x%x" % est
|
||||||
|
+ self.parse_est (est)
|
||||||
|
+
|
||||||
|
+ReloadUefi ()
|
||||||
|
+
|
||||||
|
+
|
||||||
|
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
|
||||||
|
index 66459c2..320ffe8 100644
|
||||||
|
--- a/OvmfPkg/OvmfPkgX64.dsc
|
||||||
|
+++ b/OvmfPkg/OvmfPkgX64.dsc
|
||||||
|
@@ -567,3 +567,4 @@
|
||||||
|
!endif
|
||||||
|
|
||||||
|
OvmfPkg/PlatformDxe/Platform.inf
|
||||||
|
+ DebugPkg/GdbSyms/GdbSyms.inf
|
3
ovmf-rpmlintrc
Normal file
3
ovmf-rpmlintrc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
addFilter("unstripped-binary-or-object /usr/lib/debug/*")
|
||||||
|
addFilter("statically-linked-binary /usr/lib/debug/*")
|
||||||
|
addFilter("executable-stack /usr/lib/debug/*")
|
38
ovmf.changes
38
ovmf.changes
@ -1,3 +1,41 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Aug 14 09:06:28 UTC 2014 - glin@suse.com
|
||||||
|
|
||||||
|
- Amend the spec file to package the debug files and update README
|
||||||
|
for the source level debugging
|
||||||
|
- Add gdb_uefi.py.in: the helper script to load the debug symbols
|
||||||
|
- Update to R15801
|
||||||
|
+ OvmfPkg/build.sh: Support IA32+X64 build
|
||||||
|
+ OvmfPkg/build.sh: Add support for GCC49 toolchain
|
||||||
|
+ Add ACPI5.1 header file
|
||||||
|
+ BaseTools: various fixes and add support for GCC49
|
||||||
|
+ OvmfPkg: build OVMF_VARS.fd, OVMF_CODE.fd, OVMF.fd
|
||||||
|
+ OvmfPkg: extract varstore-related FD Layout Regions to an
|
||||||
|
include file
|
||||||
|
+ StdLib: various fixes and code cleanup
|
||||||
|
+ Fix segfault while the pointers passed to WaitForEvent() are
|
||||||
|
NULL
|
||||||
|
+ Update openssl to 0.9.8za
|
||||||
|
+ Correct the default value for date opcode
|
||||||
|
+ XhciPei/UsbBusPei: Add XHCI recovery support
|
||||||
|
+ Fix a bug in IP4 driver when computing the network broadcast
|
||||||
|
adress
|
||||||
|
+ Fix the potential address overflow issue when checking PE
|
||||||
|
signature
|
||||||
|
+ OvmfPkg: add missing braces to aggregate and/or union
|
||||||
|
initializers
|
||||||
|
+ OvmfPkg: AcpiPlatformDxe: don't rely on unstable QEMU interface
|
||||||
|
+ OvmfPkg: AcpiPlatformDxe: exclude RSD PTR from QEMU's fw_cfg
|
||||||
|
payload
|
||||||
|
+ OvmfPkg: AcpiPlatformDxe: pass FwCfgFile to
|
||||||
|
InstallQemuLinkedTables()
|
||||||
|
+ OvmgPkg: QemuFwCfgLib: export QEMU_FW_CFG_FNAME_SIZE
|
||||||
|
+ Initialize the PCI device path earlier to avoid the possible
|
||||||
|
crash
|
||||||
|
+ Create boot option for all block IO devices
|
||||||
|
+ ShellPkg: various fixes
|
||||||
|
- Refresh OVMF-correct-debug-path.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Aug 13 09:32:33 UTC 2014 - glin@suse.com
|
Wed Aug 13 09:32:33 UTC 2014 - glin@suse.com
|
||||||
|
|
||||||
|
89
ovmf.spec
89
ovmf.spec
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package OVMF
|
# spec file for package ovmf
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@ -17,15 +17,17 @@
|
|||||||
|
|
||||||
# needssslcertforbuild
|
# needssslcertforbuild
|
||||||
|
|
||||||
|
%undefine _build_create_debug
|
||||||
|
|
||||||
Name: ovmf
|
Name: ovmf
|
||||||
Url: http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK2
|
Url: http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK2
|
||||||
Summary: Open Virtual Machine Firmware
|
Summary: Open Virtual Machine Firmware
|
||||||
License: BSD-2-Clause
|
License: BSD-2-Clause
|
||||||
Group: System/Emulators/PC
|
Group: System/Emulators/PC
|
||||||
Version: 0.1+svn15547
|
Version: 0.1+svn15801
|
||||||
Release: 0
|
Release: 0
|
||||||
Source0: %{name}-%{version}.tar.xz
|
Source0: %{name}-%{version}.tar.xz
|
||||||
Source1: openssl-0.9.8w.tar.gz
|
Source1: openssl-0.9.8za.tar.gz
|
||||||
Source2: README
|
Source2: README
|
||||||
Source3: SLES-UEFI-CA-Certificate-2048.crt
|
Source3: SLES-UEFI-CA-Certificate-2048.crt
|
||||||
Source4: SLES-UEFI-SIGN-Certificate-2048.crt
|
Source4: SLES-UEFI-SIGN-Certificate-2048.crt
|
||||||
@ -33,13 +35,17 @@ Source5: MicCorKEKCA2011_2011-06-24.crt
|
|||||||
Source6: MicCorUEFCA2011_2011-06-27.crt
|
Source6: MicCorUEFCA2011_2011-06-27.crt
|
||||||
Source7: openSUSE-UEFI-CA-Certificate-2048.crt
|
Source7: openSUSE-UEFI-CA-Certificate-2048.crt
|
||||||
Source8: openSUSE-UEFI-SIGN-Certificate-2048.crt
|
Source8: openSUSE-UEFI-SIGN-Certificate-2048.crt
|
||||||
Patch2: ovmf-sle-11-gcc47.patch
|
Source100: %{name}-rpmlintrc
|
||||||
Patch3: ovmf-embed-default-keys.patch
|
Source101: gdb_uefi.py.in
|
||||||
Patch4: ovmf-use-generic-sb-config.patch
|
Patch2: %{name}-sle-11-gcc47.patch
|
||||||
|
Patch3: %{name}-embed-default-keys.patch
|
||||||
|
Patch4: %{name}-use-generic-sb-config.patch
|
||||||
Patch5: edk2-basetools-aarch64.patch
|
Patch5: edk2-basetools-aarch64.patch
|
||||||
Patch6: ovmf-correct-debug-path.patch
|
Patch6: %{name}-correct-debug-path.patch
|
||||||
|
Patch7: %{name}-gdb-symbols.patch
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
BuildRequires: libuuid-devel
|
BuildRequires: libuuid-devel
|
||||||
|
BuildRequires: fdupes
|
||||||
%if 0%{?suse_version} == 1110
|
%if 0%{?suse_version} == 1110
|
||||||
BuildRequires: gcc47
|
BuildRequires: gcc47
|
||||||
%else
|
%else
|
||||||
@ -96,6 +102,18 @@ firmware for Virtual Machines using the edk2 code base.
|
|||||||
|
|
||||||
This package contains UEFI rom images for exercising UEFI secure
|
This package contains UEFI rom images for exercising UEFI secure
|
||||||
boot in a qemu environment (x86_64)
|
boot in a qemu environment (x86_64)
|
||||||
|
|
||||||
|
%package -n qemu-ovmf-x86_64-debug
|
||||||
|
Summary: Open Virtual Machine Firmware - debug symbols (x86_64)
|
||||||
|
Group: System/Emulators/PC
|
||||||
|
Requires: qemu
|
||||||
|
|
||||||
|
%description -n qemu-ovmf-x86_64-debug
|
||||||
|
The Open Virtual Machine Firmware (OVMF) project aims to support
|
||||||
|
firmware for Virtual Machines using the edk2 code base.
|
||||||
|
|
||||||
|
This package contains the debug symbols for UEFI rom images (x86_64)
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifarch aarch64
|
%ifarch aarch64
|
||||||
@ -123,9 +141,11 @@ The UEFI image for Foundation Model (AArch64)
|
|||||||
%patch5 -p1
|
%patch5 -p1
|
||||||
%endif
|
%endif
|
||||||
%patch6 -p1
|
%patch6 -p1
|
||||||
|
%patch7 -p1
|
||||||
# Intel has special patches for openssl
|
# Intel has special patches for openssl
|
||||||
pushd CryptoPkg/Library/OpensslLib/openssl-0.9.8w
|
pushd CryptoPkg/Library/OpensslLib/openssl-0.9.8za
|
||||||
patch -p0 -i ../EDKII_openssl-0.9.8w.patch
|
chmod -x crypto/bn/bn_const.c
|
||||||
|
patch -p0 -i ../EDKII_openssl-0.9.8za.patch
|
||||||
cd ..
|
cd ..
|
||||||
./Install.sh
|
./Install.sh
|
||||||
popd
|
popd
|
||||||
@ -159,8 +179,38 @@ build $BUILD_OPTIONS
|
|||||||
cp Build/OvmfIa32/DEBUG_*/FV/OVMF.fd ovmf-ia32.bin
|
cp Build/OvmfIa32/DEBUG_*/FV/OVMF.fd ovmf-ia32.bin
|
||||||
%else
|
%else
|
||||||
%ifarch x86_64
|
%ifarch x86_64
|
||||||
|
|
||||||
|
collect_debug_files()
|
||||||
|
{
|
||||||
|
target="$1"
|
||||||
|
out_dir="debug/$target"
|
||||||
|
abs_path="`pwd`/$out_dir/"
|
||||||
|
source_path="`pwd`"
|
||||||
|
gdb_src_path="/usr/src/debug/ovmf-x86_64"
|
||||||
|
|
||||||
|
# copy the debug symbols
|
||||||
|
mkdir -p $out_dir
|
||||||
|
pushd Build/OvmfX64/DEBUG_GCC4*/X64/
|
||||||
|
find . -mindepth 2 -type f -name "*.debug" -exec cp --parents -a {} $abs_path \;
|
||||||
|
cp --parents -a DebugPkg/GdbSyms/GdbSyms/DEBUG/GdbSyms.dll $abs_path
|
||||||
|
build_path=`pwd`
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Change the path in the python gdb script
|
||||||
|
sed "s:__BUILD_PATH__:$build_path:;s:__SOURCE_PATH__:$source_path:;s:__GDB_SRC_PATH__:$gdb_src_path:;s/__FLAVOR__/$target/" \
|
||||||
|
%{SOURCE101} > gdb_uefi-$target.py
|
||||||
|
}
|
||||||
|
|
||||||
cp Build/OvmfX64/DEBUG_*/FV/OVMF.fd ovmf-x86_64.bin
|
cp Build/OvmfX64/DEBUG_*/FV/OVMF.fd ovmf-x86_64.bin
|
||||||
|
|
||||||
|
# Collect the debug files
|
||||||
|
collect_debug_files ovmf-x86_64
|
||||||
|
# Collect the source
|
||||||
|
mkdir -p source/ovmf-x86_64
|
||||||
|
# TODO get the source list from debug files
|
||||||
|
src_list=`find Build/OvmfX64/DEBUG_GCC4*/X64/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;`
|
||||||
|
find $src_list \( -name "*.c" -o -name "*.h" \) -type f -exec cp --parents -a {} source/ovmf-x86_64 \;
|
||||||
|
|
||||||
build_with_keys()
|
build_with_keys()
|
||||||
{
|
{
|
||||||
suffix="$1"
|
suffix="$1"
|
||||||
@ -169,6 +219,8 @@ build_with_keys()
|
|||||||
xxd -i Default_DB > SecurityPkg/VariableAuthenticated/RuntimeDxe/Default_DB.h
|
xxd -i Default_DB > SecurityPkg/VariableAuthenticated/RuntimeDxe/Default_DB.h
|
||||||
build $BUILD_OPTIONS
|
build $BUILD_OPTIONS
|
||||||
cp Build/OvmfX64/DEBUG_*/FV/OVMF.fd ovmf-x86_64-$suffix.bin
|
cp Build/OvmfX64/DEBUG_*/FV/OVMF.fd ovmf-x86_64-$suffix.bin
|
||||||
|
|
||||||
|
collect_debug_files ovmf-x86_64-$suffix
|
||||||
}
|
}
|
||||||
# OVMF with SUSE keys
|
# OVMF with SUSE keys
|
||||||
openssl x509 -in %{SOURCE3} -outform DER > Default_PK
|
openssl x509 -in %{SOURCE3} -outform DER > Default_PK
|
||||||
@ -224,6 +276,15 @@ install -m 0644 -D ovmf-ia32.bin %{buildroot}/%{_datadir}/qemu/ovmf-ia32.bin
|
|||||||
tr -d '\r' < OvmfPkg/License.txt > License.txt
|
tr -d '\r' < OvmfPkg/License.txt > License.txt
|
||||||
install -m 0644 -D ovmf-x86_64.bin %{buildroot}/%{_datadir}/qemu/ovmf-x86_64.bin
|
install -m 0644 -D ovmf-x86_64.bin %{buildroot}/%{_datadir}/qemu/ovmf-x86_64.bin
|
||||||
install -m 0644 ovmf-x86_64-*.bin %{buildroot}/%{_datadir}/qemu/
|
install -m 0644 ovmf-x86_64-*.bin %{buildroot}/%{_datadir}/qemu/
|
||||||
|
# Install debug symbols, gdb-uefi.py
|
||||||
|
install -d %{buildroot}/%{_datadir}/ovmf-x86_64/
|
||||||
|
install -m 0644 gdb_uefi-*.py %{buildroot}/%{_datadir}/ovmf-x86_64/
|
||||||
|
mkdir -p %{buildroot}/usr/lib/debug
|
||||||
|
mv debug/ovmf-x86_64* %{buildroot}/usr/lib/debug
|
||||||
|
%fdupes %{buildroot}/usr/lib/debug/ovmf-x86_64*
|
||||||
|
mkdir -p %{buildroot}/usr/src/debug
|
||||||
|
mv source/ovmf-x86_64* %{buildroot}/usr/src/debug
|
||||||
|
%fdupes -s %{buildroot}/usr/src/debug/ovmf-x86_64
|
||||||
%else
|
%else
|
||||||
%ifarch aarch64
|
%ifarch aarch64
|
||||||
tr -d '\r' < ArmPlatformPkg/License.txt > License.txt
|
tr -d '\r' < ArmPlatformPkg/License.txt > License.txt
|
||||||
@ -251,6 +312,14 @@ install -m 0644 -D fm-uefi-bootstrap.axf %{buildroot}/%{_datadir}/foundation-mod
|
|||||||
%doc License.txt License-fat-driver.txt
|
%doc License.txt License-fat-driver.txt
|
||||||
%dir %{_datadir}/qemu/
|
%dir %{_datadir}/qemu/
|
||||||
%{_datadir}/qemu/ovmf-x86_64*.bin
|
%{_datadir}/qemu/ovmf-x86_64*.bin
|
||||||
|
|
||||||
|
%files -n qemu-ovmf-x86_64-debug
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_datadir}/ovmf-x86_64/
|
||||||
|
%dir /usr/lib/debug/
|
||||||
|
/usr/lib/debug/ovmf-x86_64*
|
||||||
|
%dir /usr/src/debug/
|
||||||
|
/usr/src/debug/ovmf-x86_64*
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifarch aarch64
|
%ifarch aarch64
|
||||||
|
Loading…
Reference in New Issue
Block a user