> 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";
> 
> 

Reply via email to