diff options
Diffstat (limited to 'scripts/gdb/linux/symbols.py')
-rw-r--r-- | scripts/gdb/linux/symbols.py | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index b255177301e9..6edb99221675 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -38,19 +38,13 @@ if hasattr(gdb, 'Breakpoint'): # Disable pagination while reporting symbol (re-)loading. # The console input is blocked in this context so that we would # get stuck waiting for the user to acknowledge paged output. - show_pagination = gdb.execute("show pagination", to_string=True) - pagination = show_pagination.endswith("on.\n") - gdb.execute("set pagination off") - - if module_name in cmd.loaded_modules: - gdb.write("refreshing all symbols to reload module " - "'{0}'\n".format(module_name)) - cmd.load_all_symbols() - else: - cmd.load_module_symbols(module) - - # restore pagination state - gdb.execute("set pagination %s" % ("on" if pagination else "off")) + with utils.pagination_off(): + if module_name in cmd.loaded_modules: + gdb.write("refreshing all symbols to reload module " + "'{0}'\n".format(module_name)) + cmd.load_all_symbols() + else: + cmd.load_module_symbols(module) return False @@ -60,6 +54,18 @@ def get_vmcore_s390(): vmcore_info = 0x0e0c paddr_vmcoreinfo_note = gdb.parse_and_eval("*(unsigned long long *)" + hex(vmcore_info)) + if paddr_vmcoreinfo_note == 0 or paddr_vmcoreinfo_note & 1: + # In the early boot case, extract vm_layout.kaslr_offset from the + # vmlinux image in physical memory. + if paddr_vmcoreinfo_note == 0: + kaslr_offset_phys = 0 + else: + kaslr_offset_phys = paddr_vmcoreinfo_note - 1 + with utils.pagination_off(): + gdb.execute("symbol-file {0} -o {1}".format( + utils.get_vmlinux(), hex(kaslr_offset_phys))) + kaslr_offset = gdb.parse_and_eval("vm_layout.kaslr_offset") + return "KERNELOFFSET=" + hex(kaslr_offset)[2:] inferior = gdb.selected_inferior() elf_note = inferior.read_memory(paddr_vmcoreinfo_note, 12) n_namesz, n_descsz, n_type = struct.unpack(">III", elf_note) @@ -78,6 +84,30 @@ def get_kerneloffset(): return None +def is_in_s390_decompressor(): + # DAT is always off in decompressor. Use this as an indicator. + # Note that in the kernel, DAT can be off during kexec() or restart. + # Accept this imprecision in order to avoid complicating things. + # It is unlikely that someone will run lx-symbols at these points. + pswm = int(gdb.parse_and_eval("$pswm")) + return (pswm & 0x0400000000000000) == 0 + + +def skip_decompressor(): + if utils.is_target_arch("s390"): + if is_in_s390_decompressor(): + # The address of the jump_to_kernel function is statically placed + # into svc_old_psw.addr (see ipl_data.c); read it from there. DAT + # is off, so we do not need to care about lowcore relocation. + svc_old_pswa = 0x148 + jump_to_kernel = int(gdb.parse_and_eval("*(unsigned long long *)" + + hex(svc_old_pswa))) + gdb.execute("tbreak *" + hex(jump_to_kernel)) + gdb.execute("continue") + while is_in_s390_decompressor(): + gdb.execute("stepi") + + class LxSymbols(gdb.Command): """(Re-)load symbols of Linux kernel and currently loaded modules. @@ -178,11 +208,7 @@ lx-symbols command.""" saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) # drop all current symbols and reload vmlinux - orig_vmlinux = 'vmlinux' - for obj in gdb.objfiles(): - if (obj.filename.endswith('vmlinux') or - obj.filename.endswith('vmlinux.debug')): - orig_vmlinux = obj.filename + orig_vmlinux = utils.get_vmlinux() gdb.execute("symbol-file", to_string=True) kerneloffset = get_kerneloffset() if kerneloffset is None: @@ -202,6 +228,8 @@ lx-symbols command.""" saved_state['breakpoint'].enabled = saved_state['enabled'] def invoke(self, arg, from_tty): + skip_decompressor() + self.module_paths = [os.path.abspath(os.path.expanduser(p)) for p in arg.split()] self.module_paths.append(os.getcwd()) |