diff --git a/README.adoc b/README.adoc index bd7e3ba..2bf7f3c 100644 --- a/README.adoc +++ b/README.adoc @@ -7699,6 +7699,26 @@ It is already usable with: TODO: factor <> with this: +===== QEMU user mode GDB + +It's nice when the obvious works, right? + +.... +./run --debug-guest --user ./x86_64.out +.... + +and on another shell: + +.... +./run-gdb --user ./x86_64.out main +.... + +or to stop at the very first instruction of a freestanding program: + +.... +./run-gdb --no-continue --user ./x86_64.out +.... + ==== gem5 syscall emulation mode Analogous to <>, but less usable: @@ -7752,7 +7772,7 @@ Then I was told that it is has never been tested outside of x86_64: ===== gem5 syscall emulation mode CLI options .... -./run --gem5 --user ./aarch64.out -- --options 'op1 "op 2" op3' +./run --gem5 --user ./x86_64.out -- --options 'op1 "op 2" op3' .... ==== User mode vs full system benchmark diff --git a/common.py b/common.py index ebd7ca4..3915f40 100644 --- a/common.py +++ b/common.py @@ -792,6 +792,7 @@ def setup(parser): # Kernel modules. this_module.kernel_modules_build_base_dir = os.path.join(this_module.out_dir, 'kernel_modules') this_module.kernel_modules_build_dir = os.path.join(this_module.kernel_modules_build_base_dir, args.arch) + this_module.kernel_modules_build_subdir = os.path.join(this_module.kernel_modules_build_dir, kernel_modules_subdir) this_module.kernel_modules_build_host_dir = os.path.join(this_module.kernel_modules_build_base_dir, 'host') this_module.userland_build_dir = os.path.join(this_module.out_dir, 'userland', args.arch) this_module.out_rootfs_overlay_dir = os.path.join(this_module.out_dir, 'rootfs_overlay', args.arch) diff --git a/run b/run index acb2814..79af610 100755 --- a/run +++ b/run @@ -36,6 +36,7 @@ defaults = { 'tmux_args': '', 'trace': None, 'user': None, + 'user_before': '', 'vnc': False, } @@ -91,7 +92,7 @@ def main(args, extra_args=None): do_trace = False # A dummy value that is already turned on by default and does not produce large output, # just to prevent QEMU from emitting a warning that '' is not valid. - trace_type = 'pr_manager_run' + trace_type = 'load_file' else: do_trace = True trace_type = args.trace @@ -205,6 +206,7 @@ def main(args, extra_args=None): os.path.join(common.qemu_build_dir, '{}-linux-user'.format(args.arch), 'qemu-{}'.format(args.arch)), ] + qemu_user_and_system_options + + shlex.split(args.user_before) + debug_args + [ args.user @@ -503,6 +505,12 @@ to use this option: help='''\ Run the given userland executable in user mode instead of full system mode. In gem5, user mode is called Syscall Emulation (SE) mode and uses se.py. +''' + ) + parser.add_argument( + '--user-before', default=defaults['user_before'], + help='''\ +Arguments to pass to the QEMU user mode CLI before the program to execute. ''' ) parser.add_argument( diff --git a/run-gdb b/run-gdb index c9e7f60..9a4ea83 100755 --- a/run-gdb +++ b/run-gdb @@ -11,11 +11,12 @@ import common defaults = { 'after': '', 'before': '', - 'sim': False, - 'no_continue': False, - 'kgdb': False, - 'no_lxsymbols': False, 'break_at': None, + 'kgdb': False, + 'no_continue': False, + 'no_lxsymbols': False, + 'sim': False, + 'user': None, } def main(args, extra_args=None): @@ -34,26 +35,27 @@ def main(args, extra_args=None): args = common.resolve_args(defaults, args, extra_args) after = shlex.split(args.after) before = shlex.split(args.before) - if args.no_lxsymbols or args.baremetal is not None: - lx_symbols = [] - else: - lx_symbols = ['-ex', 'lx-symbols {}'.format(common.kernel_modules_build_subdir)] if args.break_at is not None: break_at = ['-ex', 'break {}'.format(args.break_at)] else: break_at = [] - if args.baremetal is None: - image = common.vmlinux - allowed_toolchains = ['buildroot', 'crosstool-ng', 'host'] + linux_full_system = (args.baremetal is None and args.user is None) + if args.user: + image = args.user + elif args.baremetal: + image = args.baremetal else: - image = common.image + image = common.vmlinux + if args.baremetal: allowed_toolchains = ['crosstool-ng', 'buildroot', 'host'] + else: + allowed_toolchains = ['buildroot', 'crosstool-ng', 'host'] cmd = ( [common.get_toolchain_tool('gdb', allowed_toolchains=allowed_toolchains)] + before + ['-q'] ) - if args.baremetal is None: + if linux_full_system: cmd.extend(['-ex', 'add-auto-load-safe-path {}'.format(common.linux_build_dir)]) if args.sim: target = 'sim' @@ -85,7 +87,9 @@ def main(args, extra_args=None): # # The lx-symbols commands gets loaded through the file vmlinux-gdb.py # which gets put on the kernel build root when python debugging scripts are enabled. - cmd.extend(['-ex', 'continue'] + lx_symbols) + cmd.extend(['-ex', 'continue']) + if not args.no_lxsymbols and linux_full_system: + cmd.extend(['-ex', 'lx-symbols {}'.format(common.kernel_modules_build_subdir)]) cmd.extend(after) return common.run_cmd(cmd, cmd_file=os.path.join(common.run_dir, 'run-gdb.sh'), cwd=common.linux_build_dir) @@ -115,6 +119,9 @@ See: https://github.com/cirosantilli/linux-kernel-module-cheat#gdb-builtin-cpu-s parser.add_argument( '-X', '--no-lxsymbols', default=defaults['no_lxsymbols'], action='store_true' ) + parser.add_argument( + '--user', default=defaults['user'], + ) parser.add_argument( 'break_at', nargs='?', help='Extra options to append at the end of the emulator command line'