libkldelf: add a private library for kernel/kld-related ELF parsing

The libkldelf library was originally a part of kldxref(8). It exposed
ELF parsing helpers specialized in parsing KLDs and the kernel
executable. The library can be used to read metadata such as linker_set,
mod_depend, mod_version and PNP match info, and raw data from the ELF.

To promote the reuse of the facilities the ELF parsing code is separated
from kldxref(8) into a new private library.

For now, libkldelf's source files will be compiled into kldxref(8)
directly if kldxref is built during bootstrapping phase. The reason is
linking kldxref(8) against the libkldelf static library has an unwanted
side effect which renders the linker sets inside the libkldelf
implementation empty if the static library is not build by ld -r all the
.o files into a single .o before producing the static library.

Sponsored by:	Juniper Networks, Inc.
Reviewed by:	markj
Suggested by:	jrtc27, markj
Differential Revision:	https://reviews.freebsd.org/D46719
This commit is contained in:
Ka Ho Ng 2024-10-08 04:24:07 +00:00
parent 366d6a424e
commit 968bcca262
18 changed files with 86 additions and 24 deletions

View File

@ -2527,8 +2527,12 @@ ${_bt}-lib/libdwarf: ${_bt_m4_depend}
_bt_libelf_depend=${_bt}-lib/libelf
.endif
_libkldelf= lib/libkldelf
${_bt}-lib/libkldelf: ${_bt_libelf_depend}
_bt_libkldelf_depend=${_bt}-lib/libkldelf
_kldxref= usr.sbin/kldxref
${_bt}-usr.sbin/kldxref: ${_bt_libelf_depend}
${_bt}-usr.sbin/kldxref: ${_bt_libelf_depend} ${_bt_libkldelf_depend}
# flua is required to regenerate syscall files. It first appeared during the
# 13.0-CURRENT cycle, thus needs to be built on -older releases and stable
@ -2791,6 +2795,7 @@ bootstrap-tools: ${_bt}-links .PHONY
${_cat} \
${_kbdcontrol} \
${_elftoolchain_libs} \
${_libkldelf} \
${_kldxref} \
lib/libopenbsd \
usr.bin/mandoc \
@ -3234,7 +3239,8 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
lib/libfigpar \
${_lib_libgssapi} \
lib/libjail \
lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \
lib/libkiconv lib/libkldelf lib/libkvm \
lib/liblzma lib/libmd lib/libnv \
lib/libzstd \
${_lib_casper} \
lib/ncurses/tinfo \
@ -3269,6 +3275,7 @@ _prebuild_libs+= lib/libregex
.endif
lib/libgeom__L: lib/libexpat__L lib/libsbuf__L
lib/libkldelf__L: lib/libelf__L
lib/libkvm__L: lib/libelf__L
.if ${MK_RADIUS_SUPPORT} != "no"

View File

@ -66,6 +66,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libiscsiutil \
libjail \
libkiconv \
libkldelf \
libkvm \
liblua \
liblzma \

21
lib/libkldelf/Makefile Normal file
View File

@ -0,0 +1,21 @@
.include <bsd.own.mk>
PACKAGE= runtime
LIB= kldelf
PRIVATELIB= yes
SRCS= ef.c \
ef_obj.c \
elf.c \
ef_aarch64.c \
ef_arm.c \
ef_amd64.c \
ef_i386.c \
ef_mips.c \
ef_powerpc.c \
ef_riscv.c
WARNS?= 2
LIBADD= elf
.include <bsd.lib.mk>

View File

@ -0,0 +1,16 @@
# Autogenerated - do NOT edit!
DIRDEPS = \
include \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
lib/libelf \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -41,7 +41,7 @@
#include <stdlib.h>
#include <string.h>
#include "ef.h"
#include "kldelf.h"
#define MAXSEGS 16
struct ef_file {

View File

@ -31,7 +31,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -33,7 +33,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -34,7 +34,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -33,7 +33,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -36,7 +36,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -43,7 +43,7 @@
#include <stdlib.h>
#include <string.h>
#include "ef.h"
#include "kldelf.h"
typedef struct {
GElf_Addr addr;

View File

@ -33,7 +33,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -36,7 +36,7 @@
#include <errno.h>
#include <gelf.h>
#include "ef.h"
#include "kldelf.h"
/*
* Apply relocations to the values obtained from the file. `relbase' is the

View File

@ -44,7 +44,7 @@
#include <string.h>
#include <unistd.h>
#include "ef.h"
#include "kldelf.h"
SET_DECLARE(elf_reloc, struct elf_reloc_data);

View File

@ -32,8 +32,8 @@
* SUCH DAMAGE.
*/
#ifndef _EF_H_
#define _EF_H_
#ifndef _KLDELF_H_
#define _KLDELF_H_
#include <sys/linker_set.h>
#include <stdbool.h>
@ -312,4 +312,4 @@ int elf_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
__END_DECLS
#endif /* _EF_H_*/
#endif /* _KLDELF_H_*/

View File

@ -27,6 +27,7 @@ _PRIVATELIBS= \
gtest_main \
heimipcc \
heimipcs \
kldelf \
ldns \
sqlite3 \
ssh \
@ -312,6 +313,7 @@ _DP_bsnmp= crypto
.endif
_DP_geom= bsdxml sbuf
_DP_cam= sbuf
_DP_kldelf= elf
_DP_kvm= elf
_DP_casper= nv
_DP_cap_dns= nv

View File

@ -1,17 +1,32 @@
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
.if defined(BOOTSTRAPPING)
#
# XXX: Fix libprivatelibkldelf.a linker set issue before removing this block
#
.PATH: ${SRCTOP}/lib/libkldelf
KLDELF_SRCS= ef.c \
ef_obj.c \
elf.c \
ef_aarch64.c \
ef_arm.c \
ef_amd64.c \
ef_i386.c \
ef_mips.c \
ef_powerpc.c \
ef_riscv.c
SRCS+= ${KLDELF_SRCS}
.else
LIBADD+= kldelf
.endif
.include <bsd.prog.mk>

View File

@ -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