Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for qXfer:libraries{,-svr4}:read #142

Merged
merged 8 commits into from
Jan 6, 2024

Conversation

alexcrichton
Copy link
Contributor

@alexcrichton alexcrichton commented Dec 14, 2023

A toy project I've been working on involves loading a custom kernel and a custom guest into a KVM instance, and these commands enable gdb to be able to debug both the guest and the kernel at the same time by reporting where both images are loaded in the address space.

Initially this commit only implemented qXfer:libraries:read but it turned out that gdb never actually used that command. When implementing qXfer:libraries-svr4:read, however, gdb invoked that automatically (presumably it's target-specific). I ended up including both here for completeness.

This relates to #20 although I'm not sure if it closes it outright. The implementations here feel a little simplistic in terms of leaving all of the heavy-lifting to the taget. The implementations are copy/pasted from the memory-map command with edits for naming (as these are "just" returning XMLs as well).

An example gdb session with this support and using qXfer:libraries-svr4:read looks like:

(gdb) info sharedlibrary
From                To                  Syms Read   Shared Object Library
0x0000000100090000  0x00000001000a3568  Yes         /home/acrichto/code/wat/target/aarch64-unknown-none/debug/kernel
0x0000000100171000  0x00000001001b8a80  Yes         /home/acrichto/code/wat/target/aarch64-unknown-none/debug/guest
(gdb) b _start
Breakpoint 1 at 0x100094478 (2 locations)
Note: automatically using hardware breakpoints for read-only addresses.
(gdb) c
Continuing.

Breakpoint 1, 0x0000000100094478 in _start () from /home/acrichto/code/wat/target/aarch64-unknown-none/debug/kernel
(gdb) c
Continuing.

Breakpoint 1, guest::_start (args=0x100160fd0) at crates/guest/src/main.rs:9
9           vm::mmio_init(args);

Previously there were enough hooks in gdbstub to debug either the guest or the kernel, but this enables gdb to see both and work symbolically with both.

PS: very nice crate! The thorough documentation has made it super easy to integrate and the crate has clearly had a lot of thought put into it. A pleasure to use!

API Stability

  • This PR does not require a breaking API change

Checklist

  • Documentation
    • Ensured any public-facing rustdoc formatting looks good (via cargo doc)
    • (if appropriate) Added feature to "Debugging Features" in README.md
  • Validation
    • Included output of running examples/armv4t with RUST_LOG=trace + any relevant GDB output under the "Validation" section below
    • Included output of running ./example_no_std/check_size.sh before/after changes under the "Validation" section below
  • If implementing a new protocol extension IDET
    • Included a basic sample implementation in examples/armv4t
    • IDET can be optimized out (confirmed via ./example_no_std/check_size.sh)
    • OR implementation requires introducing non-optional binary bloat (please elaborate under "Description")
  • If upstreaming an Arch implementation
    • I have tested this code in my project, and to the best of my knowledge, it is working as intended.

Validation

GDB output
(gdb) info sharedlibrary
From                To                  Syms Read   Shared Object Library
0x0000000100090000  0x00000001000a3568  Yes         /home/acrichto/code/wat/target/aarch64-unknown-none/debug/kernel
0x0000000100171000  0x00000001001b8a80  Yes         /home/acrichto/code/wat/target/aarch64-unknown-none/debug/guest
armv4t output
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/examples/armv4t`
loading section ".text" into memory from [0x55550000..0x55550078]
Setting PC to 0x55550000
Waiting for a GDB connection on "127.0.0.1:9001"...
Debugger connected from 127.0.0.1:42668
 TRACE gdbstub::protocol::recv_packet > <-- +
 TRACE gdbstub::protocol::recv_packet > <-- $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+#ec
 TRACE gdbstub::protocol::response_writer > --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;ReverseContinue+;ReverseStep+;QDisableRandomization+;QEnvironmentHexEncoded+;QEnvironmentUnset+;QEnvironmentReset+;QStartupWithShell+;QSetWorkingDir+;swbreak+;hwbreak+;QCatchSyscalls+;qXfer:features:read+;qXfer:memory-map:read+;qXfer:exec-file:read+;qXfer:auxv:read+;qXfer:libraries:read+;qXfer:libraries-svr4:read+#28
 TRACE gdbstub::protocol::recv_packet     > <-- +
 TRACE gdbstub::protocol::recv_packet     > <-- $vMustReplyEmpty#3a
 INFO  gdbstub::stub::core_impl           > Unknown command: Ok("vMustReplyEmpty")
 TRACE gdbstub::protocol::response_writer > --> $#00
 TRACE gdbstub::protocol::recv_packet     > <-- +
 TRACE gdbstub::protocol::recv_packet     > <-- $QStartNoAckMode#b0
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::protocol::recv_packet     > <-- +
 TRACE gdbstub::protocol::recv_packet     > <-- $Hgp0.0#ad
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:features:read:target.xml:0,ffb#79
 TRACE gdbstub::protocol::response_writer > --> $m<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
    <architecture>armv4t</architecture>
    <feature name="org.gnu.gdb.arm.core">
        <vector id="padding" type="uint32" count="25"/>

        <reg name="r0" bitsize="32" type="uint32"/>
        <reg name="r1" bitsize="32" type="uint32"/>
        <reg name="r2" bitsize="32" type="uint32"/>
        <reg name="r3" bitsize="32" type="uint32"/>
        <reg name="r4" bitsize="32" type="uint32"/>
        <reg name="r5" bitsize="32" type="uint32"/>
        <reg name="r6" bitsize="32" type="uint32"/>
        <reg name="r7" bitsize="32" type="uint32"/>
        <reg name="r8" bitsize="32" type="uint32"/>
        <reg name="r9" bitsize="32" type="uint32"/>
        <reg name="r10" bitsize="32" type="uint32"/>
        <reg name="r11" bitsize="32" type="uint32"/>
        <reg name="r12" bitsize="32" type="uint32"/>
        <reg name="sp" bitsize="32" type="data_ptr"/>
        <reg name="lr" bitsize="32"/>
        <reg name="pc" bitsize="32" type="code_ptr"/>

        <!--
            For some reason, my version of `gdb-multiarch` doesn't seem to
            respect "regnum", and will not parse this custom target.xml unless I
            manually include the padding bytes in the target description.

            On the bright side, AFAIK, there aren't all that many architectures
            that use padding bytes. Heck, the only reason armv4t uses padding is
            for historical reasons (see comment below).

            Odds are if you're defining your own custom arch, you won't run into
            this issue, since you can just lay out all the registers in the
            correct order.
        -->
        <reg name="padding" type="padding" bitsize="32"/>

        <!-- The CPSR is register 25, rather than register 16, because
        the FPA registers historically were placed between the PC
        and the CPSR in the "g" packet. -->
        <reg name="cpsr" bitsize="32" regnum="25"/>
    </feature>
    <xi:include href="extra.xml"/>
</target>#38
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:features:read:target.xml:80d,ffb#15
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:features:read:extra.xml:0,ffb#16
 TRACE gdbstub::protocol::response_writer > --> $m<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<feature name="custom-armv4t-extension">
    <!--
        maps to a simple scratch register within the emulator. the GDB
        client can read the register using `p }�custom` and set it using
        `set }�custom=1337`
    -->
    <reg name="custom" bitsize="32" type="uint32"/>

    <!--
        pseudo-register that return the current time when read.

        notably, i've set up the target to NOT send this register as part of
        the regular register list, which means that GDB will fetch/update
        this register via the 'p' and 'P' packets respectively
    -->
    <reg name="time" bitsize="32" type="uint32"/>

    <!--
        pseudo-register that is always unavailable.

        it is supposed to be reported as 'x'-ed bytes in replies to 'p' packets
        and shown by the GDB client as "<unavailable>".
    -->
    <reg name="unavailable" bitsize="32" type="uint32"/>
</feature>#7d
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:features:read:extra.xml:3c5,ffb#b1
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:auxv:read::0,ffb#d8
 TRACE gdbstub::protocol::response_writer > --> $m��������#bb
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:auxv:read::8,ffb#e0
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $qTStatus#49
 INFO  gdbstub::stub::core_impl           > Unknown command: Ok("qTStatus")
 TRACE gdbstub::protocol::response_writer > --> $#00
 TRACE gdbstub::protocol::recv_packet     > <-- $?#3f
 TRACE gdbstub::protocol::response_writer > --> $T05thread:p01.01;#06
 TRACE gdbstub::protocol::recv_packet     > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::protocol::recv_packet     > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $qAttached:1#fa
GDB queried if it was attached to a process with PID 1
 TRACE gdbstub::protocol::response_writer > --> $1#31
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:exec-file:read:1:0,ffb#b7
 TRACE gdbstub::protocol::response_writer > --> $m/test.elf#c1
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:exec-file:read:1:9,ffb#c0
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $Hc-1#09
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::protocol::recv_packet     > <-- $qOffsets#4b
 TRACE gdbstub::protocol::response_writer > --> $Text=00;Data=00;Bss=00#94
 TRACE gdbstub::protocol::recv_packet     > <-- $g#67
 TRACE gdbstub::protocol::response_writer > --> $00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000107856341200005555xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1000000078563412#0a
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:libraries-svr4:read::0,ffb#8d
 TRACE gdbstub::protocol::response_writer > --> $m<library-list-svr4 version="1.0" main-lm="0x4">
    <library name="/test.elf" lm="0x8" l_addr="0" l_ld="0" lmid="0x14"/>
</library-list-svr4>#25
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:libraries-svr4:read::8d,ffb#f9
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:auxv:read::0,ffb#d8
 TRACE gdbstub::protocol::response_writer > --> $m��������#bb
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:auxv:read::8,ffb#e0
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:setfs:0#bf
 TRACE gdbstub::protocol::response_writer > --> $F0#76
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:open:6a7573742070726f62696e67,0,1c0#ed
 TRACE gdbstub::protocol::response_writer > --> $F-1,02#32
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:setfs:1#c0
 TRACE gdbstub::protocol::response_writer > --> $F0#76
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:open:2f746573742e656c66,0,0#1e
 TRACE gdbstub::protocol::response_writer > --> $F00#a6
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,0#ef
 TRACE gdbstub::protocol::response_writer > --> $F1000;�ELF��������������(�������UU4���@�������4� ���(���
�����������UU��UUx���x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ea
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,10540#b9
 TRACE gdbstub::protocol::response_writer > --> $F0230;������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#cc
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:fstat:0#bc
 TRACE gdbstub::protocol::response_writer > --> $F40;�����������������������������������p����������������������������#26
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,34#26
 TRACE gdbstub::protocol::response_writer > --> $F1000;����������UU��UUx���x�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#83
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,104b2#e8
 TRACE gdbstub::protocol::response_writer > --> $F02be;�.symtab�.strtab�.shstrtab�.text�.bss�.debug_info�.debug_abbrev�.debug_aranges�.debug_line�.debug_str�.comment�.ARM.attributes�.debug_frame���������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#d8
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,10078#bf
 TRACE gdbstub::protocol::response_writer > --> $F06f8;s�������������������.���UUx���������������o�����UUx�����o����x���	o�����t�y���	o�����l�4�UU0����i��	�o�����p�����int�����%����������������.�?���:�;�9�I�����@��B������4���:�;�9�I���������������}����>������������������������UUx�����������[�������������
�������������test.c�����������UU��	gK��Lg��i��J������/�%����e������f�j��/�����test.c�GNU C11 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] -mfloat-abi=soft -marm -march=armv4t -g -O0 -std=c11�main�GCC: (15:9-2019-q4-0ubuntu1) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]�A)���aeabi�������4T�����	����������������������������|�
�����������UUx���B����B
�t

B��������������������������UU������������x�UU����������������������������������������������������������������������������������������������������������������������	���������������
�����������������������UU������������x�UU������������x�UU������������x�UU��������+���x�UU��������7�����UUx�������<���x�UU��������I���x�UU��������W�����UU���������test.c�}�a�__DATA_START__�end�__DATA_END__�__BSS_END__�main�__TEXT_END__�__BSS_START__�__TEXT_START__��.symtab�.strtab�.shstrtab�.text�.bss�.debug_info�.debug_abbrev�.debug_aranges�.debug_line�.debug_str�.comment�.ARM.attributes�.debug_frame���������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#90
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,0#ef
 TRACE gdbstub::protocol::response_writer > --> $F1000;�ELF��������������(�������UU4���@�������4� ���(���
�����������UU��UUx���x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ea
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,10540#b9
 TRACE gdbstub::protocol::response_writer > --> $F0230;������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#cc
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,34#26
 TRACE gdbstub::protocol::response_writer > --> $F1000;����������UU��UUx���x�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#83
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,104b2#e8
 TRACE gdbstub::protocol::response_writer > --> $F02be;�.symtab�.strtab�.shstrtab�.text�.bss�.debug_info�.debug_abbrev�.debug_aranges�.debug_line�.debug_str�.comment�.ARM.attributes�.debug_frame���������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#d8
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,10078#bf
 TRACE gdbstub::protocol::response_writer > --> $F06f8;s�������������������.���UUx���������������o�����UUx�����o����x���	o�����t�y���	o�����l�4�UU0����i��	�o�����p�����int�����%����������������.�?���:�;�9�I�����@��B������4���:�;�9�I���������������}����>������������������������UUx�����������[�������������
�������������test.c�����������UU��	gK��Lg��i��J������/�%����e������f�j��/�����test.c�GNU C11 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] -mfloat-abi=soft -marm -march=armv4t -g -O0 -std=c11�main�GCC: (15:9-2019-q4-0ubuntu1) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]�A)���aeabi�������4T�����	����������������������������|�
�����������UUx���B����B
�t

B��������������������������UU������������x�UU����������������������������������������������������������������������������������������������������������������������	���������������
�����������������������UU������������x�UU������������x�UU������������x�UU��������+���x�UU��������7�����UUx�������<���x�UU��������I���x�UU��������W�����UU���������test.c�}�a�__DATA_START__�end�__DATA_END__�__BSS_END__�main�__TEXT_END__�__BSS_START__�__TEXT_START__��.symtab�.strtab�.shstrtab�.text�.bss�.debug_info�.debug_abbrev�.debug_aranges�.debug_line�.debug_str�.comment�.ARM.attributes�.debug_frame���������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#90
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,0#ef
 TRACE gdbstub::protocol::response_writer > --> $F1000;�ELF��������������(�������UU4���@�������4� ���(���
�����������UU��UUx���x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ea
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:fstat:0#bc
 TRACE gdbstub::protocol::response_writer > --> $F40;�����������������������������������p����������������������������#26
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,102fc#1b
 TRACE gdbstub::protocol::response_writer > --> $F0474;����������������������UU������������x�UU����������������������������������������������������������������������������������������������������������������������	���������������
�����������������������UU������������x�UU������������x�UU������������x�UU��������+���x�UU��������7�����UUx�������<���x�UU��������I���x�UU��������W�����UU���������test.c�}�a�__DATA_START__�end�__DATA_END__�__BSS_END__�main�__TEXT_END__�__BSS_START__�__TEXT_START__��.symtab�.strtab�.shstrtab�.text�.bss�.debug_info�.debug_abbrev�.debug_aranges�.debug_line�.debug_str�.comment�.ARM.attributes�.debug_frame���������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#31
 TRACE gdbstub::protocol::recv_packet     > <-- $vFile:pread:0,1000,10078#bf
 TRACE gdbstub::protocol::response_writer > --> $F06f8;s�������������������.���UUx���������������o�����UUx�����o����x���	o�����t�y���	o�����l�4�UU0����i��	�o�����p�����int�����%����������������.�?���:�;�9�I�����@��B������4���:�;�9�I���������������}����>������������������������UUx�����������[�������������
�������������test.c�����������UU��	gK��Lg��i��J������/�%����e������f�j��/�����test.c�GNU C11 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] -mfloat-abi=soft -marm -march=armv4t -g -O0 -std=c11�main�GCC: (15:9-2019-q4-0ubuntu1) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]�A)���aeabi�������4T�����	����������������������������|�
�����������UUx���B����B
�t

B��������������������������UU������������x�UU����������������������������������������������������������������������������������������������������������������������	���������������
�����������������������UU������������x�UU������������x�UU������������x�UU��������+���x�UU��������7�����UUx�������<���x�UU��������I���x�UU��������W�����UU���������test.c�}�a�__DATA_START__�end�__DATA_END__�__BSS_END__�main�__TEXT_END__�__BSS_START__�__TEXT_START__��.symtab�.strtab�.shstrtab�.text�.bss�.debug_info�.debug_abbrev�.debug_aranges�.debug_line�.debug_str�.comment�.ARM.attributes�.debug_frame���������������������������������������������������������UU����x�������������������!�����������x�UUx�����������������������&���������������x���w�������������������2�������������������U�������������������@���������������D��� �������������������O���������������d���_�������������������[�������0�������������������������������f�������0�������H���Y�������������������o������p������������}
���������������������������������������0���������������������������������������P������
�����������	���������������L���f�����������������������������������������������������������#90
 TRACE gdbstub::protocol::recv_packet     > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::protocol::recv_packet     > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:memory-map:read::0,ffb#18
 TRACE gdbstub::protocol::response_writer > --> $m<?xml version="1.0"?>
<!DOCTYPE memory-map
    PUBLIC "+//IDN gnu.org//DTD GDB Memory Map V1.0//EN"
            "http://sourceware.org/gdb/gdb-memory-map.dtd">
<memory-map>
    <memory type="ram" start="0x0" length="0x100000000"/>
</memory-map>#76
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:memory-map:read::f4,ffb#82
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,2#5f
 TRACE gdbstub::protocol::response_writer > --> $04b0#f6
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffe,2#35
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffc,2#33
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,2#5f
 TRACE gdbstub::protocol::response_writer > --> $04b0#f6
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffe,2#35
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffc,2#33
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $E79#b5
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::protocol::recv_packet     > <-- $qSymbol::#5b
 INFO  gdbstub::stub::core_impl           > Unknown command: Ok("qSymbol::")
 TRACE gdbstub::protocol::response_writer > --> $#00
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:libraries-svr4:read::0,ffb#8d
 TRACE gdbstub::protocol::response_writer > --> $m<library-list-svr4 version="1.0" main-lm="0x4">
    <library name="/test.elf" lm="0x8" l_addr="0" l_ld="0" lmid="0x14"/>
</library-list-svr4>#25
 TRACE gdbstub::protocol::recv_packet     > <-- $qXfer:libraries-svr4:read::8d,ffb#f9
 TRACE gdbstub::protocol::response_writer > --> $l#6c
Before/After `./example_no_std/check_size.sh` output

Before

target/release/gdbstub-nostd  :
section               size    addr
.interp                 27     568
.note.gnu.build-id      36     596
.note.ABI-tag           32     632
.gnu.hash               28     664
.dynsym                432     696
.dynstr                198    1128
.gnu.version            36    1326
.gnu.version_r          48    1368
.rela.dyn              192    1416
.rela.plt              312    1608
.init                   24    1920
.plt                   240    1952
.text                15324    2240
.fini                   20   17564
.rodata                746   17584
.eh_frame_hdr          276   18332
.eh_frame              944   18608
.init_array              8   85328
.fini_array              8   85336
.dynamic               496   85344
.got                   176   85840
.data                    8   86016
.bss                     8   86024
.comment                87       0
Total                19706

After

target/release/gdbstub-nostd  :
section               size    addr
.interp                 27     568
.note.gnu.build-id      36     596
.note.ABI-tag           32     632
.gnu.hash               28     664
.dynsym                432     696
.dynstr                198    1128
.gnu.version            36    1326
.gnu.version_r          48    1368
.rela.dyn              192    1416
.rela.plt              312    1608
.init                   24    1920
.plt                   240    1952
.text                15324    2240
.fini                   20   17564
.rodata                746   17584
.eh_frame_hdr          276   18332
.eh_frame              944   18608
.init_array              8   85328
.fini_array              8   85336
.dynamic               496   85344
.got                   176   85840
.data                    8   86016
.bss                     8   86024
.comment                87       0
Total                19706

A toy project I've been working on involves loading a custom kernel and
a custom guest into a KVM instance, and these commands enable `gdb` to
be able to debug both the guest and the kernel at the same time by
reporting where both images are loaded in the address space.

Initially this commit only implemented `qXfer:libraries:read` but it
turned out that gdb never actually used that command. When implementing
`qXfer:libraries-svr4:read`, however, gdb invoked that automatically
(presumably it's target-specific). I ended up including both here for
completeness.
@daniel5151
Copy link
Owner

Ah, very nice!

I'll try and find some time soon to give this a more thorough look through.

In the meantime, can you update the PR with some of the checkboxes + validation outlined in the PR template? Not sure if you missed that, or GitHub just didn't auto-suggest using it... Weird.

https://github.com/daniel5151/gdbstub/blob/master/.github/pull_request_template.md

@alexcrichton
Copy link
Contributor Author

I'll try and find some time soon to give this a more thorough look through.

No rush! What I'm working on is still proof-of-concept at the moment and may not see the light of day anyway. This'll help me debug things in the future and I figured I'd upstream after poking at it.

Not sure if you missed that, or GitHub just didn't auto-suggest using it... Weird.

heh no full disclosure I saw it and it seemed quite long so I replaced it with a description and figured I'd see what happened. In any case I've filled in the bits here, but I'm not sure how to handle the examples/armv4t example since this should only apply when more than one library is loaded which I don't think that's doing.

@daniel5151
Copy link
Owner

daniel5151 commented Dec 14, 2023

Ha, all good, appreciate the honesty! 😄
Thanks for filling it in, it's much appreciated.


As for the arrmv4t example... my usual advice there is pretty much "fake it (if you can)".

i.e: so long as the fake / stub implementation wouldn't make GDB blow up when connecting to the armv4t example, all new protocol features should land in-tree with a corresponding example implementation in armv4t.

e.g: maybe the stub implementation can just report a single entry (corresponding to the in-tree test binary)?

This is useful for two reasons:

  1. Future users of gdbstub can use the stub implementation as a jumping off point for implementing something more fleshed out in their own projects
  2. It give me - as the sole gdbstub dev - a bit of code that I can use for manual regression testing (since I never actually invested in a good testing framework for gdbstub - whoops!)

@daniel5151 daniel5151 self-requested a review December 14, 2023 22:54
@alexcrichton
Copy link
Contributor Author

Sounds good! I've filled in a few stubs which at least got info sharedlibraries printing something in gdb with the example. I'll note though that I don't actually know how to get gdb to call qXfer:libraries:read, so that part is untested. If you'd prefer I can remove that piece from this PR.

@daniel5151
Copy link
Owner

Yeah, lets nix the qXfer:libraries:read code from the PR in that case.

If someone ends up needing it, they can send a PR to fill in that gap (along with doing the work of digging into how we could validate it in-tree)

///
/// If `offset` is greater than the length of the underlying data, return
/// `Ok(0)`.
fn get_libraries_svr4(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's not as part of this PR... but having another API force the user return "raw XML" (vs. having gdbstub generate it on-the-fly) seems a little unfortunate from a usability POV.

e.g: In this case, I wonder if we could instead have an API that looks something like this instead:

fn get_libraries_srv4(
    &self, 
    main_lm: Target::Arch::Usize,
    report_lib: &mut dyn FnMut(
        /*name:*/ &str, 
        /*lm:*/ Target::Arch::Usize,
        /*l_addr:*/ Target::Arch::Usize,
        /*l_ld:*/ Target::Arch::Usize, 
        /*lmid:*/ Option<Target::Arch::Usize>
    )
) -> TargetResult<usize, Self>;

Though, as I typed this out, I remembered that I basically had the same through process while reviewing #54, and after reviewing that thread... I think the implementation in gdbstub would get a bit too hairy (especially when considering how we'd need to handle non-zero offset requests...)

Maybe a middle ground could be to keep the "raw XML" API, but also include some helper XML builders that would make it easier for end-users to generate the properly formatted XML they need to return?

e.g:

struct LibrariesSvr4XmlBuilder<'a, T> { ... }

impl<'a, T> LibrariesSvr4XmlBuilder<'a, T> where T: Target {
    pub fn new_fixed(buf: &'a mut [u8]) -> Self { ... }
    // using a growable vec
    #[cfg(feature = "alloc")]
    pub fn new_dynamic(&mut Vec<u8>) -> Self { ... }
    // returns error if buffer is full
    pub fn add_lib(&mut self, name: &str, lm: T::Arch::Usize, l_addr: T::Arch::Usize, ...) -> TargetResult<(), T> { ... }
}

Under the hood, this could re-use the ManagedVec type https://github.com/daniel5151/gdbstub/blob/master/src/util/managed_vec.rs

Hmmm...


...but in any case, I don't think this is something that needs to happen as part of this PR.

I think adding this (and other) XML builders would be a workstream in its own right, and some more thinking is required on what I'd want maintain a cohesive-ish API across all the different kinds of XML that'd be getting generated.

TL;DR: feel free to ignore this comment - I basically just wrote it for future me 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is a really good idea yeah, and I was wondering how bad it would be to prototype this. I like your idea of a LibrariesSvr4XmlBuilder as a sort of maximally general way of doing this so if raw XML were available it could be given but otherwise it's just as convenient to use the builder. The builder could also have a helper function to take all the raw parameters to get_libraries_svr4 plus a closure and do it all on-the-fly.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am now tracking this and other instances of generating XML via #143

Copy link
Owner

@daniel5151 daniel5151 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a more proper look through. LGTM, barring those other discussions we had (wrt. updating the armv4t example, removing the untested libraries support, etc.)

src/protocol/commands.rs Outdated Show resolved Hide resolved
Copy link
Owner

@daniel5151 daniel5151 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's one last TODO to resolve, but aside from that, this should be ready to rock

src/target/ext/libraries.rs Outdated Show resolved Hide resolved
@daniel5151
Copy link
Owner

Ah, also: could you update some of the docs at https://docs.rs/gdbstub/latest/gdbstub/target/ext/section_offsets/index.html, given they relate to #20?

@alexcrichton
Copy link
Contributor Author

Ok pushed up a resolution of the TODO plus some more docs on the section_offsets module. I'll defer the XML-bits to #143 and leave the extensions like start=address for later since I don't fully understand those myself yet.

Copy link
Owner

@daniel5151 daniel5151 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nightly rustfmt strikes again...

Barring that one fix, I think this is now merge-ready!

@alexcrichton
Copy link
Contributor Author

Oops, sorry about that!

@daniel5151 daniel5151 merged commit 9790714 into daniel5151:master Jan 6, 2024
2 checks passed
@daniel5151
Copy link
Owner

daniel5151 commented Jan 6, 2024

Awesome! Thanks again for the PR.

I'll go ahead and publish 0.7.1 with this change shortly

EDIT: 0.7.1 is now available on crates.io 🎉

@alexcrichton alexcrichton deleted the libraries branch January 8, 2024 15:14
@alexcrichton
Copy link
Contributor Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants