# | |
# Copyright (c) 2021, Arm Limited. All rights reserved. | |
# | |
# SPDX-License-Identifier: BSD-2-Clause-Patent | |
# | |
from arm_ds.debugger_v1 import DebugException | |
import subprocess, os, edk2_debugger, re | |
def get_module_name(line): | |
path = line.rsplit(' ')[1] | |
return os.path.splitext(os.path.basename(path))[0] | |
def get_module_path(line): | |
return line.rsplit(' ')[1] | |
def get_module_entrypoint(list, module_name): | |
line = [i for i in list if module_name in i and re.search(r'\b'+module_name+r'\b', i)] | |
if len(line) == 0: | |
# Module was not loaded using DxeDispatcher or PeiDispatcher. It is a SEC module | |
# Symbols for these modules are loaded from FV, not from console log | |
return None | |
entrypoint_str = line[0].rsplit(' ')[4] | |
return entrypoint_str.rsplit('=')[1] | |
def load_symbol_from_console(ec, console_file, objdump, verbose): | |
if objdump is None: | |
print "Error: A path to objdump tool is not specified, but -i parameter is provided" | |
elif not os.path.exists(objdump): | |
print "Error: Provided path to objdump is invalid: %s" % objdump | |
elif not os.path.exists(console_file): | |
print "Error: UEFI console file is not found: %s" % console_file | |
else: | |
full_list = open(console_file).read().splitlines() | |
efi_list = [i for i in full_list if "EntryPoint=" in i] | |
full_list = dict.fromkeys(full_list) | |
full_list = [i for i in full_list if "add-symbol-file" in i] | |
module_dict = {} | |
for line in full_list: | |
name = get_module_name(line) | |
module_dict[name] = (get_module_path(line), get_module_entrypoint(efi_list, name)) | |
for module in module_dict: | |
entrypoint_addr = module_dict[module][1] | |
if entrypoint_addr is not None: | |
path = module_dict[module][0] | |
if not os.path.exists(path): | |
print "Module not found: " + path + ". Skipping..." | |
continue | |
sp = subprocess.Popen([objdump,'-S', path], stdout = subprocess.PIPE) | |
objdump_out = sp.stdout.readlines() | |
entrypoint_record = [i for i in objdump_out if "<_ModuleEntryPoint>" in i] | |
entrypoint_offset = entrypoint_record[0].split(' ')[0] | |
load_addr = int(entrypoint_addr, 16) - int(entrypoint_offset, 16) | |
edk2_debugger.load_symbol_from_file(ec, path, load_addr, verbose) |