| # | |
| # Copyright (c) 2011-2013, ARM Limited. All rights reserved. | |
| # | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| # | |
| from arm_ds.debugger_v1 import DebugException | |
| import struct | |
| import edk2_debugger | |
| import firmware_volume | |
| class DebugInfoTable: | |
| CONST_DEBUG_INFO_TABLE_GUID = ( 0x49152E77L, 0x47641ADAL, 0xFE7AA2B7L, 0x8B5ED9FEL) | |
| DebugInfos = [] | |
| def __init__(self, ec, debug_info_table_header_offset): | |
| self.ec = ec | |
| self.base = debug_info_table_header_offset | |
| def get_debug_info(self): | |
| # Get the information from EFI_DEBUG_IMAGE_INFO_TABLE_HEADER | |
| count = self.ec.getMemoryService().readMemory32(self.base + 0x4) | |
| if edk2_debugger.is_aarch64(self.ec): | |
| debug_info_table_base = self.ec.getMemoryService().readMemory64(self.base + 0x8) | |
| else: | |
| debug_info_table_base = self.ec.getMemoryService().readMemory32(self.base + 0x8) | |
| self.DebugInfos = [] | |
| for i in range(0, count): | |
| # Get the address of the structure EFI_DEBUG_IMAGE_INFO | |
| if edk2_debugger.is_aarch64(self.ec): | |
| debug_info = self.ec.getMemoryService().readMemory64(debug_info_table_base + (i * 8)) | |
| else: | |
| debug_info = self.ec.getMemoryService().readMemory32(debug_info_table_base + (i * 4)) | |
| if debug_info: | |
| debug_info_type = self.ec.getMemoryService().readMemory32(debug_info) | |
| # Normal Debug Info Type | |
| if debug_info_type == 1: | |
| if edk2_debugger.is_aarch64(self.ec): | |
| # Get the base address of the structure EFI_LOADED_IMAGE_PROTOCOL | |
| loaded_image_protocol = self.ec.getMemoryService().readMemory64(debug_info + 0x8) | |
| image_base = self.ec.getMemoryService().readMemory64(loaded_image_protocol + 0x40) | |
| image_size = self.ec.getMemoryService().readMemory32(loaded_image_protocol + 0x48) | |
| else: | |
| # Get the base address of the structure EFI_LOADED_IMAGE_PROTOCOL | |
| loaded_image_protocol = self.ec.getMemoryService().readMemory32(debug_info + 0x4) | |
| image_base = self.ec.getMemoryService().readMemory32(loaded_image_protocol + 0x20) | |
| image_size = self.ec.getMemoryService().readMemory32(loaded_image_protocol + 0x28) | |
| self.DebugInfos.append((image_base,image_size)) | |
| # Return (base, size) | |
| def load_symbols_at(self, addr, verbose = False): | |
| if self.DebugInfos == []: | |
| self.get_debug_info() | |
| found = False | |
| for debug_info in self.DebugInfos: | |
| if (addr >= debug_info[0]) and (addr < debug_info[0] + debug_info[1]): | |
| if edk2_debugger.is_aarch64(self.ec): | |
| section = firmware_volume.EfiSectionPE64(self.ec, debug_info[0]) | |
| else: | |
| section = firmware_volume.EfiSectionPE32(self.ec, debug_info[0]) | |
| try: | |
| edk2_debugger.load_symbol_from_file(self.ec, section.get_debug_filepath(), section.get_debug_elfbase(), verbose) | |
| except Exception, (ErrorClass, ErrorMessage): | |
| if verbose: | |
| print "Error while loading a symbol file (%s: %s)" % (ErrorClass, ErrorMessage) | |
| found = True | |
| return debug_info | |
| if found == False: | |
| raise Exception('DebugInfoTable','No symbol found at 0x%x' % addr) | |
| def load_all_symbols(self, verbose = False): | |
| if self.DebugInfos == []: | |
| self.get_debug_info() | |
| for debug_info in self.DebugInfos: | |
| if edk2_debugger.is_aarch64(self.ec): | |
| section = firmware_volume.EfiSectionPE64(self.ec, debug_info[0]) | |
| else: | |
| section = firmware_volume.EfiSectionPE32(self.ec, debug_info[0]) | |
| try: | |
| edk2_debugger.load_symbol_from_file(self.ec, section.get_debug_filepath(), section.get_debug_elfbase(), verbose) | |
| except Exception, (ErrorClass, ErrorMessage): | |
| if verbose: | |
| print "Error while loading a symbol file (%s: %s)" % (ErrorClass, ErrorMessage) | |
| def dump(self): | |
| self.get_debug_info() | |
| for debug_info in self.DebugInfos: | |
| base_pe32 = debug_info[0] | |
| if edk2_debugger.is_aarch64(self.ec): | |
| section = firmware_volume.EfiSectionPE64(self.ec, base_pe32) | |
| else: | |
| section = firmware_volume.EfiSectionPE32(self.ec, base_pe32) | |
| print section.get_debug_filepath() | |
| class SystemTable: | |
| CONST_ST_SIGNATURE = ('I','B','I',' ','S','Y','S','T') | |
| def __init__(self, ec, membase, memsize): | |
| self.membase = membase | |
| self.memsize = memsize | |
| self.ec = ec | |
| found = False | |
| # Start from the top of the memory | |
| offset = self.membase + self.memsize | |
| # Align to highest 4MB boundary | |
| offset = offset & ~0x3FFFFF | |
| # We should not have a System Table at the top of the System Memory | |
| offset = offset - 0x400000 | |
| # Start at top and look on 4MB boundaries for system table ptr structure | |
| while offset > self.membase: | |
| try: | |
| signature = struct.unpack("cccccccc", self.ec.getMemoryService().read(str(offset), 8, 32)) | |
| except DebugException: | |
| raise Exception('SystemTable','Fail to access System Memory. Ensure all the memory in the region [0x%x;0x%X] is accessible.' % (membase,membase+memsize)) | |
| if signature == SystemTable.CONST_ST_SIGNATURE: | |
| found = True | |
| if edk2_debugger.is_aarch64(self.ec): | |
| self.system_table_base = self.ec.getMemoryService().readMemory64(offset + 0x8) | |
| else: | |
| self.system_table_base = self.ec.getMemoryService().readMemory32(offset + 0x8) | |
| break | |
| offset = offset - 0x400000 | |
| if not found: | |
| raise Exception('SystemTable','System Table not found in System Memory [0x%x;0x%X]' % (membase,membase+memsize)) | |
| def get_configuration_table(self, conf_table_guid): | |
| if edk2_debugger.is_aarch64(self.ec): | |
| # Number of configuration Table entry | |
| conf_table_entry_count = self.ec.getMemoryService().readMemory32(self.system_table_base + 0x68) | |
| # Get location of the Configuration Table entries | |
| conf_table_offset = self.ec.getMemoryService().readMemory64(self.system_table_base + 0x70) | |
| else: | |
| # Number of configuration Table entry | |
| conf_table_entry_count = self.ec.getMemoryService().readMemory32(self.system_table_base + 0x40) | |
| # Get location of the Configuration Table entries | |
| conf_table_offset = self.ec.getMemoryService().readMemory32(self.system_table_base + 0x44) | |
| for i in range(0, conf_table_entry_count): | |
| if edk2_debugger.is_aarch64(self.ec): | |
| offset = conf_table_offset + (i * 0x18) | |
| else: | |
| offset = conf_table_offset + (i * 0x14) | |
| guid = struct.unpack("<IIII", self.ec.getMemoryService().read(str(offset), 16, 32)) | |
| if guid == conf_table_guid: | |
| if edk2_debugger.is_aarch64(self.ec): | |
| return self.ec.getMemoryService().readMemory64(offset + 0x10) | |
| else: | |
| return self.ec.getMemoryService().readMemory32(offset + 0x10) | |
| raise Exception('SystemTable','Configuration Table not found') |