> Date: Sat, 13 Jun 2020 00:03:14 +0200
> From: Klemens Nanni <[email protected]>
>
> DDB's "show struct" on sparc64 does not work because the boot loader
> does not load the kernel's ELF section ".SUNW_ctf".
>
> Adapt ofwboot to do so just like libsa already does on other platforms
> (such as amd64) and therefore enable DDB utilise CTF information.
>
> I needed this back when the earlier wireguard patchsets would panic due
> to memory alignment issues; those issues were fixed independently
> before I even started this diff, but here's the proper fix nonetheless.
>
> mpi mentioned the boot loader issue after I poked him regarding missing
> CTF information in DDB, the rest I managed to figure out myself afer
> reading through libsa's loadfile_elf.c:ELFNAME(), i.e. elf64_exec() on
> amd64, and simply copying the missing bits into ofwboot.
>
>
> To test, drop to DDB and simply do `show struct timespec' for example or
> pick a real panic/issue (mine disappeared):
>
> OpenBSD/sparc64 (xxx) (console)
>
> login: Stopped at db_enter+0x8: nop
> ddb{0}> show struct timespec
> struct timespec at 0x1361588 (16 bytes) {tv_sec = 0x100000081c3e008,
> tv_nsec = 0
> x9c23bf3030680003}
>
> Feedback? OK?
ok kettenis@
(there are some style issues with this code, but they are present in
the libsa version as well)
> diff --git a/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
> b/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
> index 887aa5745..5ccdc6e0c 100644
> --- a/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
> +++ b/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
> @@ -204,11 +204,24 @@ elf64_exec(int fd, Elf_Ehdr *elf, u_int64_t *entryp,
> void **ssymp, void **esymp)
> printf("read section headers: %s\n", strerror(errno));
> return (1);
> }
> +
> + size_t shstrsz = shp[elf->e_shstrndx].sh_size;
> + char *shstr = alloc(shstrsz);
> + if (lseek(fd, (off_t)shp[elf->e_shstrndx].sh_offset, SEEK_SET) == -1) {
> + printf("lseek section header string table: %s\n",
> strerror(errno));
> + return 1;
> + }
> + if (read(fd, shstr, shstrsz) != shstrsz) {
> + printf("read section header string table: %s\n",
> strerror(errno));
> + return 1;
> + }
> +
> for (i = 0; i < elf->e_shnum; i++, shp++) {
> if (shp->sh_type == SHT_NULL)
> continue;
> if (shp->sh_type != SHT_SYMTAB
> - && shp->sh_type != SHT_STRTAB) {
> + && shp->sh_type != SHT_STRTAB
> + && strcmp(shstr + shp->sh_name, ELF_CTF)) {
> shp->sh_offset = 0;
> continue;
> }
> @@ -244,7 +257,8 @@ elf64_exec(int fd, Elf_Ehdr *elf, u_int64_t *entryp, void
> **ssymp, void **esymp)
> off = size;
> for (first = 1, i = 0; i < elf->e_shnum; i++, shp++) {
> if (shp->sh_type == SHT_SYMTAB
> - || shp->sh_type == SHT_STRTAB) {
> + || shp->sh_type == SHT_STRTAB
> + || !strcmp(shstr + shp->sh_name, ELF_CTF)) {
> if (first)
> printf("symbols @ 0x%lx ", (u_long)addr);
> printf("%s%d", first ? "" : "+", (int)shp->sh_size);
> @@ -255,6 +269,7 @@ elf64_exec(int fd, Elf_Ehdr *elf, u_int64_t *entryp, void
> **ssymp, void **esymp)
> }
> addr += ELF_ALIGN(shp->sh_size);
> shp->sh_offset = off;
> + shp->sh_flags |= SHF_ALLOC;
> off += ELF_ALIGN(shp->sh_size);
> first = 0;
> }
> diff --git a/sys/arch/sparc64/stand/ofwboot/vers.c
> b/sys/arch/sparc64/stand/ofwboot/vers.c
> index cc2630e4e..2a743eee2 100644
> --- a/sys/arch/sparc64/stand/ofwboot/vers.c
> +++ b/sys/arch/sparc64/stand/ofwboot/vers.c
> @@ -1 +1 @@
> -const char version[] = "1.19";
> +const char version[] = "1.20";
>
>