cmd_load_symbols.py can only load symbols from FV. Add the possibility to use UEFI console output to calculate dll load address and send add-symbol-file commands directly to ArmDS debugger dll load address can't be used directly from UEFI output, see comment in DebugPeCoffExtraActionLib: "This may not work correctly if you generate PE/COFF directly as then the Offset would not be required". 1) Use objdump -S module.dll | grep <_ModuleEntryPoint> to get offset in dll (offset) 2) Use Entrypoint=<address> from UEFI console output (entrypoint) 3) dll load address is (entrypoint)-(offset) Signed-off-by: Artem Kopotev <artem.kopotev@arm.com> Tested-by: Pierre Gondois <Pierre.Gondois@arm.com>
		
			
				
	
	
		
			69 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #
 | |
| #  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)
 |