Page MenuHomeFreeBSD

D46720.id143546.diff
No OneTemporary

D46720.id143546.diff

diff --git a/usr.sbin/kldxref/Makefile b/usr.sbin/kldxref/Makefile
--- a/usr.sbin/kldxref/Makefile
+++ b/usr.sbin/kldxref/Makefile
@@ -1,17 +1,12 @@
PACKAGE= runtime
PROG= kldxref
MAN= kldxref.8
-SRCS= kldxref.c ef.c ef_obj.c elf.c
-SRCS+= ef_aarch64.c \
- ef_arm.c \
- ef_amd64.c \
- ef_i386.c \
- ef_mips.c \
- ef_powerpc.c \
- ef_riscv.c
+SRCS= kldxref.c
+
+CFLAGS+=-I${SRCTOP}/lib/libkldelf
WARNS?= 2
-LIBADD= elf
+LIBADD= elf kldelf
.include <bsd.prog.mk>
diff --git a/usr.sbin/kldxref/ef.h b/usr.sbin/kldxref/ef.h
deleted file mode 100644
--- a/usr.sbin/kldxref/ef.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) 2000, Boris Popov
- * All rights reserved.
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#ifndef _EF_H_
-#define _EF_H_
-
-#include <sys/linker_set.h>
-#include <stdbool.h>
-
-#define EF_CLOSE(ef) \
- (ef)->ef_ops->close((ef)->ef_ef)
-#define EF_SEG_READ_REL(ef, address, len, dest) \
- (ef)->ef_ops->seg_read_rel((ef)->ef_ef, address, len, dest)
-#define EF_SEG_READ_STRING(ef, address, len, dest) \
- (ef)->ef_ops->seg_read_string((ef)->ef_ef, address, len, dest)
-#define EF_SYMADDR(ef, symidx) \
- (ef)->ef_ops->symaddr((ef)->ef_ef, symidx)
-#define EF_LOOKUP_SET(ef, name, startp, stopp, countp) \
- (ef)->ef_ops->lookup_set((ef)->ef_ef, name, startp, stopp, countp)
-
-/* XXX, should have a different name. */
-typedef struct ef_file *elf_file_t;
-
-/* FreeBSD's headers define additional typedef's for ELF structures. */
-typedef Elf64_Size GElf_Size;
-typedef Elf64_Hashelt GElf_Hashelt;
-
-struct elf_file;
-
-struct elf_file_ops {
- void (*close)(elf_file_t ef);
- int (*seg_read_rel)(elf_file_t ef, GElf_Addr address, size_t len,
- void *dest);
- int (*seg_read_string)(elf_file_t ef, GElf_Addr address, size_t len,
- char *dest);
- GElf_Addr (*symaddr)(elf_file_t ef, GElf_Size symidx);
- int (*lookup_set)(elf_file_t ef, const char *name, GElf_Addr *startp,
- GElf_Addr *stopp, long *countp);
-};
-
-typedef int (elf_reloc_t)(struct elf_file *ef, const void *reldata,
- Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len,
- void *dest);
-
-struct elf_reloc_data {
- unsigned char class;
- unsigned char data;
- GElf_Half machine;
- elf_reloc_t *reloc;
-};
-
-#define ELF_RELOC(_class, _data, _machine, _reloc) \
- static struct elf_reloc_data __CONCAT(elf_reloc_data_, __LINE__) = { \
- .class = (_class), \
- .data = (_data), \
- .machine = (_machine), \
- .reloc = (_reloc) \
- }; \
- DATA_SET(elf_reloc, __CONCAT(elf_reloc_data_, __LINE__))
-
-struct elf_file {
- elf_file_t ef_ef;
- struct elf_file_ops *ef_ops;
- const char *ef_filename;
- Elf *ef_elf;
- elf_reloc_t *ef_reloc;
- GElf_Ehdr ef_hdr;
- size_t ef_pointer_size;
- int ef_fd;
-};
-
-#define elf_machine(ef) ((ef)->ef_hdr.e_machine)
-#define elf_class(ef) ((ef)->ef_hdr.e_ident[EI_CLASS])
-#define elf_encoding(ef) ((ef)->ef_hdr.e_ident[EI_DATA])
-
-/*
- * "Generic" versions of module metadata structures.
- */
-struct Gmod_depend {
- int md_ver_minimum;
- int md_ver_preferred;
- int md_ver_maximum;
-};
-
-struct Gmod_version {
- int mv_version;
-};
-
-struct Gmod_metadata {
- int md_version; /* structure version MDTV_* */
- int md_type; /* type of entry MDT_* */
- GElf_Addr md_data; /* specific data */
- GElf_Addr md_cval; /* common string label */
-};
-
-struct Gmod_pnp_match_info
-{
- GElf_Addr descr; /* Description of the table */
- GElf_Addr bus; /* Name of the bus for this table */
- GElf_Addr table; /* Pointer to pnp table */
- int entry_len; /* Length of each entry in the table (may be */
- /* longer than descr describes). */
- int num_entry; /* Number of entries in the table */
-};
-
-__BEGIN_DECLS
-
-/*
- * Attempt to parse an open ELF file as either an executable or DSO
- * (ef_open) or an object file (ef_obj_open). On success, these
- * routines initialize the 'ef_ef' and 'ef_ops' members of 'ef'.
- */
-int ef_open(struct elf_file *ef, int verbose);
-int ef_obj_open(struct elf_file *ef, int verbose);
-
-/*
- * Direct operations on an ELF file regardless of type. Many of these
- * use libelf.
- */
-
-/*
- * Open an ELF file with libelf. Populates fields other than ef_ef
- * and ef_ops in '*efile'.
- */
-int elf_open_file(struct elf_file *efile, const char *filename,
- int verbose);
-
-/* Close an ELF file. */
-void elf_close_file(struct elf_file *efile);
-
-/* Is an ELF file the same architecture as hdr? */
-bool elf_compatible(struct elf_file *efile, const GElf_Ehdr *hdr);
-
-/* The size of a single object of 'type'. */
-size_t elf_object_size(struct elf_file *efile, Elf_Type type);
-
-/* The size of a pointer in architecture of 'efile'. */
-size_t elf_pointer_size(struct elf_file *efile);
-
-/*
- * Read and convert an array of a data type from an ELF file. This is
- * a wrapper around gelf_xlatetom() which reads an array of raw ELF
- * objects from the file and converts them into host structures using
- * native endianness. The data is returned in a dynamically-allocated
- * buffer.
- */
-int elf_read_data(struct elf_file *efile, Elf_Type type, off_t offset,
- size_t len, void **out);
-
-/* Reads "raw" data from an ELF file without any translation. */
-int elf_read_raw_data(struct elf_file *efile, off_t offset, void *dst,
- size_t len);
-
-/*
- * A wrapper around elf_read_raw_data which returns the data in a
- * dynamically-allocated buffer.
- */
-int elf_read_raw_data_alloc(struct elf_file *efile, off_t offset,
- size_t len, void **out);
-
-/* Reads a single string at the given offset from an ELF file. */
-int elf_read_raw_string(struct elf_file *efile, off_t offset, char *dst,
- size_t len);
-
-/*
- * Read relocated data from an ELF file and return it in a
- * dynamically-allocated buffer. Note that no translation
- * (byte-swapping for endianness, 32-vs-64) is performed on the
- * returned data, but any ELF relocations which affect the contents
- * are applied to the returned data. The address parameter gives the
- * address of the data buffer if the ELF file were loaded into memory
- * rather than a direct file offset.
- */
-int elf_read_relocated_data(struct elf_file *efile, GElf_Addr address,
- size_t len, void **buf);
-
-/*
- * Read the program headers from an ELF file and return them in a
- * dynamically-allocated array of GElf_Phdr objects.
- */
-int elf_read_phdrs(struct elf_file *efile, size_t *nphdrp,
- GElf_Phdr **phdrp);
-
-/*
- * Read the section headers from an ELF file and return them in a
- * dynamically-allocated array of GElf_Shdr objects.
- */
-int elf_read_shdrs(struct elf_file *efile, size_t *nshdrp,
- GElf_Shdr **shdrp);
-
-/*
- * Read the dynamic table from a section of an ELF file into a
- * dynamically-allocated array of GElf_Dyn objects.
- */
-int elf_read_dynamic(struct elf_file *efile, int section_index, size_t *ndynp,
- GElf_Dyn **dynp);
-
-/*
- * Read a symbol table from a section of an ELF file into a
- * dynamically-allocated array of GElf_Sym objects.
- */
-int elf_read_symbols(struct elf_file *efile, int section_index,
- size_t *nsymp, GElf_Sym **symp);
-
-/*
- * Read a string table described by a section header of an ELF file
- * into a dynamically-allocated buffer.
- */
-int elf_read_string_table(struct elf_file *efile, const GElf_Shdr *shdr,
- long *strcnt, char **strtab);
-
-/*
- * Read a table of relocation objects from a section of an ELF file
- * into a dynamically-allocated array of GElf_Rel objects.
- */
-int elf_read_rel(struct elf_file *efile, int section_index, long *nrelp,
- GElf_Rel **relp);
-
-/*
- * Read a table of relocation-with-addend objects from a section of an
- * ELF file into a dynamically-allocated array of GElf_Rela objects.
- */
-int elf_read_rela(struct elf_file *efile, int section_index, long *nrelap,
- GElf_Rela **relap);
-
-/*
- * Read a string from an ELF file and return it in the provided
- * buffer. If the string is longer than the buffer, this fails with
- * EFAULT. The address parameter gives the address of the data buffer
- * if the ELF file were loaded into memory rather than a direct file
- * offset.
- */
-int elf_read_string(struct elf_file *efile, GElf_Addr address, void *dst,
- size_t len);
-
-/* Return the address extracted from a target pointer stored at 'p'. */
-GElf_Addr elf_address_from_pointer(struct elf_file *efile, const void *p);
-
-/*
- * Read a linker set and return an array of addresses extracted from the
- * relocated pointers in the linker set.
- */
-int elf_read_linker_set(struct elf_file *efile, const char *name,
- GElf_Addr **buf, long *countp);
-
-/*
- * Read and convert a target 'struct mod_depend' into a host
- * 'struct Gmod_depend'.
- */
-int elf_read_mod_depend(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_depend *mdp);
-
-/*
- * Read and convert a target 'struct mod_version' into a host
- * 'struct Gmod_version'.
- */
-int elf_read_mod_version(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_version *mdv);
-
-/*
- * Read and convert a target 'struct mod_metadata' into a host
- * 'struct Gmod_metadata'.
- */
-int elf_read_mod_metadata(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_metadata *md);
-
-/*
- * Read and convert a target 'struct mod_pnp_match_info' into a host
- * 'struct Gmod_pnp_match_info'.
- */
-int elf_read_mod_pnp_match_info(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_pnp_match_info *pnp);
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-int elf_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest);
-
-__END_DECLS
-
-#endif /* _EF_H_*/
diff --git a/usr.sbin/kldxref/ef.c b/usr.sbin/kldxref/ef.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) 2000, Boris Popov
- * All rights reserved.
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/param.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ef.h"
-
-#define MAXSEGS 16
-struct ef_file {
- char *ef_name;
- struct elf_file *ef_efile;
- GElf_Phdr *ef_ph;
- void *ef_fpage; /* First block of the file */
- int ef_fplen; /* length of first block */
- GElf_Hashelt ef_nbuckets;
- GElf_Hashelt ef_nchains;
- GElf_Hashelt *ef_buckets;
- GElf_Hashelt *ef_chains;
- GElf_Hashelt *ef_hashtab;
- caddr_t ef_strtab;
- long ef_strsz;
- GElf_Sym *ef_symtab;
- int ef_nsegs;
- GElf_Phdr *ef_segs[MAXSEGS];
- int ef_verbose;
- GElf_Rel *ef_rel; /* relocation table */
- long ef_relsz; /* number of entries */
- GElf_Rela *ef_rela; /* relocation table */
- long ef_relasz; /* number of entries */
-};
-
-static void ef_print_phdr(GElf_Phdr *);
-static GElf_Off ef_get_offset(elf_file_t, GElf_Addr);
-
-static void ef_close(elf_file_t ef);
-
-static int ef_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len,
- void *dest);
-static int ef_seg_read_string(elf_file_t ef, GElf_Addr address, size_t len,
- char *dest);
-
-static GElf_Addr ef_symaddr(elf_file_t ef, GElf_Size symidx);
-static int ef_lookup_set(elf_file_t ef, const char *name,
- GElf_Addr *startp, GElf_Addr *stopp, long *countp);
-static int ef_lookup_symbol(elf_file_t ef, const char *name,
- GElf_Sym **sym);
-
-static struct elf_file_ops ef_file_ops = {
- .close = ef_close,
- .seg_read_rel = ef_seg_read_rel,
- .seg_read_string = ef_seg_read_string,
- .symaddr = ef_symaddr,
- .lookup_set = ef_lookup_set,
-};
-
-static void
-ef_print_phdr(GElf_Phdr *phdr)
-{
-
- if ((phdr->p_flags & PF_W) == 0) {
- printf("text=0x%jx ", (uintmax_t)phdr->p_filesz);
- } else {
- printf("data=0x%jx", (uintmax_t)phdr->p_filesz);
- if (phdr->p_filesz < phdr->p_memsz)
- printf("+0x%jx",
- (uintmax_t)(phdr->p_memsz - phdr->p_filesz));
- printf(" ");
- }
-}
-
-static GElf_Off
-ef_get_offset(elf_file_t ef, GElf_Addr addr)
-{
- GElf_Phdr *ph;
- int i;
-
- for (i = 0; i < ef->ef_nsegs; i++) {
- ph = ef->ef_segs[i];
- if (addr >= ph->p_vaddr && addr < ph->p_vaddr + ph->p_memsz) {
- return (ph->p_offset + (addr - ph->p_vaddr));
- }
- }
- return (0);
-}
-
-/*
- * next two functions copied from link_elf.c
- */
-static int
-ef_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym)
-{
- unsigned long hash, symnum;
- GElf_Sym *symp;
- char *strp;
-
- /* First, search hashed global symbols */
- hash = elf_hash(name);
- symnum = ef->ef_buckets[hash % ef->ef_nbuckets];
-
- while (symnum != STN_UNDEF) {
- if (symnum >= ef->ef_nchains) {
- warnx("ef_lookup_symbol: file %s have corrupted symbol table\n",
- ef->ef_name);
- return (ENOENT);
- }
-
- symp = ef->ef_symtab + symnum;
- if (symp->st_name == 0) {
- warnx("ef_lookup_symbol: file %s have corrupted symbol table\n",
- ef->ef_name);
- return (ENOENT);
- }
-
- strp = ef->ef_strtab + symp->st_name;
-
- if (strcmp(name, strp) == 0) {
- if (symp->st_shndx != SHN_UNDEF ||
- (symp->st_value != 0 &&
- GELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
- *sym = symp;
- return (0);
- } else
- return (ENOENT);
- }
-
- symnum = ef->ef_chains[symnum];
- }
-
- return (ENOENT);
-}
-
-static int
-ef_lookup_set(elf_file_t ef, const char *name, GElf_Addr *startp,
- GElf_Addr *stopp, long *countp)
-{
- GElf_Sym *sym;
- char *setsym;
- int error, len;
-
- len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
- setsym = malloc(len);
- if (setsym == NULL)
- return (errno);
-
- /* get address of first entry */
- snprintf(setsym, len, "%s%s", "__start_set_", name);
- error = ef_lookup_symbol(ef, setsym, &sym);
- if (error != 0)
- goto out;
- *startp = sym->st_value;
-
- /* get address of last entry */
- snprintf(setsym, len, "%s%s", "__stop_set_", name);
- error = ef_lookup_symbol(ef, setsym, &sym);
- if (error != 0)
- goto out;
- *stopp = sym->st_value;
-
- /* and the number of entries */
- *countp = (*stopp - *startp) / elf_pointer_size(ef->ef_efile);
-
-out:
- free(setsym);
- return (error);
-}
-
-static GElf_Addr
-ef_symaddr(elf_file_t ef, GElf_Size symidx)
-{
- const GElf_Sym *sym;
-
- if (symidx >= ef->ef_nchains)
- return (0);
- sym = ef->ef_symtab + symidx;
-
- if (GELF_ST_BIND(sym->st_info) == STB_LOCAL &&
- sym->st_shndx != SHN_UNDEF && sym->st_value != 0)
- return (sym->st_value);
- return (0);
-}
-
-static int
-ef_parse_dynamic(elf_file_t ef, const GElf_Phdr *phdyn)
-{
- GElf_Shdr *shdr;
- GElf_Dyn *dyn, *dp;
- size_t i, ndyn, nshdr, nsym;
- int error;
- GElf_Off hash_off, sym_off, str_off;
- GElf_Off rel_off;
- GElf_Off rela_off;
- int rel_sz;
- int rela_sz;
- int dynamic_idx;
-
- /*
- * The kernel linker parses the PT_DYNAMIC segment to find
- * various important tables. The gelf API of libelf is
- * section-oriented and requires extracting data from sections
- * instead of segments (program headers). As a result,
- * iterate over section headers to read various tables after
- * parsing values from PT_DYNAMIC.
- */
- error = elf_read_shdrs(ef->ef_efile, &nshdr, &shdr);
- if (error != 0)
- return (EFTYPE);
- dyn = NULL;
-
- /* Find section for .dynamic. */
- dynamic_idx = -1;
- for (i = 0; i < nshdr; i++) {
- if (shdr[i].sh_type == SHT_DYNAMIC) {
- /*
- * PowerPC kernels contain additional sections
- * beyond .dynamic in PT_DYNAMIC due to a linker
- * script bug. Permit a section with a smaller
- * size as a workaround.
- */
- if (shdr[i].sh_offset != phdyn->p_offset ||
- ((elf_machine(ef->ef_efile) == EM_PPC ||
- elf_machine(ef->ef_efile) == EM_PPC64) ?
- shdr[i].sh_size > phdyn->p_filesz :
- shdr[i].sh_size != phdyn->p_filesz)) {
- warnx(".dynamic section doesn't match phdr");
- error = EFTYPE;
- goto out;
- }
- if (dynamic_idx != -1) {
- warnx("multiple SHT_DYNAMIC sections");
- error = EFTYPE;
- goto out;
- }
- dynamic_idx = i;
- }
- }
-
- error = elf_read_dynamic(ef->ef_efile, dynamic_idx, &ndyn, &dyn);
- if (error != 0)
- goto out;
-
- hash_off = rel_off = rela_off = sym_off = str_off = 0;
- rel_sz = rela_sz = 0;
- for (i = 0; i < ndyn; i++) {
- dp = &dyn[i];
- if (dp->d_tag == DT_NULL)
- break;
-
- switch (dp->d_tag) {
- case DT_HASH:
- if (hash_off != 0)
- warnx("second DT_HASH entry ignored");
- else
- hash_off = ef_get_offset(ef, dp->d_un.d_ptr);
- break;
- case DT_STRTAB:
- if (str_off != 0)
- warnx("second DT_STRTAB entry ignored");
- else
- str_off = ef_get_offset(ef, dp->d_un.d_ptr);
- break;
- case DT_SYMTAB:
- if (sym_off != 0)
- warnx("second DT_SYMTAB entry ignored");
- else
- sym_off = ef_get_offset(ef, dp->d_un.d_ptr);
- break;
- case DT_SYMENT:
- if (dp->d_un.d_val != elf_object_size(ef->ef_efile,
- ELF_T_SYM)) {
- error = EFTYPE;
- goto out;
- }
- break;
- case DT_REL:
- if (rel_off != 0)
- warnx("second DT_REL entry ignored");
- else
- rel_off = ef_get_offset(ef, dp->d_un.d_ptr);
- break;
- case DT_RELSZ:
- if (rel_sz != 0)
- warnx("second DT_RELSZ entry ignored");
- else
- rel_sz = dp->d_un.d_val;
- break;
- case DT_RELENT:
- if (dp->d_un.d_val != elf_object_size(ef->ef_efile,
- ELF_T_REL)) {
- error = EFTYPE;
- goto out;
- }
- break;
- case DT_RELA:
- if (rela_off != 0)
- warnx("second DT_RELA entry ignored");
- else
- rela_off = ef_get_offset(ef, dp->d_un.d_ptr);
- break;
- case DT_RELASZ:
- if (rela_sz != 0)
- warnx("second DT_RELSZ entry ignored");
- else
- rela_sz = dp->d_un.d_val;
- break;
- case DT_RELAENT:
- if (dp->d_un.d_val != elf_object_size(ef->ef_efile,
- ELF_T_RELA)) {
- error = EFTYPE;
- goto out;
- }
- break;
- }
- }
- if (hash_off == 0) {
- warnx("%s: no .hash section found\n", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (sym_off == 0) {
- warnx("%s: no .dynsym section found\n", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (str_off == 0) {
- warnx("%s: no .dynstr section found\n", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (rel_off == 0 && rela_off == 0) {
- warnx("%s: no ELF relocation table found\n", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
-
- nsym = 0;
- for (i = 0; i < nshdr; i++) {
- switch (shdr[i].sh_type) {
- case SHT_HASH:
- if (shdr[i].sh_offset != hash_off) {
- warnx("%s: ignoring SHT_HASH at different offset from DT_HASH",
- ef->ef_name);
- break;
- }
-
- /*
- * libelf(3) mentions ELF_T_HASH, but it is
- * not defined.
- */
- if (shdr[i].sh_size < sizeof(*ef->ef_hashtab) * 2) {
- warnx("hash section too small");
- error = EFTYPE;
- goto out;
- }
- error = elf_read_data(ef->ef_efile, ELF_T_WORD,
- shdr[i].sh_offset, shdr[i].sh_size,
- (void **)&ef->ef_hashtab);
- if (error != 0) {
- warnc(error, "can't read hash table");
- goto out;
- }
- ef->ef_nbuckets = ef->ef_hashtab[0];
- ef->ef_nchains = ef->ef_hashtab[1];
- if ((2 + ef->ef_nbuckets + ef->ef_nchains) *
- sizeof(*ef->ef_hashtab) != shdr[i].sh_size) {
- warnx("inconsistent hash section size");
- error = EFTYPE;
- goto out;
- }
-
- ef->ef_buckets = ef->ef_hashtab + 2;
- ef->ef_chains = ef->ef_buckets + ef->ef_nbuckets;
- break;
- case SHT_DYNSYM:
- if (shdr[i].sh_offset != sym_off) {
- warnx("%s: ignoring SHT_DYNSYM at different offset from DT_SYMTAB",
- ef->ef_name);
- break;
- }
- error = elf_read_symbols(ef->ef_efile, i, &nsym,
- &ef->ef_symtab);
- if (error != 0) {
- if (ef->ef_verbose)
- warnx("%s: can't load .dynsym section (0x%jx)",
- ef->ef_name, (uintmax_t)sym_off);
- goto out;
- }
- break;
- case SHT_STRTAB:
- if (shdr[i].sh_offset != str_off)
- break;
- error = elf_read_string_table(ef->ef_efile,
- &shdr[i], &ef->ef_strsz, &ef->ef_strtab);
- if (error != 0) {
- warnx("can't load .dynstr section");
- error = EIO;
- goto out;
- }
- break;
- case SHT_REL:
- if (shdr[i].sh_offset != rel_off)
- break;
- if (shdr[i].sh_size != rel_sz) {
- warnx("%s: size mismatch for DT_REL section",
- ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- error = elf_read_rel(ef->ef_efile, i, &ef->ef_relsz,
- &ef->ef_rel);
- if (error != 0) {
- warnx("%s: cannot load DT_REL section",
- ef->ef_name);
- goto out;
- }
- break;
- case SHT_RELA:
- if (shdr[i].sh_offset != rela_off)
- break;
- if (shdr[i].sh_size != rela_sz) {
- warnx("%s: size mismatch for DT_RELA section",
- ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- error = elf_read_rela(ef->ef_efile, i, &ef->ef_relasz,
- &ef->ef_rela);
- if (error != 0) {
- warnx("%s: cannot load DT_RELA section",
- ef->ef_name);
- goto out;
- }
- break;
- }
- }
-
- if (ef->ef_hashtab == NULL) {
- warnx("%s: did not find a symbol hash table", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (ef->ef_symtab == NULL) {
- warnx("%s: did not find a dynamic symbol table", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (nsym != ef->ef_nchains) {
- warnx("%s: symbol count mismatch", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (ef->ef_strtab == NULL) {
- warnx("%s: did not find a dynamic string table", ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (rel_off != 0 && ef->ef_rel == NULL) {
- warnx("%s: did not find a DT_REL relocation table",
- ef->ef_name);
- error = EFTYPE;
- goto out;
- }
- if (rela_off != 0 && ef->ef_rela == NULL) {
- warnx("%s: did not find a DT_RELA relocation table",
- ef->ef_name);
- error = EFTYPE;
- goto out;
- }
-
- error = 0;
-out:
- free(dyn);
- free(shdr);
- return (error);
-}
-
-static int
-ef_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len, void *dest)
-{
- GElf_Off ofs;
- const GElf_Rela *a;
- const GElf_Rel *r;
- int error;
-
- ofs = ef_get_offset(ef, address);
- if (ofs == 0) {
- if (ef->ef_verbose)
- warnx("ef_seg_read_rel(%s): bad address (%jx)",
- ef->ef_name, (uintmax_t)address);
- return (EFAULT);
- }
- error = elf_read_raw_data(ef->ef_efile, ofs, dest, len);
- if (error != 0)
- return (error);
-
- for (r = ef->ef_rel; r < &ef->ef_rel[ef->ef_relsz]; r++) {
- error = elf_reloc(ef->ef_efile, r, ELF_T_REL, 0, address,
- len, dest);
- if (error != 0)
- return (error);
- }
- for (a = ef->ef_rela; a < &ef->ef_rela[ef->ef_relasz]; a++) {
- error = elf_reloc(ef->ef_efile, a, ELF_T_RELA, 0, address,
- len, dest);
- if (error != 0)
- return (error);
- }
- return (0);
-}
-
-static int
-ef_seg_read_string(elf_file_t ef, GElf_Addr address, size_t len, char *dest)
-{
- GElf_Off ofs;
-
- ofs = ef_get_offset(ef, address);
- if (ofs == 0) {
- if (ef->ef_verbose)
- warnx("ef_seg_read_string(%s): bad offset (%jx:%ju)",
- ef->ef_name, (uintmax_t)address, (uintmax_t)ofs);
- return (EFAULT);
- }
-
- return (elf_read_raw_string(ef->ef_efile, ofs, dest, len));
-}
-
-int
-ef_open(struct elf_file *efile, int verbose)
-{
- elf_file_t ef;
- GElf_Ehdr *hdr;
- size_t i, nphdr, nsegs;
- int error;
- GElf_Phdr *phdr, *phdyn;
-
- hdr = &efile->ef_hdr;
- if (hdr->e_phnum == 0 ||
- hdr->e_phentsize != elf_object_size(efile, ELF_T_PHDR) ||
- hdr->e_shnum == 0 || hdr->e_shoff == 0 ||
- hdr->e_shentsize != elf_object_size(efile, ELF_T_SHDR))
- return (EFTYPE);
-
- ef = malloc(sizeof(*ef));
- if (ef == NULL)
- return (errno);
-
- efile->ef_ef = ef;
- efile->ef_ops = &ef_file_ops;
-
- bzero(ef, sizeof(*ef));
- ef->ef_verbose = verbose;
- ef->ef_name = strdup(efile->ef_filename);
- ef->ef_efile = efile;
-
- error = elf_read_phdrs(efile, &nphdr, &ef->ef_ph);
- if (error != 0) {
- phdr = NULL;
- goto out;
- }
-
- error = EFTYPE;
- nsegs = 0;
- phdyn = NULL;
- phdr = ef->ef_ph;
- for (i = 0; i < nphdr; i++, phdr++) {
- if (verbose > 1)
- ef_print_phdr(phdr);
- switch (phdr->p_type) {
- case PT_LOAD:
- if (nsegs < MAXSEGS)
- ef->ef_segs[nsegs] = phdr;
- nsegs++;
- break;
- case PT_PHDR:
- break;
- case PT_DYNAMIC:
- phdyn = phdr;
- break;
- }
- }
- if (verbose > 1)
- printf("\n");
- if (phdyn == NULL) {
- warnx("Skipping %s: not dynamically-linked",
- ef->ef_name);
- goto out;
- }
-
- if (nsegs > MAXSEGS) {
- warnx("%s: too many segments", ef->ef_name);
- goto out;
- }
- ef->ef_nsegs = nsegs;
-
- error = ef_parse_dynamic(ef, phdyn);
-out:
- if (error != 0)
- ef_close(ef);
- return (error);
-}
-
-static void
-ef_close(elf_file_t ef)
-{
- free(ef->ef_rela);
- free(ef->ef_rel);
- free(ef->ef_strtab);
- free(ef->ef_symtab);
- free(ef->ef_hashtab);
- free(ef->ef_ph);
- if (ef->ef_name)
- free(ef->ef_name);
- ef->ef_efile->ef_ops = NULL;
- ef->ef_efile->ef_ef = NULL;
- free(ef);
-}
diff --git a/usr.sbin/kldxref/ef_aarch64.c b/usr.sbin/kldxref/ef_aarch64.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_aarch64.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*-
- * Copyright (c) 2005 Peter Grehan.
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_aarch64_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- switch (rtype) {
- case R_AARCH64_RELATIVE:
- addr = relbase + addend;
- le64enc(where, addr);
- break;
- case R_AARCH64_ABS64:
- addr = EF_SYMADDR(ef, symidx) + addend;
- le64enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- break;
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS64, ELFDATA2LSB, EM_AARCH64, ef_aarch64_reloc);
diff --git a/usr.sbin/kldxref/ef_amd64.c b/usr.sbin/kldxref/ef_amd64.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_amd64.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2003 Jake Burkholder.
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_amd64_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rel *rel;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_REL:
- rel = (const GElf_Rel *)reldata;
- where = (char *)dest + (relbase + rel->r_offset - dataoff);
- addend = 0;
- rtype = GELF_R_TYPE(rel->r_info);
- symidx = GELF_R_SYM(rel->r_info);
- break;
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- if (reltype == ELF_T_REL) {
- /* Addend is 32 bit on 32 bit relocs */
- switch (rtype) {
- case R_X86_64_PC32:
- case R_X86_64_32S:
- addend = le32dec(where);
- break;
- default:
- addend = le64dec(where);
- break;
- }
- }
-
- switch (rtype) {
- case R_X86_64_NONE: /* none */
- break;
- case R_X86_64_64: /* S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- le64enc(where, addr);
- break;
- case R_X86_64_32S: /* S + A sign extend */
- addr = EF_SYMADDR(ef, symidx) + addend;
- le32enc(where, addr);
- break;
- case R_X86_64_GLOB_DAT: /* S */
- addr = EF_SYMADDR(ef, symidx);
- le64enc(where, addr);
- break;
- case R_X86_64_RELATIVE: /* B + A */
- addr = relbase + addend;
- le64enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS64, ELFDATA2LSB, EM_X86_64, ef_amd64_reloc);
diff --git a/usr.sbin/kldxref/ef_arm.c b/usr.sbin/kldxref/ef_arm.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_arm.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2003 Jake Burkholder.
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
- * Copyright (c) 2023 Jessica Clarke <jrtc27@FreeBSD.org>
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_arm_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rel *rel;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_REL:
- rel = (const GElf_Rel *)reldata;
- where = (char *)dest + (relbase + rel->r_offset - dataoff);
- addend = 0;
- rtype = GELF_R_TYPE(rel->r_info);
- symidx = GELF_R_SYM(rel->r_info);
- break;
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- if (reltype == ELF_T_REL)
- addend = le32dec(where);
-
- switch (rtype) {
- case R_ARM_ABS32: /* S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- le32enc(where, addr);
- break;
- case R_ARM_RELATIVE: /* B + A */
- addr = relbase + addend;
- le32enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS32, ELFDATA2LSB, EM_ARM, ef_arm_reloc);
diff --git a/usr.sbin/kldxref/ef_i386.c b/usr.sbin/kldxref/ef_i386.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_i386.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2003 Jake Burkholder.
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_i386_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rel *rel;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_REL:
- rel = (const GElf_Rel *)reldata;
- where = (char *)dest + (relbase + rel->r_offset - dataoff);
- addend = 0;
- rtype = GELF_R_TYPE(rel->r_info);
- symidx = GELF_R_SYM(rel->r_info);
- break;
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- if (reltype == ELF_T_REL)
- addend = le32dec(where);
-
- switch (rtype) {
- case R_386_RELATIVE: /* B + A */
- addr = relbase + addend;
- le32enc(where, addr);
- break;
- case R_386_32: /* S + A - P */
- addr = EF_SYMADDR(ef, symidx) + addend;
- le32enc(where, addr);
- break;
- case R_386_GLOB_DAT: /* S */
- addr = EF_SYMADDR(ef, symidx);
- le32enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS32, ELFDATA2LSB, EM_386, ef_i386_reloc);
diff --git a/usr.sbin/kldxref/ef_mips.c b/usr.sbin/kldxref/ef_mips.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_mips.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 John Baldwin <jhb@FreeBSD.org>
- *
- * This software was developed by SRI International and the University of
- * Cambridge Computer Laboratory (Department of Computer Science and
- * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
- * DARPA SSITH research programme.
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_mips_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rel *rel;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_REL:
- rel = (const GElf_Rel *)reldata;
- where = (char *)dest + (relbase + rel->r_offset - dataoff);
- addend = 0;
- rtype = GELF_R_TYPE(rel->r_info);
- symidx = GELF_R_SYM(rel->r_info);
- break;
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- if (reltype == ELF_T_REL) {
- if (elf_class(ef) == ELFCLASS64) {
- if (elf_encoding(ef) == ELFDATA2LSB)
- addend = le64dec(where);
- else
- addend = be64dec(where);
- } else {
- if (elf_encoding(ef) == ELFDATA2LSB)
- addend = le32dec(where);
- else
- addend = be32dec(where);
- }
- }
-
- switch (rtype) {
- case R_MIPS_64: /* S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- if (elf_encoding(ef) == ELFDATA2LSB)
- le64enc(where, addr);
- else
- be64enc(where, addr);
- break;
- case R_MIPS_32: /* S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- if (elf_encoding(ef) == ELFDATA2LSB)
- le32enc(where, addr);
- else
- be32enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS32, ELFDATA2LSB, EM_MIPS, ef_mips_reloc);
-ELF_RELOC(ELFCLASS32, ELFDATA2MSB, EM_MIPS, ef_mips_reloc);
-ELF_RELOC(ELFCLASS64, ELFDATA2LSB, EM_MIPS, ef_mips_reloc);
-ELF_RELOC(ELFCLASS64, ELFDATA2MSB, EM_MIPS, ef_mips_reloc);
diff --git a/usr.sbin/kldxref/ef_obj.c b/usr.sbin/kldxref/ef_obj.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_obj.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) 2000, Boris Popov
- * Copyright (c) 1998-2000 Doug Rabson
- * Copyright (c) 2004 Peter Wemm
- * All rights reserved.
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/param.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ef.h"
-
-typedef struct {
- GElf_Addr addr;
- GElf_Off offset;
- GElf_Off size;
- int flags;
- int sec; /* Original section */
- char *name;
-} Elf_progent;
-
-typedef struct {
- GElf_Rel *rel;
- long nrel;
- int sec;
-} Elf_relent;
-
-typedef struct {
- GElf_Rela *rela;
- long nrela;
- int sec;
-} Elf_relaent;
-
-struct ef_file {
- char *ef_name;
- struct elf_file *ef_efile;
-
- Elf_progent *progtab;
- int nprogtab;
-
- Elf_relaent *relatab;
- int nrela;
-
- Elf_relent *reltab;
- int nrel;
-
- GElf_Sym *ddbsymtab; /* The symbol table we are using */
- size_t ddbsymcnt; /* Number of symbols */
- caddr_t ddbstrtab; /* String table */
- long ddbstrcnt; /* number of bytes in string table */
-
- caddr_t shstrtab; /* Section name string table */
- long shstrcnt; /* number of bytes in string table */
-
- int ef_verbose;
-};
-
-static void ef_obj_close(elf_file_t ef);
-
-static int ef_obj_seg_read_rel(elf_file_t ef, GElf_Addr address,
- size_t len, void *dest);
-static int ef_obj_seg_read_string(elf_file_t ef, GElf_Addr address,
- size_t len, char *dest);
-
-static GElf_Addr ef_obj_symaddr(elf_file_t ef, GElf_Size symidx);
-static int ef_obj_lookup_set(elf_file_t ef, const char *name,
- GElf_Addr *startp, GElf_Addr *stopp, long *countp);
-static int ef_obj_lookup_symbol(elf_file_t ef, const char *name,
- GElf_Sym **sym);
-
-static struct elf_file_ops ef_obj_file_ops = {
- .close = ef_obj_close,
- .seg_read_rel = ef_obj_seg_read_rel,
- .seg_read_string = ef_obj_seg_read_string,
- .symaddr = ef_obj_symaddr,
- .lookup_set = ef_obj_lookup_set,
-};
-
-static GElf_Off
-ef_obj_get_offset(elf_file_t ef, GElf_Addr addr)
-{
- Elf_progent *pt;
- int i;
-
- for (i = 0; i < ef->nprogtab; i++) {
- pt = &ef->progtab[i];
- if (pt->offset == (GElf_Off)-1)
- continue;
- if (addr >= pt->addr && addr < pt->addr + pt->size)
- return (pt->offset + (addr - pt->addr));
- }
- return (0);
-}
-
-static int
-ef_obj_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym)
-{
- GElf_Sym *symp;
- const char *strp;
- int i;
-
- for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
- strp = ef->ddbstrtab + symp->st_name;
- if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
- *sym = symp;
- return (0);
- }
- }
- return (ENOENT);
-}
-
-static int
-ef_obj_lookup_set(elf_file_t ef, const char *name, GElf_Addr *startp,
- GElf_Addr *stopp, long *countp)
-{
- int i;
-
- for (i = 0; i < ef->nprogtab; i++) {
- if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) &&
- strcmp(ef->progtab[i].name + 4, name) == 0) {
- *startp = ef->progtab[i].addr;
- *stopp = ef->progtab[i].addr + ef->progtab[i].size;
- *countp = (*stopp - *startp) /
- elf_pointer_size(ef->ef_efile);
- return (0);
- }
- }
- return (ESRCH);
-}
-
-static GElf_Addr
-ef_obj_symaddr(elf_file_t ef, GElf_Size symidx)
-{
- const GElf_Sym *sym;
-
- if (symidx >= ef->ddbsymcnt)
- return (0);
- sym = ef->ddbsymtab + symidx;
-
- if (sym->st_shndx != SHN_UNDEF)
- return (sym->st_value);
- return (0);
-}
-
-static int
-ef_obj_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len, void *dest)
-{
- GElf_Off secofs;
- GElf_Rel *r;
- GElf_Rela *a;
- GElf_Addr secbase, dataoff;
- int error, i, sec;
-
- /* Find out which section contains the data. */
- sec = -1;
- for (i = 0; i < ef->nprogtab; i++) {
- if (address < ef->progtab[i].addr)
- continue;
-
- dataoff = address - ef->progtab[i].addr;
- if (dataoff + len > ef->progtab[i].size)
- continue;
-
- sec = ef->progtab[i].sec;
- secbase = ef->progtab[i].addr;
- secofs = ef->progtab[i].offset;
- break;
- }
-
- if (sec == -1) {
- if (ef->ef_verbose)
- warnx("ef_obj_seg_read_rel(%s): bad address (%jx)",
- ef->ef_name, (uintmax_t)address);
- return (EFAULT);
- }
-
- if (secofs == (GElf_Off)-1) {
- memset(dest, 0, len);
- } else {
- error = elf_read_raw_data(ef->ef_efile, secofs + dataoff, dest,
- len);
- if (error != 0)
- return (error);
- }
-
- /* Now do the relocations. */
- for (i = 0; i < ef->nrel; i++) {
- if (ef->reltab[i].sec != sec)
- continue;
- for (r = ef->reltab[i].rel;
- r < &ef->reltab[i].rel[ef->reltab[i].nrel]; r++) {
- error = elf_reloc(ef->ef_efile, r, ELF_T_REL, secbase,
- address, len, dest);
- if (error != 0)
- return (error);
- }
- }
- for (i = 0; i < ef->nrela; i++) {
- if (ef->relatab[i].sec != sec)
- continue;
- for (a = ef->relatab[i].rela;
- a < &ef->relatab[i].rela[ef->relatab[i].nrela]; a++) {
- error = elf_reloc(ef->ef_efile, a, ELF_T_RELA, secbase,
- address, len, dest);
- if (error != 0)
- return (error);
- }
- }
- return (0);
-}
-
-static int
-ef_obj_seg_read_string(elf_file_t ef, GElf_Addr address, size_t len, char *dest)
-{
- GElf_Off ofs;
-
- ofs = ef_obj_get_offset(ef, address);
- if (ofs == 0) {
- if (ef->ef_verbose)
- warnx("ef_obj_seg_read_string(%s): bad address (%jx)",
- ef->ef_name, (uintmax_t)address);
- return (EFAULT);
- }
-
- return (elf_read_raw_string(ef->ef_efile, ofs, dest, len));
-}
-
-int
-ef_obj_open(struct elf_file *efile, int verbose)
-{
- elf_file_t ef;
- GElf_Ehdr *hdr;
- GElf_Shdr *shdr;
- GElf_Sym *es;
- GElf_Addr mapbase;
- size_t i, nshdr;
- int error, pb, ra, rl;
- int j, nsym, symstrindex, symtabindex;
-
- hdr = &efile->ef_hdr;
- if (hdr->e_type != ET_REL || hdr->e_shnum == 0 || hdr->e_shoff == 0 ||
- hdr->e_shentsize != elf_object_size(efile, ELF_T_SHDR))
- return (EFTYPE);
-
- ef = calloc(1, sizeof(*ef));
- if (ef == NULL)
- return (errno);
-
- efile->ef_ef = ef;
- efile->ef_ops = &ef_obj_file_ops;
-
- ef->ef_verbose = verbose;
- ef->ef_name = strdup(efile->ef_filename);
- ef->ef_efile = efile;
-
- error = elf_read_shdrs(efile, &nshdr, &shdr);
- if (error != 0) {
- shdr = NULL;
- goto out;
- }
-
- /* Scan the section headers for information and table sizing. */
- nsym = 0;
- symtabindex = -1;
- symstrindex = -1;
- for (i = 0; i < nshdr; i++) {
- switch (shdr[i].sh_type) {
- case SHT_PROGBITS:
- case SHT_NOBITS:
- ef->nprogtab++;
- break;
- case SHT_SYMTAB:
- nsym++;
- symtabindex = i;
- symstrindex = shdr[i].sh_link;
- break;
- case SHT_REL:
- ef->nrel++;
- break;
- case SHT_RELA:
- ef->nrela++;
- break;
- case SHT_STRTAB:
- break;
- }
- }
-
- if (ef->nprogtab == 0) {
- warnx("%s: file has no contents", ef->ef_name);
- goto out;
- }
- if (nsym != 1) {
- warnx("%s: file has no valid symbol table", ef->ef_name);
- goto out;
- }
- if (symstrindex < 0 || symstrindex > nshdr ||
- shdr[symstrindex].sh_type != SHT_STRTAB) {
- warnx("%s: file has invalid symbol strings", ef->ef_name);
- goto out;
- }
-
- /* Allocate space for tracking the load chunks */
- if (ef->nprogtab != 0)
- ef->progtab = calloc(ef->nprogtab, sizeof(*ef->progtab));
- if (ef->nrel != 0)
- ef->reltab = calloc(ef->nrel, sizeof(*ef->reltab));
- if (ef->nrela != 0)
- ef->relatab = calloc(ef->nrela, sizeof(*ef->relatab));
- if ((ef->nprogtab != 0 && ef->progtab == NULL) ||
- (ef->nrel != 0 && ef->reltab == NULL) ||
- (ef->nrela != 0 && ef->relatab == NULL)) {
- printf("malloc failed\n");
- error = ENOMEM;
- goto out;
- }
-
- if (elf_read_symbols(efile, symtabindex, &ef->ddbsymcnt,
- &ef->ddbsymtab) != 0) {
- printf("elf_read_symbols failed\n");
- goto out;
- }
-
- if (elf_read_string_table(efile, &shdr[symstrindex], &ef->ddbstrcnt,
- &ef->ddbstrtab) != 0) {
- printf("elf_read_string_table failed\n");
- goto out;
- }
-
- /* Do we have a string table for the section names? */
- if (hdr->e_shstrndx != 0 &&
- shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
- if (elf_read_string_table(efile, &shdr[hdr->e_shstrndx],
- &ef->shstrcnt, &ef->shstrtab) != 0) {
- printf("elf_read_string_table failed\n");
- goto out;
- }
- }
-
- /*
- * Now allocate address space for code/data(progbits) and
- * bss(nobits) and allocate space for and load relocs.
- */
- pb = 0;
- rl = 0;
- ra = 0;
- mapbase = 0;
- for (i = 0; i < nshdr; i++) {
- switch (shdr[i].sh_type) {
- case SHT_PROGBITS:
- case SHT_NOBITS:
- mapbase = roundup2(mapbase, shdr[i].sh_addralign);
- ef->progtab[pb].addr = mapbase;
- if (shdr[i].sh_type == SHT_PROGBITS) {
- ef->progtab[pb].name = "<<PROGBITS>>";
- ef->progtab[pb].offset = shdr[i].sh_offset;
- } else {
- ef->progtab[pb].name = "<<NOBITS>>";
- ef->progtab[pb].offset = (GElf_Off)-1;
- }
- ef->progtab[pb].size = shdr[i].sh_size;
- ef->progtab[pb].sec = i;
- if (ef->shstrtab && shdr[i].sh_name != 0)
- ef->progtab[pb].name =
- ef->shstrtab + shdr[i].sh_name;
-
- /* Update all symbol values with the offset. */
- for (j = 0; j < ef->ddbsymcnt; j++) {
- es = &ef->ddbsymtab[j];
- if (es->st_shndx != i)
- continue;
- es->st_value += ef->progtab[pb].addr;
- }
- mapbase += shdr[i].sh_size;
- pb++;
- break;
- case SHT_REL:
- ef->reltab[rl].sec = shdr[i].sh_info;
- if (elf_read_rel(efile, i, &ef->reltab[rl].nrel,
- &ef->reltab[rl].rel) != 0) {
- printf("elf_read_rel failed\n");
- goto out;
- }
- rl++;
- break;
- case SHT_RELA:
- ef->relatab[ra].sec = shdr[i].sh_info;
- if (elf_read_rela(efile, i, &ef->relatab[ra].nrela,
- &ef->relatab[ra].rela) != 0) {
- printf("elf_read_rela failed\n");
- goto out;
- }
- ra++;
- break;
- }
- }
- error = 0;
-out:
- free(shdr);
- if (error != 0)
- ef_obj_close(ef);
- return (error);
-}
-
-static void
-ef_obj_close(elf_file_t ef)
-{
- int i;
-
- if (ef->ef_name)
- free(ef->ef_name);
- if (ef->nprogtab != 0)
- free(ef->progtab);
- if (ef->nrel != 0) {
- for (i = 0; i < ef->nrel; i++)
- if (ef->reltab[i].rel != NULL)
- free(ef->reltab[i].rel);
- free(ef->reltab);
- }
- if (ef->nrela != 0) {
- for (i = 0; i < ef->nrela; i++)
- if (ef->relatab[i].rela != NULL)
- free(ef->relatab[i].rela);
- free(ef->relatab);
- }
- if (ef->ddbsymtab != NULL)
- free(ef->ddbsymtab);
- if (ef->ddbstrtab != NULL)
- free(ef->ddbstrtab);
- if (ef->shstrtab != NULL)
- free(ef->shstrtab);
- ef->ef_efile->ef_ops = NULL;
- ef->ef_efile->ef_ef = NULL;
- free(ef);
-}
diff --git a/usr.sbin/kldxref/ef_powerpc.c b/usr.sbin/kldxref/ef_powerpc.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_powerpc.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2005 Peter Grehan.
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_ppc_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- switch (rtype) {
- case R_PPC_RELATIVE: /* word32|doubleword64 B + A */
- addr = relbase + addend;
- if (elf_class(ef) == ELFCLASS64) {
- if (elf_encoding(ef) == ELFDATA2LSB)
- le64enc(where, addr);
- else
- be64enc(where, addr);
- } else
- be32enc(where, addr);
- break;
- case R_PPC_ADDR32: /* word32 S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- be32enc(where, addr);
- break;
- case R_PPC64_ADDR64: /* doubleword64 S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- if (elf_encoding(ef) == ELFDATA2LSB)
- le64enc(where, addr);
- else
- be64enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS32, ELFDATA2MSB, EM_PPC, ef_ppc_reloc);
-ELF_RELOC(ELFCLASS64, ELFDATA2LSB, EM_PPC64, ef_ppc_reloc);
-ELF_RELOC(ELFCLASS64, ELFDATA2MSB, EM_PPC64, ef_ppc_reloc);
diff --git a/usr.sbin/kldxref/ef_riscv.c b/usr.sbin/kldxref/ef_riscv.c
deleted file mode 100644
--- a/usr.sbin/kldxref/ef_riscv.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2018 John Baldwin <jhb@FreeBSD.org>
- *
- * This software was developed by SRI International and the University of
- * Cambridge Computer Laboratory (Department of Computer Science and
- * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
- * DARPA SSITH research programme.
- *
- * 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 AUTHOR 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 AUTHOR 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/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <gelf.h>
-
-#include "ef.h"
-
-/*
- * Apply relocations to the values obtained from the file. `relbase' is the
- * target relocation address of the section, and `dataoff/len' is the region
- * that is to be relocated, and has been copied to *dest
- */
-static int
-ef_riscv_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- char *where;
- GElf_Addr addr, addend;
- GElf_Size rtype, symidx;
- const GElf_Rela *rela;
-
- switch (reltype) {
- case ELF_T_RELA:
- rela = (const GElf_Rela *)reldata;
- where = (char *)dest + (relbase + rela->r_offset - dataoff);
- addend = rela->r_addend;
- rtype = GELF_R_TYPE(rela->r_info);
- symidx = GELF_R_SYM(rela->r_info);
- break;
- default:
- return (EINVAL);
- }
-
- if (where < (char *)dest || where >= (char *)dest + len)
- return (0);
-
- switch (rtype) {
- case R_RISCV_64: /* S + A */
- addr = EF_SYMADDR(ef, symidx) + addend;
- le64enc(where, addr);
- break;
- case R_RISCV_RELATIVE: /* B + A */
- addr = relbase + addend;
- le64enc(where, addr);
- break;
- default:
- warnx("unhandled relocation type %d", (int)rtype);
- }
- return (0);
-}
-
-ELF_RELOC(ELFCLASS64, ELFDATA2LSB, EM_RISCV, ef_riscv_reloc);
diff --git a/usr.sbin/kldxref/elf.c b/usr.sbin/kldxref/elf.c
deleted file mode 100644
--- a/usr.sbin/kldxref/elf.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2021-2023 John Baldwin <jhb@FreeBSD.org>
- *
- * This software was developed by SRI International and the University
- * of Cambridge Computer Laboratory (Department of Computer Science
- * and Technology) under Defense Advanced Research Projects Agency
- * (DARPA) contract HR0011-18-C-0016 ("ECATS"), as part of the DARPA
- * SSITH research programme and under DARPA Contract No. HR001123C0031
- * ("MTSS").
- *
- * 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 AUTHOR 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 AUTHOR 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/param.h>
-#include <sys/endian.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <gelf.h>
-#include <libelf.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "ef.h"
-
-SET_DECLARE(elf_reloc, struct elf_reloc_data);
-
-static elf_reloc_t *
-elf_find_reloc(const GElf_Ehdr *hdr)
-{
- struct elf_reloc_data **erd;
-
- SET_FOREACH(erd, elf_reloc) {
- if (hdr->e_ident[EI_CLASS] == (*erd)->class &&
- hdr->e_ident[EI_DATA] == (*erd)->data &&
- hdr->e_machine == (*erd)->machine)
- return ((*erd)->reloc);
- }
- return (NULL);
-}
-
-int
-elf_open_file(struct elf_file *efile, const char *filename, int verbose)
-{
- int error;
-
- memset(efile, 0, sizeof(*efile));
- efile->ef_filename = filename;
- efile->ef_fd = open(filename, O_RDONLY);
- if (efile->ef_fd == -1) {
- if (verbose)
- warn("open(%s)", filename);
- return (errno);
- }
-
- efile->ef_elf = elf_begin(efile->ef_fd, ELF_C_READ, NULL);
- if (efile->ef_elf == NULL) {
- if (verbose)
- warnx("elf_begin(%s): %s", filename, elf_errmsg(0));
- elf_close_file(efile);
- return (EINVAL);
- }
-
- if (elf_kind(efile->ef_elf) != ELF_K_ELF) {
- if (verbose)
- warnx("%s: not an ELF file", filename);
- elf_close_file(efile);
- return (EINVAL);
- }
-
- if (gelf_getehdr(efile->ef_elf, &efile->ef_hdr) == NULL) {
- if (verbose)
- warnx("gelf_getehdr(%s): %s", filename, elf_errmsg(0));
- elf_close_file(efile);
- return (EINVAL);
- }
-
- efile->ef_reloc = elf_find_reloc(&efile->ef_hdr);
- if (efile->ef_reloc == NULL) {
- if (verbose)
- warnx("%s: unsupported architecture", filename);
- elf_close_file(efile);
- return (EFTYPE);
- }
-
- error = ef_open(efile, verbose);
- if (error != 0) {
- error = ef_obj_open(efile, verbose);
- if (error != 0) {
- if (verbose)
- warnc(error, "%s: not a valid DSO or object file",
- filename);
- elf_close_file(efile);
- return (error);
- }
- }
-
- efile->ef_pointer_size = elf_object_size(efile, ELF_T_ADDR);
-
- return (0);
-}
-
-void
-elf_close_file(struct elf_file *efile)
-{
- if (efile->ef_ops != NULL) {
- EF_CLOSE(efile);
- }
- if (efile->ef_elf != NULL) {
- elf_end(efile->ef_elf);
- efile->ef_elf = NULL;
- }
- if (efile->ef_fd > 0) {
- close(efile->ef_fd);
- efile->ef_fd = -1;
- }
-}
-
-bool
-elf_compatible(struct elf_file *efile, const GElf_Ehdr *hdr)
-{
- if (efile->ef_hdr.e_ident[EI_CLASS] != hdr->e_ident[EI_CLASS] ||
- efile->ef_hdr.e_ident[EI_DATA] != hdr->e_ident[EI_DATA] ||
- efile->ef_hdr.e_machine != hdr->e_machine)
- return (false);
- return (true);
-}
-
-size_t
-elf_object_size(struct elf_file *efile, Elf_Type type)
-{
- return (gelf_fsize(efile->ef_elf, type, 1, efile->ef_hdr.e_version));
-}
-
-/*
- * The number of objects of 'type' in region of the file of size
- * 'file_size'.
- */
-static size_t
-elf_object_count(struct elf_file *efile, Elf_Type type, size_t file_size)
-{
- return (file_size / elf_object_size(efile, type));
-}
-
-int
-elf_read_raw_data(struct elf_file *efile, off_t offset, void *dst, size_t len)
-{
- ssize_t nread;
-
- nread = pread(efile->ef_fd, dst, len, offset);
- if (nread == -1)
- return (errno);
- if (nread != len)
- return (EIO);
- return (0);
-}
-
-int
-elf_read_raw_data_alloc(struct elf_file *efile, off_t offset, size_t len,
- void **out)
-{
- void *buf;
- int error;
-
- buf = malloc(len);
- if (buf == NULL)
- return (ENOMEM);
- error = elf_read_raw_data(efile, offset, buf, len);
- if (error != 0) {
- free(buf);
- return (error);
- }
- *out = buf;
- return (0);
-}
-
-int
-elf_read_raw_string(struct elf_file *efile, off_t offset, char *dst, size_t len)
-{
- ssize_t nread;
-
- nread = pread(efile->ef_fd, dst, len, offset);
- if (nread == -1)
- return (errno);
- if (nread == 0)
- return (EIO);
-
- /* A short read is ok so long as the data contains a terminator. */
- if (strnlen(dst, nread) == nread)
- return (EFAULT);
-
- return (0);
-}
-
-int
-elf_read_data(struct elf_file *efile, Elf_Type type, off_t offset, size_t len,
- void **out)
-{
- Elf_Data dst, src;
- void *buf;
- int error;
-
- buf = malloc(len);
- if (buf == NULL)
- return (ENOMEM);
-
- error = elf_read_raw_data(efile, offset, buf, len);
- if (error != 0) {
- free(buf);
- return (error);
- }
-
- memset(&dst, 0, sizeof(dst));
- memset(&src, 0, sizeof(src));
-
- src.d_buf = buf;
- src.d_size = len;
- src.d_type = type;
- src.d_version = efile->ef_hdr.e_version;
-
- dst.d_buf = buf;
- dst.d_size = len;
- dst.d_version = EV_CURRENT;
-
- if (gelf_xlatetom(efile->ef_elf, &dst, &src, elf_encoding(efile)) ==
- NULL) {
- free(buf);
- return (ENXIO);
- }
-
- if (dst.d_size != len)
- warnx("elf_read_data: translation of type %u size mismatch",
- type);
-
- *out = buf;
- return (0);
-}
-
-int
-elf_read_relocated_data(struct elf_file *efile, GElf_Addr address, size_t len,
- void **buf)
-{
- int error;
- void *p;
-
- p = malloc(len);
- if (p == NULL)
- return (ENOMEM);
- error = EF_SEG_READ_REL(efile, address, len, p);
- if (error != 0) {
- free(p);
- return (error);
- }
- *buf = p;
- return (0);
-}
-
-int
-elf_read_phdrs(struct elf_file *efile, size_t *nphdrp, GElf_Phdr **phdrp)
-{
- GElf_Phdr *phdr;
- size_t nphdr, i;
- int error;
-
- if (elf_getphdrnum(efile->ef_elf, &nphdr) == -1)
- return (EFTYPE);
-
- phdr = calloc(nphdr, sizeof(*phdr));
- if (phdr == NULL)
- return (ENOMEM);
-
- for (i = 0; i < nphdr; i++) {
- if (gelf_getphdr(efile->ef_elf, i, &phdr[i]) == NULL) {
- error = EFTYPE;
- goto out;
- }
- }
-
- *nphdrp = nphdr;
- *phdrp = phdr;
- return (0);
-out:
- free(phdr);
- return (error);
-}
-
-int
-elf_read_shdrs(struct elf_file *efile, size_t *nshdrp, GElf_Shdr **shdrp)
-{
- GElf_Shdr *shdr;
- Elf_Scn *scn;
- size_t nshdr, i;
- int error;
-
- if (elf_getshdrnum(efile->ef_elf, &nshdr) == -1)
- return (EFTYPE);
-
- shdr = calloc(nshdr, sizeof(*shdr));
- if (shdr == NULL)
- return (ENOMEM);
-
- for (i = 0; i < nshdr; i++) {
- scn = elf_getscn(efile->ef_elf, i);
- if (scn == NULL) {
- error = EFTYPE;
- goto out;
- }
- if (gelf_getshdr(scn, &shdr[i]) == NULL) {
- error = EFTYPE;
- goto out;
- }
- }
-
- *nshdrp = nshdr;
- *shdrp = shdr;
- return (0);
-out:
- free(shdr);
- return (error);
-}
-
-int
-elf_read_dynamic(struct elf_file *efile, int section_index, size_t *ndynp,
- GElf_Dyn **dynp)
-{
- GElf_Shdr shdr;
- Elf_Scn *scn;
- Elf_Data *data;
- GElf_Dyn *dyn;
- long i, ndyn;
-
- scn = elf_getscn(efile->ef_elf, section_index);
- if (scn == NULL)
- return (EINVAL);
- if (gelf_getshdr(scn, &shdr) == NULL)
- return (EINVAL);
- data = elf_getdata(scn, NULL);
- if (data == NULL)
- return (EINVAL);
-
- ndyn = elf_object_count(efile, ELF_T_DYN, shdr.sh_size);
- dyn = calloc(ndyn, sizeof(*dyn));
- if (dyn == NULL)
- return (ENOMEM);
-
- for (i = 0; i < ndyn; i++) {
- if (gelf_getdyn(data, i, &dyn[i]) == NULL) {
- free(dyn);
- return (EINVAL);
- }
- }
-
- *ndynp = ndyn;
- *dynp = dyn;
- return (0);
-}
-
-int
-elf_read_symbols(struct elf_file *efile, int section_index, size_t *nsymp,
- GElf_Sym **symp)
-{
- GElf_Shdr shdr;
- Elf_Scn *scn;
- Elf_Data *data;
- GElf_Sym *sym;
- size_t i, nsym;
-
- scn = elf_getscn(efile->ef_elf, section_index);
- if (scn == NULL)
- return (EINVAL);
- if (gelf_getshdr(scn, &shdr) == NULL)
- return (EINVAL);
- data = elf_getdata(scn, NULL);
- if (data == NULL)
- return (EINVAL);
-
- nsym = elf_object_count(efile, ELF_T_SYM, shdr.sh_size);
- sym = calloc(nsym, sizeof(*sym));
- if (sym == NULL)
- return (ENOMEM);
-
- for (i = 0; i < nsym; i++) {
- if (gelf_getsym(data, i, &sym[i]) == NULL) {
- free(sym);
- return (EINVAL);
- }
- }
-
- *nsymp = nsym;
- *symp = sym;
- return (0);
-}
-
-int
-elf_read_string_table(struct elf_file *efile, const GElf_Shdr *shdr,
- long *strcnt, char **strtab)
-{
- int error;
-
- if (shdr->sh_type != SHT_STRTAB)
- return (EINVAL);
- error = elf_read_raw_data_alloc(efile, shdr->sh_offset, shdr->sh_size,
- (void **)strtab);
- if (error != 0)
- return (error);
- *strcnt = shdr->sh_size;
- return (0);
-}
-
-int
-elf_read_rel(struct elf_file *efile, int section_index, long *nrelp,
- GElf_Rel **relp)
-{
- GElf_Shdr shdr;
- Elf_Scn *scn;
- Elf_Data *data;
- GElf_Rel *rel;
- long i, nrel;
-
- scn = elf_getscn(efile->ef_elf, section_index);
- if (scn == NULL)
- return (EINVAL);
- if (gelf_getshdr(scn, &shdr) == NULL)
- return (EINVAL);
- data = elf_getdata(scn, NULL);
- if (data == NULL)
- return (EINVAL);
-
- nrel = elf_object_count(efile, ELF_T_REL, shdr.sh_size);
- rel = calloc(nrel, sizeof(*rel));
- if (rel == NULL)
- return (ENOMEM);
-
- for (i = 0; i < nrel; i++) {
- if (gelf_getrel(data, i, &rel[i]) == NULL) {
- free(rel);
- return (EINVAL);
- }
- }
-
- *nrelp = nrel;
- *relp = rel;
- return (0);
-}
-
-int
-elf_read_rela(struct elf_file *efile, int section_index, long *nrelap,
- GElf_Rela **relap)
-{
- GElf_Shdr shdr;
- Elf_Scn *scn;
- Elf_Data *data;
- GElf_Rela *rela;
- long i, nrela;
-
- scn = elf_getscn(efile->ef_elf, section_index);
- if (scn == NULL)
- return (EINVAL);
- if (gelf_getshdr(scn, &shdr) == NULL)
- return (EINVAL);
- data = elf_getdata(scn, NULL);
- if (data == NULL)
- return (EINVAL);
-
- nrela = elf_object_count(efile, ELF_T_RELA, shdr.sh_size);
- rela = calloc(nrela, sizeof(*rela));
- if (rela == NULL)
- return (ENOMEM);
-
- for (i = 0; i < nrela; i++) {
- if (gelf_getrela(data, i, &rela[i]) == NULL) {
- free(rela);
- return (EINVAL);
- }
- }
-
- *nrelap = nrela;
- *relap = rela;
- return (0);
-}
-
-size_t
-elf_pointer_size(struct elf_file *efile)
-{
- return (efile->ef_pointer_size);
-}
-
-int
-elf_int(struct elf_file *efile, const void *p)
-{
- if (elf_encoding(efile) == ELFDATA2LSB)
- return (le32dec(p));
- else
- return (be32dec(p));
-}
-
-GElf_Addr
-elf_address_from_pointer(struct elf_file *efile, const void *p)
-{
- switch (elf_class(efile)) {
- case ELFCLASS32:
- if (elf_encoding(efile) == ELFDATA2LSB)
- return (le32dec(p));
- else
- return (be32dec(p));
- case ELFCLASS64:
- if (elf_encoding(efile) == ELFDATA2LSB)
- return (le64dec(p));
- else
- return (be64dec(p));
- default:
- __unreachable();
- }
-}
-
-int
-elf_read_string(struct elf_file *efile, GElf_Addr address, void *dst,
- size_t len)
-{
- return (EF_SEG_READ_STRING(efile, address, len, dst));
-}
-
-int
-elf_read_linker_set(struct elf_file *efile, const char *name, GElf_Addr **bufp,
- long *countp)
-{
- GElf_Addr *buf, start, stop;
- char *p;
- void *raw;
- long i, count;
- int error;
-
- error = EF_LOOKUP_SET(efile, name, &start, &stop, &count);
- if (error != 0)
- return (error);
-
- error = elf_read_relocated_data(efile, start,
- count * elf_pointer_size(efile), &raw);
- if (error != 0)
- return (error);
-
- buf = calloc(count, sizeof(*buf));
- if (buf == NULL) {
- free(raw);
- return (ENOMEM);
- }
-
- p = raw;
- for (i = 0; i < count; i++) {
- buf[i] = elf_address_from_pointer(efile, p);
- p += elf_pointer_size(efile);
- }
- free(raw);
-
- *bufp = buf;
- *countp = count;
- return (0);
-}
-
-int
-elf_read_mod_depend(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_depend *mdp)
-{
- int *p;
- int error;
-
- error = elf_read_relocated_data(efile, addr, sizeof(int) * 3,
- (void **)&p);
- if (error != 0)
- return (error);
-
- memset(mdp, 0, sizeof(*mdp));
- mdp->md_ver_minimum = elf_int(efile, p);
- mdp->md_ver_preferred = elf_int(efile, p + 1);
- mdp->md_ver_maximum = elf_int(efile, p + 2);
- free(p);
- return (0);
-}
-
-int
-elf_read_mod_version(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_version *mdv)
-{
- int error, value;
-
- error = EF_SEG_READ_REL(efile, addr, sizeof(int), &value);
- if (error != 0)
- return (error);
-
- memset(mdv, 0, sizeof(*mdv));
- mdv->mv_version = elf_int(efile, &value);
- return (0);
-}
-
-int
-elf_read_mod_metadata(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_metadata *md)
-{
- char *p;
- size_t len, offset, pointer_size;
- int error;
-
- pointer_size = elf_pointer_size(efile);
- len = 2 * sizeof(int);
- len = roundup(len, pointer_size);
- len += 2 * pointer_size;
-
- error = elf_read_relocated_data(efile, addr, len, (void **)&p);
- if (error != 0)
- return (error);
-
- memset(md, 0, sizeof(*md));
- offset = 0;
- md->md_version = elf_int(efile, p + offset);
- offset += sizeof(int);
- md->md_type = elf_int(efile, p + offset);
- offset += sizeof(int);
- offset = roundup(offset, pointer_size);
- md->md_data = elf_address_from_pointer(efile, p + offset);
- offset += pointer_size;
- md->md_cval = elf_address_from_pointer(efile, p + offset);
- free(p);
- return (0);
-}
-
-int
-elf_read_mod_pnp_match_info(struct elf_file *efile, GElf_Addr addr,
- struct Gmod_pnp_match_info *pnp)
-{
- char *p;
- size_t len, offset, pointer_size;
- int error;
-
- pointer_size = elf_pointer_size(efile);
- len = 3 * pointer_size;
- len = roundup(len, pointer_size);
- len += 2 * sizeof(int);
-
- error = elf_read_relocated_data(efile, addr, len, (void **)&p);
- if (error != 0)
- return (error);
-
- memset(pnp, 0, sizeof(*pnp));
- offset = 0;
- pnp->descr = elf_address_from_pointer(efile, p + offset);
- offset += pointer_size;
- pnp->bus = elf_address_from_pointer(efile, p + offset);
- offset += pointer_size;
- pnp->table = elf_address_from_pointer(efile, p + offset);
- offset += pointer_size;
- offset = roundup(offset, pointer_size);
- pnp->entry_len = elf_int(efile, p + offset);
- offset += sizeof(int);
- pnp->num_entry = elf_int(efile, p + offset);
- free(p);
- return (0);
-}
-
-int
-elf_reloc(struct elf_file *efile, const void *reldata, Elf_Type reltype,
- GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest)
-{
- return (efile->ef_reloc(efile, reldata, reltype, relbase, dataoff, len,
- dest));
-}
diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c
--- a/usr.sbin/kldxref/kldxref.c
+++ b/usr.sbin/kldxref/kldxref.c
@@ -51,7 +51,7 @@
#include <string.h>
#include <unistd.h>
-#include "ef.h"
+#include <kldelf.h>
#define MAXRECSIZE (64 << 10) /* 64k */
#define check(val) if ((error = (val)) != 0) break

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 12:28 AM (8 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12443456
Default Alt Text
D46720.id143546.diff (78 KB)

Event Timeline