From: Jonathan Gray Subject: Re: btrace(8): cache ELF .symtab, .strtab in sorted array To: Scott Cheloha via tech Cc: mpi@openbsd.org Date: Sat, 30 Mar 2024 18:59:02 +1100 On Wed, Mar 13, 2024 at 07:58:28PM -0500, Scott Cheloha via tech wrote: > Index: ksyms.c > =================================================================== > RCS file: /cvs/src/usr.sbin/btrace/ksyms.c,v > diff -u -p -r1.8 -r1.7 > --- ksyms.c 14 Mar 2024 00:54:54 -0000 1.8 > +++ ksyms.c 12 Mar 2024 17:22:24 -0000 1.7 > @@ -1,4 +1,4 @@ > -/* $OpenBSD: ksyms.c,v 1.8 2024/03/14 00:54:54 cheloha Exp $ */ > +/* $OpenBSD: ksyms.c,v 1.7 2024/03/12 17:22:24 cheloha Exp $ */ > > /* > * Copyright (c) 2016 Martin Pieuchot > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -30,60 +31,149 @@ > > #include "btrace.h" > > +struct sym { > + char *sym_name; > + unsigned long sym_value; /* from st_value */ > + unsigned long sym_size; /* from st_size */ > +}; > + > struct syms { > - int fd; > - Elf *elf; > - Elf_Scn *symtab; > - size_t strtabndx, nsymb; > + struct sym *table; > + size_t nsymb; > }; > > -int kelf_parse(struct syms *); > +int sym_compare_search(const void *, const void *); > +int sym_compare_sort(const void *, const void *); > > struct syms * > kelf_open(const char *path) > { > - struct syms *syms; > - int error; > + char *name; > + Elf *elf; > + Elf_Data *data = NULL; > + Elf_Scn *scn = NULL, *symtab; > + GElf_Sym sym; > + GElf_Shdr shdr; > + size_t i, shstrndx, strtabndx = SIZE_MAX, symtab_size; > + unsigned long diff; > + struct sym *tmp; > + struct syms *syms = NULL; > + int fd; > > if (elf_version(EV_CURRENT) == EV_NONE) > errx(1, "elf_version: %s", elf_errmsg(-1)); > > - if ((syms = calloc(1, sizeof(*syms))) == NULL) > - err(1, NULL); > - > - syms->fd = open(path, O_RDONLY); > - if (syms->fd == -1) { > + fd = open(path, O_RDONLY); > + if (fd == -1) { > warn("open: %s", path); > - free(syms); > return NULL; > } > > - if ((syms->elf = elf_begin(syms->fd, ELF_C_READ, NULL)) == NULL) { > + if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { > warnx("elf_begin: %s", elf_errmsg(-1)); > goto bad; > } > > - if (elf_kind(syms->elf) != ELF_K_ELF) > + if (elf_kind(elf) != ELF_K_ELF) > goto bad; > > - error = kelf_parse(syms); > - if (error) > + if (elf_getshdrstrndx(elf, &shstrndx) != 0) { > + warnx("elf_getshdrstrndx: %s", elf_errmsg(-1)); > goto bad; > + } > > - return syms; > + while ((scn = elf_nextscn(elf, scn)) != NULL) { > + if (gelf_getshdr(scn, &shdr) != &shdr) { > + warnx("elf_getshdr: %s", elf_errmsg(-1)); > + goto bad; > + } > + if ((name = elf_strptr(elf, shstrndx, shdr.sh_name)) == NULL) { > + warnx("elf_strptr: %s", elf_errmsg(-1)); > + goto bad; > + } > + if (strcmp(name, ELF_SYMTAB) == 0 && > + shdr.sh_type == SHT_SYMTAB && shdr.sh_entsize != 0) { > + symtab = scn; > + symtab_size = shdr.sh_size / shdr.sh_entsize; > + } > + if (strcmp(name, ELF_STRTAB) == 0 && > + shdr.sh_type == SHT_STRTAB) { > + strtabndx = elf_ndxscn(scn); > + } > + } > + if (symtab == NULL) { > + warnx("%s: %s: section not found", path, ELF_SYMTAB); > + goto bad; > + } only makes sense if symtab gets initialised as noted by smatch: /usr/src/usr.sbin/btrace/ksyms.c:104 kelf_open() error: uninitialized symbol 'symtab'. /usr/src/usr.sbin/btrace/ksyms.c:119 kelf_open() error: uninitialized symbol 'symtab_size'. Index: ksyms.c =================================================================== RCS file: /cvs/src/usr.sbin/btrace/ksyms.c,v diff -u -p -r1.9 ksyms.c --- ksyms.c 16 Mar 2024 17:42:37 -0000 1.9 +++ ksyms.c 30 Mar 2024 07:44:40 -0000 @@ -51,7 +51,7 @@ kelf_open(const char *path) char *name; Elf *elf; Elf_Data *data = NULL; - Elf_Scn *scn = NULL, *symtab; + Elf_Scn *scn = NULL, *symtab = NULL; GElf_Sym sym; GElf_Shdr shdr; size_t i, shstrndx, strtabndx = SIZE_MAX, symtab_size;