Download raw body.
btrace(8): cache ELF .symtab, .strtab in sorted array
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 <mpi@openbsd.org>
> @@ -23,6 +23,7 @@
> #include <err.h>
> #include <fcntl.h>
> #include <gelf.h>
> +#include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> @@ -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;
btrace(8): cache ELF .symtab, .strtab in sorted array