SHA256
1
0
forked from pool/ovmf

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:
Olaf Hering 2014-08-15 06:59:05 +00:00 committed by Git OBS Bridge
parent 0b4a304504
commit 4fbbe447f6
10 changed files with 1041 additions and 20 deletions

365
gdb_uefi.py.in Normal file
View 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 ()

View File

@ -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
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cdcb98d0fbc026ca798b17919334310271d3a593554ffd6a59659b9222fd4e48
size 3787508

View File

@ -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
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:65d58bf3a837e77229ec8f86f8d6434395a42eb5d3dde9db7497cc095f9891fc
size 21773372

View File

@ -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
View 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
View 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/*")

View File

@ -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

View File

@ -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