mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	scripts/gdb/symbols: determine KASLR offset on s390
Use QEMU's qemu.PhyMemMode [1] functionality to read vmcore from the physical memory the same way the existing dump tooling does this. Gracefully handle non-QEMU targets, early boot, and memory corruptions; print a warning if such situation is detected. [1] https://qemu-project.gitlab.io/qemu/system/gdb.html#examining-physical-memory Link: https://lkml.kernel.org/r/20250303110437.79070-1-iii@linux.ibm.com Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Acked-by: Jan Kiszka <jan.kiszka@siemens.com> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Andrew Donnellan <ajd@linux.ibm.com> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Kieran Bingham <kbingham@kernel.org> Cc: Nina Schoetterl-Glausch <nsg@linux.ibm.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									8a56f26607
								
							
						
					
					
						commit
						28939c3e99
					
				
					 2 changed files with 65 additions and 1 deletions
				
			
		|  | @ -14,6 +14,7 @@ | ||||||
| import gdb | import gdb | ||||||
| import os | import os | ||||||
| import re | import re | ||||||
|  | import struct | ||||||
| 
 | 
 | ||||||
| from itertools import count | from itertools import count | ||||||
| from linux import modules, utils, constants | from linux import modules, utils, constants | ||||||
|  | @ -54,6 +55,29 @@ if hasattr(gdb, 'Breakpoint'): | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def get_vmcore_s390(): | ||||||
|  |     with utils.qemu_phy_mem_mode(): | ||||||
|  |         vmcore_info = 0x0e0c | ||||||
|  |         paddr_vmcoreinfo_note = gdb.parse_and_eval("*(unsigned long long *)" + | ||||||
|  |                                                    hex(vmcore_info)) | ||||||
|  |         inferior = gdb.selected_inferior() | ||||||
|  |         elf_note = inferior.read_memory(paddr_vmcoreinfo_note, 12) | ||||||
|  |         n_namesz, n_descsz, n_type = struct.unpack(">III", elf_note) | ||||||
|  |         desc_paddr = paddr_vmcoreinfo_note + len(elf_note) + n_namesz + 1 | ||||||
|  |         return gdb.parse_and_eval("(char *)" + hex(desc_paddr)).string() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_kerneloffset(): | ||||||
|  |     if utils.is_target_arch('s390'): | ||||||
|  |         try: | ||||||
|  |             vmcore_str = get_vmcore_s390() | ||||||
|  |         except gdb.error as e: | ||||||
|  |             gdb.write("{}\n".format(e)) | ||||||
|  |             return None | ||||||
|  |         return utils.parse_vmcore(vmcore_str).kerneloffset | ||||||
|  |     return None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class LxSymbols(gdb.Command): | class LxSymbols(gdb.Command): | ||||||
|     """(Re-)load symbols of Linux kernel and currently loaded modules. |     """(Re-)load symbols of Linux kernel and currently loaded modules. | ||||||
| 
 | 
 | ||||||
|  | @ -160,7 +184,12 @@ lx-symbols command.""" | ||||||
|                 obj.filename.endswith('vmlinux.debug')): |                 obj.filename.endswith('vmlinux.debug')): | ||||||
|                 orig_vmlinux = obj.filename |                 orig_vmlinux = obj.filename | ||||||
|         gdb.execute("symbol-file", to_string=True) |         gdb.execute("symbol-file", to_string=True) | ||||||
|         gdb.execute("symbol-file {0}".format(orig_vmlinux)) |         kerneloffset = get_kerneloffset() | ||||||
|  |         if kerneloffset is None: | ||||||
|  |             offset_arg = "" | ||||||
|  |         else: | ||||||
|  |             offset_arg = " -o " + hex(kerneloffset) | ||||||
|  |         gdb.execute("symbol-file {0}{1}".format(orig_vmlinux, offset_arg)) | ||||||
| 
 | 
 | ||||||
|         self.loaded_modules = [] |         self.loaded_modules = [] | ||||||
|         module_list = modules.module_list() |         module_list = modules.module_list() | ||||||
|  |  | ||||||
|  | @ -11,6 +11,11 @@ | ||||||
| # This work is licensed under the terms of the GNU GPL version 2. | # This work is licensed under the terms of the GNU GPL version 2. | ||||||
| # | # | ||||||
| 
 | 
 | ||||||
|  | import contextlib | ||||||
|  | import dataclasses | ||||||
|  | import re | ||||||
|  | import typing | ||||||
|  | 
 | ||||||
| import gdb | import gdb | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -216,3 +221,33 @@ def gdb_eval_or_none(expresssion): | ||||||
|         return gdb.parse_and_eval(expresssion) |         return gdb.parse_and_eval(expresssion) | ||||||
|     except gdb.error: |     except gdb.error: | ||||||
|         return None |         return None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @contextlib.contextmanager | ||||||
|  | def qemu_phy_mem_mode(): | ||||||
|  |     connection = gdb.selected_inferior().connection | ||||||
|  |     orig = connection.send_packet("qqemu.PhyMemMode") | ||||||
|  |     if orig not in b"01": | ||||||
|  |         raise gdb.error("Unexpected qemu.PhyMemMode") | ||||||
|  |     orig = orig.decode() | ||||||
|  |     if connection.send_packet("Qqemu.PhyMemMode:1") != b"OK": | ||||||
|  |         raise gdb.error("Failed to set qemu.PhyMemMode") | ||||||
|  |     try: | ||||||
|  |         yield | ||||||
|  |     finally: | ||||||
|  |         if connection.send_packet("Qqemu.PhyMemMode:" + orig) != b"OK": | ||||||
|  |             raise gdb.error("Failed to restore qemu.PhyMemMode") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @dataclasses.dataclass | ||||||
|  | class VmCore: | ||||||
|  |     kerneloffset: typing.Optional[int] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def parse_vmcore(s): | ||||||
|  |     match = re.search(r"KERNELOFFSET=([0-9a-f]+)", s) | ||||||
|  |     if match is None: | ||||||
|  |         kerneloffset = None | ||||||
|  |     else: | ||||||
|  |         kerneloffset = int(match.group(1), 16) | ||||||
|  |     return VmCore(kerneloffset=kerneloffset) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Ilya Leoshkevich
						Ilya Leoshkevich