Skip to content

Commit 28939c3

Browse files
iii-iakpm00
authored andcommitted
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>
1 parent 8a56f26 commit 28939c3

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

scripts/gdb/linux/symbols.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import gdb
1515
import os
1616
import re
17+
import struct
1718

1819
from itertools import count
1920
from linux import modules, utils, constants
@@ -54,6 +55,29 @@ def stop(self):
5455
return False
5556

5657

58+
def get_vmcore_s390():
59+
with utils.qemu_phy_mem_mode():
60+
vmcore_info = 0x0e0c
61+
paddr_vmcoreinfo_note = gdb.parse_and_eval("*(unsigned long long *)" +
62+
hex(vmcore_info))
63+
inferior = gdb.selected_inferior()
64+
elf_note = inferior.read_memory(paddr_vmcoreinfo_note, 12)
65+
n_namesz, n_descsz, n_type = struct.unpack(">III", elf_note)
66+
desc_paddr = paddr_vmcoreinfo_note + len(elf_note) + n_namesz + 1
67+
return gdb.parse_and_eval("(char *)" + hex(desc_paddr)).string()
68+
69+
70+
def get_kerneloffset():
71+
if utils.is_target_arch('s390'):
72+
try:
73+
vmcore_str = get_vmcore_s390()
74+
except gdb.error as e:
75+
gdb.write("{}\n".format(e))
76+
return None
77+
return utils.parse_vmcore(vmcore_str).kerneloffset
78+
return None
79+
80+
5781
class LxSymbols(gdb.Command):
5882
"""(Re-)load symbols of Linux kernel and currently loaded modules.
5983
@@ -160,7 +184,12 @@ def load_all_symbols(self):
160184
obj.filename.endswith('vmlinux.debug')):
161185
orig_vmlinux = obj.filename
162186
gdb.execute("symbol-file", to_string=True)
163-
gdb.execute("symbol-file {0}".format(orig_vmlinux))
187+
kerneloffset = get_kerneloffset()
188+
if kerneloffset is None:
189+
offset_arg = ""
190+
else:
191+
offset_arg = " -o " + hex(kerneloffset)
192+
gdb.execute("symbol-file {0}{1}".format(orig_vmlinux, offset_arg))
164193

165194
self.loaded_modules = []
166195
module_list = modules.module_list()

scripts/gdb/linux/utils.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
# This work is licensed under the terms of the GNU GPL version 2.
1212
#
1313

14+
import contextlib
15+
import dataclasses
16+
import re
17+
import typing
18+
1419
import gdb
1520

1621

@@ -216,3 +221,33 @@ def gdb_eval_or_none(expresssion):
216221
return gdb.parse_and_eval(expresssion)
217222
except gdb.error:
218223
return None
224+
225+
226+
@contextlib.contextmanager
227+
def qemu_phy_mem_mode():
228+
connection = gdb.selected_inferior().connection
229+
orig = connection.send_packet("qqemu.PhyMemMode")
230+
if orig not in b"01":
231+
raise gdb.error("Unexpected qemu.PhyMemMode")
232+
orig = orig.decode()
233+
if connection.send_packet("Qqemu.PhyMemMode:1") != b"OK":
234+
raise gdb.error("Failed to set qemu.PhyMemMode")
235+
try:
236+
yield
237+
finally:
238+
if connection.send_packet("Qqemu.PhyMemMode:" + orig) != b"OK":
239+
raise gdb.error("Failed to restore qemu.PhyMemMode")
240+
241+
242+
@dataclasses.dataclass
243+
class VmCore:
244+
kerneloffset: typing.Optional[int]
245+
246+
247+
def parse_vmcore(s):
248+
match = re.search(r"KERNELOFFSET=([0-9a-f]+)", s)
249+
if match is None:
250+
kerneloffset = None
251+
else:
252+
kerneloffset = int(match.group(1), 16)
253+
return VmCore(kerneloffset=kerneloffset)

0 commit comments

Comments
 (0)