[Bug gdb/34519] New: RISC-V: GDB crashes when disassembling elf32-bigriscv produced by -mbig-endian, and remote PC is byte-swapped

mumuxi_ll at outlook dot com via Gdb-prs <[email protected]>
Newsgroups gmane.comp.gdb.bugs.discuss
Message-ID <[email protected]/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=34519

            Bug ID: 34519
           Summary: RISC-V: GDB crashes when disassembling elf32-bigriscv
                    produced by -mbig-endian, and remote PC is
                    byte-swapped
           Product: gdb
           Version: 16.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: mumuxi_ll at outlook dot com
  Target Milestone: ---

Hi GDB maintainers,

I would like to report a RISC-V big-endian debugging issue.  A
riscv64-unknown-elf GDB configured for the normal little-endian target
can load an elf32-bigriscv executable produced by GCC with -mbig-endian,
but it crashes when asked to disassemble code from that executable.

There also appears to be a separate remote-debugging endianness issue:
when debugging the same big-endian ELF on a big-endian RISC-V QEMU target,
GDB can set a breakpoint at the correct symbol address, but after the
breakpoint is hit, the reported PC value is byte-swapped.

Program compiler:

  riscv64-unknown-elf-gcc

  GCC was configured for target riscv64-unknown-elf.  The test program
  was compiled with -mbig-endian, -march=rv32ic and -mabi=ilp32.

How to repeat:

  The reproducer is a minimal freestanding RISC-V program.

  However, GDB crashes when trying to disassemble the same ELF locally:

    $ riscv64-unknown-elf-gdb -q -batch \
          -ex "disassemble _start" \
          le-gcc-mbig.elf

  Actual result:

    Fatal signal: Segmentation fault
    ----- Backtrace -----
    0x4e43bd ???
    0x5ef0e1 ???
    0x5ef1af ???
    0x7fb54784c41f ???
           
/build/glibc-B3wQXB/glibc-2.31/nptl/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
    0x8f140a ???
    0x490bbb ???
    0x569077 ???
    0x569ad0 ???
    0x56a1ec ???
    0x56b88b ???
    0x50b3c3 ???
    0x51036d ???
    0x514244 ???
    0x7dd3e3 ???
    0x691bb5 ???
    0x691c7f ???
    0x692c88 ???
    0x69388a ???
    0x436d74 ???
    0x7fb54766a082 __libc_start_main
            ../csu/libc-start.c:308
    0x448bf7 ???
    0xffffffffffffffff ???
    ---------------------
    A fatal error internal to GDB has been detected, further
    debugging is not possible.  GDB will now terminate.

    This is a bug, please report it.  For instructions, see:
    <https://www.gnu.org/software/gdb/bugs/>.

  The same crash happens with:

    $ riscv64-unknown-elf-gdb -q -batch \
          -ex "x/8i _start" \
          le-gcc-mbig.elf

Expected result:

  GDB should disassemble code from elf32-bigriscv in the same way objdump
  does, or at least report a normal error.  It should not crash.

Additional remote debugging issue:

  When the same big-endian ELF is run under a big-endian target,
  GDB can connect and can read memory.  For example:

    riscv64-unknown-elf-gdb -q -batch \
        -ex "target remote :3363" \
        -ex "show endian" \
        -ex "show architecture" \
        -ex "hbreak main" \
        -ex "continue" \
        -ex 'printf "after_continue_pc=%p\n", $pc' \
        -ex "info registers pc sp" \
        -ex "si" \
        -ex 'printf "after_si_pc=%p\n", $pc' \
        -ex "stepi" \
        -ex 'printf "after_stepi_pc=%p\n", $pc' \
        -ex "nexti" \
        -ex 'printf "after_nexti_pc=%p\n", $pc' \
        -ex "detach" \
        -ex "quit" \
        le-gcc-mbig.elf

  GDB output:

    Hardware assisted breakpoint 1 at 0x8000004c: file main.c, line 16.

    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x4c000080 in ?? ()
    after_continue_pc=0x4c000080
    pc             0x4c000080    0x4c000080
    sp             0xf00f0090    0xf00f0090
    0x50000080 in ?? ()
    after_si_pc=0x50000080
    0x54000080 in ?? ()
    after_stepi_pc=0x54000080
    0x58000080 in ?? ()
    after_nexti_pc=0x58000080

  The breakpoint was set at the correct symbol address, 0x8000004c.
  After it is hit, GDB reports the PC as 0x4c000080, which is the
  32-bit byte-swapped form of 0x8000004c.  The following single-step PC
  values show the same pattern.

  Source-level stepping also fails:

    Breakpoint 1 at 0x8000004c: file main.c, line 16.

    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x4c000080 in ?? ()
    at_main_pc=0x4c000080
    #0  0x4c000080 in ?? ()
    10      return y;
    11  }
    12
    13  int
    14  main(void)
    15  {
    16      uint32_t marker = 0x11223344u;
    17      sink = marker;
    18
    19      int value = helper(5);
    gdb-c-step.gdb:10: Error in sourced command file:
    Cannot find bounds of current function

Notes:

  The disassembly crash is reproducible without any remote target,
  so it appears independent from the target gdbstub.

  The PC byte-swapping issue is only observed in the remote debugging path.
  GDB does detect the target endianness as big endian:

    The target endianness is set automatically (currently big endian).
    The target architecture is set to "auto" (currently "riscv:rv32").

  Raw memory reads work:

    x/16xb _start
    x/4xw _start

  but instruction disassembly through GDB crashes.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.