Re: [PATCH v2] gdb: add support for handling core dumps on arm-none-eabi

Luis Machado via Gdb-patches
2020-10-06T12:46:06Z

On 10/6/20 1:32 AM, Paul Mathieu via Gdb-patches wrote:
>>> Having a sniffer for GDB_OSABI_NONE seems like the right way to do this.
>>>
>>> Since the format isn't specified (yet), I can still freely control it. I
>>> imagine I could add some sort of OSABI marker in the core file to mark
>>> it as an arm-none-eabi core.o
>>>
>>> My first guess was to set the EI_OSABI e_ident elf header field to
>>> ELFOSABI_NONE, but that happens to be the same enum value as
>>> ELFOSABI_SYSV, which is afaik broadly used by the linux kernel for core
>>> files. So it wouldn't be a good marker.
>>>
>>> Not sure what a better way would be to not abuse the ELF structure and
>>> produce reasonable ELF core dumps (since they already work so well with
>>> gdb).
>>
>> I really don't know either. Technically, it could be as simple as
>> adding a new section / note of your choice, but I don't know if that
>> would be an acceptable thing to do.
>
> So, I implemented a basic sniffer, and it seems like the core file is
> being recognized as GDB_OSABI_NONE, but gdb crashes while loading it.
> The assert & stack trace are as follows:
>
> gdbarch.c:3684: internal-error: void
> gdbarch_iterate_over_regset_sections(gdbarch*, void (*)(const char*,
> int, int, const regset*, const char*, void*), void*, const regcache*):
> Assertion `gdbarch->iterate_over_regset_sections != NULL' failed.
>
> #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
> #1 0x00007fd93a9a4537 in __GI_abort () at abort.c:79
> #2 0x000055e524ab29b7 in dump_core () at utils.c:204
> #3 0x000055e524ab770d in internal_vproblem(internal_problem *, const
> char *, int, const char *, typedef __va_list_tag __va_list_tag *) (
> problem=0x55e524f5a3a0 <internal_error_problem>, file=<optimized
> out>, line=<optimized out>, fmt=<optimized out>, ap=<optimized out>)
> at utils.c:414
> #4 0x000055e524ab78eb in internal_verror (file=<optimized out>,
> line=<optimized out>, fmt=<optimized out>, ap=ap@entry=0x7fffb8c40628)
> at utils.c:439
> #5 0x000055e524be45c2 in internal_error
> (file=file@entry=0x55e524c7e484 "gdbarch.c", line=line@entry=3684,
> fmt=<optimized out>)
> at errors.cc:55
> #6 0x000055e5248d8c48 in gdbarch_iterate_over_regset_sections
> (gdbarch=0x55e5261014f0,
> cb=0x55e5248354e0 <get_core_registers_cb(char const*, int, int,
> regset const*, char const*, void*)>, cb_data=0x7fffb8c40730,
> regcache=0x0) at gdbarch.c:3687
> #7 0x000055e524834f07 in core_target::fetch_registers
> (regno=<optimized out>, regcache=0x55e5261625c0, this=<optimized out>)
> at corelow.c:735
> #8 core_target::fetch_registers (this=<optimized out>,
> regcache=0x55e5261625c0, regno=<optimized out>) at corelow.c:723
> #9 0x000055e524a6ee8d in target_fetch_registers
> (regcache=regcache@entry=0x55e5261625c0, regno=regno@entry=15) at
> target.h:1334
> #10 0x000055e5249df14a in regcache::raw_update (regnum=15,
> this=0x55e5261625c0) at regcache.c:583
> #11 regcache::raw_update (this=0x55e5261625c0, regnum=<optimized out>)
> at regcache.c:572
> #12 0x000055e5249df1ea in readable_regcache::raw_read
> (this=0x55e5261625c0, regnum=15, buf=0x7fffb8c407c0 "\001") at
> regcache.c:597
> #13 0x000055e5249e4edf in readable_regcache::cooked_read<unsigned
> long, void> (this=this@entry=0x55e5261625c0, regnum=15,
> val=val@entry=0x7fffb8c40818) at regcache.c:769
> #14 0x000055e5249e1ce3 in regcache_cooked_read_unsigned
> (val=0x7fffb8c40818, regnum=<optimized out>, regcache=0x55e5261625c0)
> at regcache.c:790
> #15 regcache_read_pc (regcache=0x55e5261625c0) at regcache.c:1294
> #16 0x000055e524907e2e in post_create_inferior
> (target=target@entry=0x55e52615b480, from_tty=from_tty@entry=1) at
> infcmd.c:303
> #17 0x000055e5248360ff in core_target_open (arg=<error reading
> variable: value has been optimized out>,
> from_tty=<error reading variable: value has been optimized out>)
> at corelow.c:521
> #18 0x000055e5249571e0 in catch_command_errors (command=<optimized
> out>, arg=<optimized out>, from_tty=<optimized out>) at main.c:457
> #19 0x000055e524958ecf in captured_main_1 (context=<optimized out>) at
> main.c:1167
> #20 0x000055e52495904b in captured_main (data=<optimized out>) at main.c:1268
> #21 gdb_main (args=<optimized out>) at main.c:1268
> #22 0x000055e524765f0c in main (argc=<optimized out>, argv=<optimized
> out>) at gdb.c:32
>
> Seems to me like current_inferior()->gdbarch is returning the
> arm-linux gdbarch. Maybe this is because the main .elf executable
> itself is recognized as arm-linux? I have virtually no control over
> the executable image, so I would not be able to insert the same kind
> of note section as I would for a core file to differentiate it from
> arm-linux executables.

I think there may be enough hints here and there to be able to tell
those apart via an heuristic. Isn't there a particular note section or
flag that you can fetch and tell it is not a Linux executable but a
bare-metal one?

>
> I'm not sure how to proceed forward, would you have any pointers?

See the code in gdb/arm-tdep.c:arm_gdbarch_init, around the BFD flag
checks and the ABI checks. Is that something usable?

>
> Thanks!
> Paul
>