/* $NetBSD: symtab.c,v 1.10 2023/08/23 12:24:59 rin Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: symtab.c,v 1.10 2023/08/23 12:24:59 rin Exp $");
static int
address_compare(const void *a, const void *b)
{
const struct symbol *sa = a;
const struct symbol *sb = b;
return (int)(intmax_t)(sa->st_value - sb->st_value);
}
void
symtab_destroy(symtab_t *s)
{
if (s == NULL)
return;
for (size_t i = 0; i < s->nsymbols; i++)
free(s->symbols[i].st_name);
free(s->symbols);
free(s);
}
symtab_t *
symtab_create(int fd, int bind, int type)
{
Elf *elf;
symtab_t *st;
Elf_Scn *scn = NULL;
GElf_Ehdr ehdr;
if (elf_version(EV_CURRENT) == EV_NONE) {
warnx("Elf Library is out of date.");
return NULL;
}
elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL) {
warnx("Error opening elf file: %s", elf_errmsg(elf_errno()));
return NULL;
}
st = calloc(1, sizeof(*st));
if (st == NULL) {
warnx("Error allocating symbol table");
elf_end(elf);
return NULL;
}
if (gelf_getehdr(elf, &ehdr) == NULL) {
warnx("Error getting ELF Ehdr");
elf_end(elf);
return NULL;
}
st->ispie = ehdr.e_type == ET_DYN;
while ((scn = elf_nextscn(elf, scn)) != NULL) {
GElf_Shdr shdr;
Elf_Data *edata;
size_t ns;
struct symbol *s;