diff --git a/Makefile.inc1 b/Makefile.inc1 index 8cfe1cc85cb0..1665e221dc03 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2533,8 +2533,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 @@ -2797,6 +2801,7 @@ bootstrap-tools: ${_bt}-links .PHONY ${_cat} \ ${_kbdcontrol} \ ${_elftoolchain_libs} \ + ${_libkldelf} \ ${_kldxref} \ lib/libopenbsd \ usr.bin/mandoc \ @@ -3237,7 +3242,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 \ @@ -3272,6 +3278,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" diff --git a/lib/Makefile b/lib/Makefile index 5213b955d9ce..7a11425a017d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -66,6 +66,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ libiscsiutil \ libjail \ libkiconv \ + libkldelf \ libkvm \ liblattzfs \ liblua \ diff --git a/lib/libc/csu/aarch64/Makefile.inc b/lib/libc/csu/aarch64/Makefile.inc index b3420a638164..6c315c5e2624 100644 --- a/lib/libc/csu/aarch64/Makefile.inc +++ b/lib/libc/csu/aarch64/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_RELA \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/aarch64/reloc.c b/lib/libc/csu/aarch64/reloc.c index ead48a8ad4fb..4ba7920bcb07 100644 --- a/lib/libc/csu/aarch64/reloc.c +++ b/lib/libc/csu/aarch64/reloc.c @@ -24,6 +24,13 @@ * SUCH DAMAGE. */ +#include + +static void +ifunc_init(const Elf_Auxinfo *aux __unused) +{ +} + static void crt1_handle_rela(const Elf_Rela *r) { diff --git a/lib/libc/csu/amd64/Makefile.inc b/lib/libc/csu/amd64/Makefile.inc index 252f374a026a..d5fb7328284c 100644 --- a/lib/libc/csu/amd64/Makefile.inc +++ b/lib/libc/csu/amd64/Makefile.inc @@ -1,6 +1,10 @@ # +<<<<<<< HEAD CFLAGS+= -DCRT_IRELOC_RELA \ -DINIT_IRELOCS="init_cpu_features()" MK_LTOLIB= no +======= +CFLAGS+= -DCRT_IRELOC_RELA +>>>>>>> internal/freebsd/current/main diff --git a/lib/libc/csu/amd64/reloc.c b/lib/libc/csu/amd64/reloc.c index 6424d69fbd5c..f1f83db9a391 100644 --- a/lib/libc/csu/amd64/reloc.c +++ b/lib/libc/csu/amd64/reloc.c @@ -23,6 +23,8 @@ * SUCH DAMAGE. */ +#include + #include #include @@ -30,7 +32,7 @@ static uint32_t cpu_feature, cpu_feature2; static uint32_t cpu_stdext_feature, cpu_stdext_feature2; static void -init_cpu_features(void) +ifunc_init(const Elf_Auxinfo *aux __unused) { u_int p[4]; diff --git a/lib/libc/csu/arm/Makefile.inc b/lib/libc/csu/arm/Makefile.inc index 2534e6579f38..ddead75f874d 100644 --- a/lib/libc/csu/arm/Makefile.inc +++ b/lib/libc/csu/arm/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/csu/i386/Makefile.inc b/lib/libc/csu/i386/Makefile.inc index f3f8c2b176ce..32018000e1f2 100644 --- a/lib/libc/csu/i386/Makefile.inc +++ b/lib/libc/csu/i386/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_REL \ - -DINIT_IRELOCS="init_cpu_features()" +CFLAGS+= -DCRT_IRELOC_REL diff --git a/lib/libc/csu/i386/reloc.c b/lib/libc/csu/i386/reloc.c index 1c9ec173facc..7097f58d8f26 100644 --- a/lib/libc/csu/i386/reloc.c +++ b/lib/libc/csu/i386/reloc.c @@ -23,6 +23,8 @@ * SUCH DAMAGE. */ +#include + #include #include @@ -30,7 +32,7 @@ static uint32_t cpu_feature, cpu_feature2; static uint32_t cpu_stdext_feature, cpu_stdext_feature2; static void -init_cpu_features(void) +ifunc_init(const Elf_Auxinfo *aux __unused) { u_int cpuid_supported, p[4]; diff --git a/lib/libc/csu/libc_start1.c b/lib/libc/csu/libc_start1.c index f0e708e405ce..045ea1e68141 100644 --- a/lib/libc/csu/libc_start1.c +++ b/lib/libc/csu/libc_start1.c @@ -137,6 +137,24 @@ handle_argv(int argc, char *argv[], char **env) } } +static void +handle_irelocs(char *env[]) +{ +#ifndef CRT_IRELOC_SUPPRESS + const Elf_Auxinfo *aux; + + /* Find the auxiliary vector on the stack. */ + while (*env++ != 0) /* Skip over environment, and NULL terminator */ + ; + aux = (const Elf_Auxinfo *)env; + + ifunc_init(aux); + process_irelocs(); +#else + (void)env; +#endif +} + void __libc_start1(int argc, char *argv[], char *env[], void (*cleanup)(void), int (*mainX)(int, char *[], char *[])) @@ -146,10 +164,7 @@ __libc_start1(int argc, char *argv[], char *env[], void (*cleanup)(void), if (&_DYNAMIC != NULL) { atexit(cleanup); } else { -#ifndef CRT_IRELOC_SUPPRESS - INIT_IRELOCS; - process_irelocs(); -#endif + handle_irelocs(env); _init_tls(); } @@ -171,10 +186,7 @@ __libc_start1_gcrt(int argc, char *argv[], char *env[], if (&_DYNAMIC != NULL) { atexit(cleanup); } else { -#ifndef CRT_IRELOC_SUPPRESS - INIT_IRELOCS; - process_irelocs(); -#endif + handle_irelocs(env); _init_tls(); } diff --git a/lib/libc/csu/powerpc/Makefile.inc b/lib/libc/csu/powerpc/Makefile.inc index 2534e6579f38..ddead75f874d 100644 --- a/lib/libc/csu/powerpc/Makefile.inc +++ b/lib/libc/csu/powerpc/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/csu/powerpc64/Makefile.inc b/lib/libc/csu/powerpc64/Makefile.inc index 5d59d40eb393..6c315c5e2624 100644 --- a/lib/libc/csu/powerpc64/Makefile.inc +++ b/lib/libc/csu/powerpc64/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_RELA \ - -DINIT_IRELOCS="init_cpu_features(env)" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/powerpc64/reloc.c b/lib/libc/csu/powerpc64/reloc.c index 41419bf0e6c2..5637e6534197 100644 --- a/lib/libc/csu/powerpc64/reloc.c +++ b/lib/libc/csu/powerpc64/reloc.c @@ -24,15 +24,8 @@ static uint32_t cpu_features; static uint32_t cpu_features2; static void -init_cpu_features(char **env) +ifunc_init(const Elf_Auxinfo *aux) { - const Elf_Auxinfo *aux; - - /* Find the auxiliary vector on the stack. */ - while (*env++ != 0) /* Skip over environment, and NULL terminator */ - ; - aux = (const Elf_Auxinfo *)env; - /* Digest the auxiliary vector. */ for (; aux->a_type != AT_NULL; aux++) { switch (aux->a_type) { diff --git a/lib/libc/csu/powerpcspe/Makefile.inc b/lib/libc/csu/powerpcspe/Makefile.inc index 2534e6579f38..ddead75f874d 100644 --- a/lib/libc/csu/powerpcspe/Makefile.inc +++ b/lib/libc/csu/powerpcspe/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/csu/riscv/Makefile.inc b/lib/libc/csu/riscv/Makefile.inc index 2534e6579f38..6c315c5e2624 100644 --- a/lib/libc/csu/riscv/Makefile.inc +++ b/lib/libc/csu/riscv/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/riscv/reloc.c b/lib/libc/csu/riscv/reloc.c new file mode 100644 index 000000000000..6ae85085089b --- /dev/null +++ b/lib/libc/csu/riscv/reloc.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * Copyright (c) 2024 Jessica Clarke + * + * 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. + * + * 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. + */ + +static unsigned long elf_hwcap; + +static void +ifunc_init(const Elf_Auxinfo *aux) +{ + /* Digest the auxiliary vector. */ + for (; aux->a_type != AT_NULL; aux++) { + switch (aux->a_type) { + case AT_HWCAP: + elf_hwcap = (uint32_t)aux->a_un.a_val; + break; + } + } +} + +static void +crt1_handle_rela(const Elf_Rela *r) +{ + typedef Elf_Addr (*ifunc_resolver_t)( + unsigned long, unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long, unsigned long); + Elf_Addr *ptr, *where, target; + + switch (ELF_R_TYPE(r->r_info)) { + case R_RISCV_IRELATIVE: + ptr = (Elf_Addr *)r->r_addend; + where = (Elf_Addr *)r->r_offset; + target = ((ifunc_resolver_t)ptr)(elf_hwcap, + 0, 0, 0, 0, 0, 0, 0); + *where = target; + break; + } +} diff --git a/lib/libkldelf/Makefile b/lib/libkldelf/Makefile new file mode 100644 index 000000000000..0d1716f17fca --- /dev/null +++ b/lib/libkldelf/Makefile @@ -0,0 +1,21 @@ +.include + +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 diff --git a/lib/libkldelf/Makefile.depend b/lib/libkldelf/Makefile.depend new file mode 100644 index 000000000000..b0aa274151ad --- /dev/null +++ b/lib/libkldelf/Makefile.depend @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/libelf \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/kldxref/ef.c b/lib/libkldelf/ef.c similarity index 99% rename from usr.sbin/kldxref/ef.c rename to lib/libkldelf/ef.c index 975626e46046..dcd87fe2bf83 100644 --- a/usr.sbin/kldxref/ef.c +++ b/lib/libkldelf/ef.c @@ -41,7 +41,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" #define MAXSEGS 16 struct ef_file { @@ -89,6 +89,7 @@ static struct elf_file_ops ef_file_ops = { .seg_read_string = ef_seg_read_string, .symaddr = ef_symaddr, .lookup_set = ef_lookup_set, + .lookup_symbol = ef_lookup_symbol, }; static void diff --git a/usr.sbin/kldxref/ef_aarch64.c b/lib/libkldelf/ef_aarch64.c similarity index 99% rename from usr.sbin/kldxref/ef_aarch64.c rename to lib/libkldelf/ef_aarch64.c index b61de3b032ab..d2db29f22891 100644 --- a/usr.sbin/kldxref/ef_aarch64.c +++ b/lib/libkldelf/ef_aarch64.c @@ -31,7 +31,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/ef_amd64.c b/lib/libkldelf/ef_amd64.c similarity index 99% rename from usr.sbin/kldxref/ef_amd64.c rename to lib/libkldelf/ef_amd64.c index fde032dcabc2..7295835f75b3 100644 --- a/usr.sbin/kldxref/ef_amd64.c +++ b/lib/libkldelf/ef_amd64.c @@ -33,7 +33,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/ef_arm.c b/lib/libkldelf/ef_arm.c similarity index 99% rename from usr.sbin/kldxref/ef_arm.c rename to lib/libkldelf/ef_arm.c index cc5e265f821e..657294dc9fb0 100644 --- a/usr.sbin/kldxref/ef_arm.c +++ b/lib/libkldelf/ef_arm.c @@ -34,7 +34,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/ef_i386.c b/lib/libkldelf/ef_i386.c similarity index 99% rename from usr.sbin/kldxref/ef_i386.c rename to lib/libkldelf/ef_i386.c index 962ed2bc0664..ae571e2d50f2 100644 --- a/usr.sbin/kldxref/ef_i386.c +++ b/lib/libkldelf/ef_i386.c @@ -33,7 +33,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/ef_mips.c b/lib/libkldelf/ef_mips.c similarity index 99% rename from usr.sbin/kldxref/ef_mips.c rename to lib/libkldelf/ef_mips.c index e4aeedb5c08b..99790e11a9c3 100644 --- a/usr.sbin/kldxref/ef_mips.c +++ b/lib/libkldelf/ef_mips.c @@ -36,7 +36,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/ef_obj.c b/lib/libkldelf/ef_obj.c similarity index 97% rename from usr.sbin/kldxref/ef_obj.c rename to lib/libkldelf/ef_obj.c index ac83137cd394..30e0d7886995 100644 --- a/usr.sbin/kldxref/ef_obj.c +++ b/lib/libkldelf/ef_obj.c @@ -43,7 +43,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" typedef struct { GElf_Addr addr; @@ -109,6 +109,7 @@ static struct elf_file_ops ef_obj_file_ops = { .seg_read_string = ef_obj_seg_read_string, .symaddr = ef_obj_symaddr, .lookup_set = ef_obj_lookup_set, + .lookup_symbol = ef_obj_lookup_symbol, }; static GElf_Off @@ -344,20 +345,20 @@ ef_obj_open(struct elf_file *efile, int verbose) if ((ef->nprogtab != 0 && ef->progtab == NULL) || (ef->nrel != 0 && ef->reltab == NULL) || (ef->nrela != 0 && ef->relatab == NULL)) { - printf("malloc failed\n"); + warnx("malloc failed"); error = ENOMEM; goto out; } if (elf_read_symbols(efile, symtabindex, &ef->ddbsymcnt, &ef->ddbsymtab) != 0) { - printf("elf_read_symbols failed\n"); + warnx("elf_read_symbols failed"); goto out; } if (elf_read_string_table(efile, &shdr[symstrindex], &ef->ddbstrcnt, &ef->ddbstrtab) != 0) { - printf("elf_read_string_table failed\n"); + warnx("elf_read_string_table failed"); goto out; } @@ -366,7 +367,7 @@ ef_obj_open(struct elf_file *efile, int verbose) 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"); + warnx("elf_read_string_table failed"); goto out; } } @@ -412,7 +413,7 @@ ef_obj_open(struct elf_file *efile, int verbose) 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"); + warnx("elf_read_rel failed"); goto out; } rl++; @@ -421,7 +422,7 @@ ef_obj_open(struct elf_file *efile, int verbose) 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"); + warnx("elf_read_rela failed"); goto out; } ra++; diff --git a/usr.sbin/kldxref/ef_powerpc.c b/lib/libkldelf/ef_powerpc.c similarity index 99% rename from usr.sbin/kldxref/ef_powerpc.c rename to lib/libkldelf/ef_powerpc.c index f72cc1d85e20..33f09c0d69ef 100644 --- a/usr.sbin/kldxref/ef_powerpc.c +++ b/lib/libkldelf/ef_powerpc.c @@ -33,7 +33,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/ef_riscv.c b/lib/libkldelf/ef_riscv.c similarity index 99% rename from usr.sbin/kldxref/ef_riscv.c rename to lib/libkldelf/ef_riscv.c index 46b9b66bee58..bda04bb2c39a 100644 --- a/usr.sbin/kldxref/ef_riscv.c +++ b/lib/libkldelf/ef_riscv.c @@ -36,7 +36,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" /* * Apply relocations to the values obtained from the file. `relbase' is the diff --git a/usr.sbin/kldxref/elf.c b/lib/libkldelf/elf.c similarity index 98% rename from usr.sbin/kldxref/elf.c rename to lib/libkldelf/elf.c index f98c39b69c0b..8af02622de13 100644 --- a/usr.sbin/kldxref/elf.c +++ b/lib/libkldelf/elf.c @@ -44,7 +44,7 @@ #include #include -#include "ef.h" +#include "kldelf.h" SET_DECLARE(elf_reloc, struct elf_reloc_data); @@ -686,3 +686,9 @@ elf_reloc(struct elf_file *efile, const void *reldata, Elf_Type reltype, return (efile->ef_reloc(efile, reldata, reltype, relbase, dataoff, len, dest)); } + +int +elf_lookup_symbol(struct elf_file *efile, const char *name, GElf_Sym **sym) +{ + return (EF_LOOKUP_SYMBOL(efile, name, sym)); +} diff --git a/usr.sbin/kldxref/ef.h b/lib/libkldelf/kldelf.h similarity index 94% rename from usr.sbin/kldxref/ef.h rename to lib/libkldelf/kldelf.h index 9d3dc1b1b435..71de31a94291 100644 --- a/usr.sbin/kldxref/ef.h +++ b/lib/libkldelf/kldelf.h @@ -32,8 +32,8 @@ * SUCH DAMAGE. */ -#ifndef _EF_H_ -#define _EF_H_ +#ifndef _KLDELF_H_ +#define _KLDELF_H_ #include #include @@ -48,6 +48,8 @@ (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) +#define EF_LOOKUP_SYMBOL(ef, name, sym) \ + (ef)->ef_ops->lookup_symbol((ef)->ef_ef, name, sym) /* XXX, should have a different name. */ typedef struct ef_file *elf_file_t; @@ -67,6 +69,7 @@ struct elf_file_ops { 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); + int (*lookup_symbol)(elf_file_t ef, const char *name, GElf_Sym **sym); }; typedef int (elf_reloc_t)(struct elf_file *ef, const void *reldata, @@ -310,6 +313,16 @@ int elf_read_mod_pnp_match_info(struct elf_file *efile, GElf_Addr addr, int elf_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest); +/* + * Find the symbol with the specified symbol name 'name' within the given + * 'efile'. 0 is returned when such a symbol is found, otherwise ENOENT is + * returned. + * + * XXX: This only return the first symbol being found when traversing symtab. + */ +int elf_lookup_symbol(struct elf_file *efile, const char *name, + GElf_Sym **sym); + __END_DECLS -#endif /* _EF_H_*/ +#endif /* _KLDELF_H_*/ diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index ec97c47d72b9..f41db2303554 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -27,6 +27,7 @@ _PRIVATELIBS= \ gtest_main \ heimipcc \ heimipcs \ + kldelf \ ldns \ sqlite3 \ ssh \ @@ -320,6 +321,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 diff --git a/sys/dev/ipmi/ipmi.c b/sys/dev/ipmi/ipmi.c index efb8a7e7669b..5f759017441c 100644 --- a/sys/dev/ipmi/ipmi.c +++ b/sys/dev/ipmi/ipmi.c @@ -360,7 +360,7 @@ ipmi_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, kreq->ir_request[req->msg.data_len + 7] = ipmi_ipmb_checksum(&kreq->ir_request[4], req->msg.data_len + 3); - error = ipmi_submit_driver_request(sc, kreq, MAX_TIMEOUT); + error = ipmi_submit_driver_request(sc, kreq); if (error != 0) return (error); @@ -565,11 +565,10 @@ ipmi_complete_request(struct ipmi_softc *sc, struct ipmi_request *req) /* Perform an internal driver request. */ int -ipmi_submit_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, - int timo) +ipmi_submit_driver_request(struct ipmi_softc *sc, struct ipmi_request *req) { - return (sc->ipmi_driver_request(sc, req, timo)); + return (sc->ipmi_driver_request(sc, req)); } /* @@ -636,7 +635,7 @@ ipmi_reset_watchdog(struct ipmi_softc *sc) IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_RESET_WDOG, 0, 0); - error = ipmi_submit_driver_request(sc, req, 0); + error = ipmi_submit_driver_request(sc, req); if (error) { device_printf(sc->ipmi_dev, "Failed to reset watchdog\n"); } else if (req->ir_compcode == 0x80) { @@ -677,7 +676,7 @@ ipmi_set_watchdog(struct ipmi_softc *sc, unsigned int sec) req->ir_request[4] = 0; req->ir_request[5] = 0; } - error = ipmi_submit_driver_request(sc, req, 0); + error = ipmi_submit_driver_request(sc, req); if (error) { device_printf(sc->ipmi_dev, "Failed to set watchdog\n"); } else if (req->ir_compcode != 0) { @@ -812,7 +811,7 @@ ipmi_power_cycle(void *arg, int howto) IPMI_CHASSIS_CONTROL, 1, 0); req->ir_request[0] = IPMI_CC_POWER_CYCLE; - ipmi_submit_driver_request(sc, req, MAX_TIMEOUT); + ipmi_submit_driver_request(sc, req); if (req->ir_error != 0 || req->ir_compcode != 0) { device_printf(sc->ipmi_dev, "Power cycling via IPMI failed code %#x %#x\n", @@ -859,7 +858,7 @@ ipmi_startup(void *arg) IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_GET_DEVICE_ID, 0, 15); - error = ipmi_submit_driver_request(sc, req, MAX_TIMEOUT); + error = ipmi_submit_driver_request(sc, req); if (error == EWOULDBLOCK) { device_printf(dev, "Timed out waiting for GET_DEVICE_ID\n"); return; @@ -888,7 +887,7 @@ ipmi_startup(void *arg) IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_CLEAR_FLAGS, 1, 0); - ipmi_submit_driver_request(sc, req, 0); + ipmi_submit_driver_request(sc, req); /* XXX: Magic numbers */ if (req->ir_compcode == 0xc0) { @@ -903,7 +902,7 @@ ipmi_startup(void *arg) IPMI_GET_CHANNEL_INFO, 1, 0); req->ir_request[0] = i; - error = ipmi_submit_driver_request(sc, req, 0); + error = ipmi_submit_driver_request(sc, req); if (error != 0 || req->ir_compcode != 0) break; @@ -918,7 +917,7 @@ ipmi_startup(void *arg) IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_GET_WDOG, 0, 0); - error = ipmi_submit_driver_request(sc, req, 0); + error = ipmi_submit_driver_request(sc, req); if (error == 0 && req->ir_compcode == 0x00) { device_printf(dev, "Attached watchdog\n"); diff --git a/sys/dev/ipmi/ipmi_bt.c b/sys/dev/ipmi/ipmi_bt.c index 2e92bdb0699e..c13397abd253 100644 --- a/sys/dev/ipmi/ipmi_bt.c +++ b/sys/dev/ipmi/ipmi_bt.c @@ -85,7 +85,7 @@ #define BT_IM_BMC_HWRST (1L << 7) static int bt_polled_request(struct ipmi_softc *, struct ipmi_request *); -static int bt_driver_request(struct ipmi_softc *, struct ipmi_request *, int); +static int bt_driver_request(struct ipmi_softc *, struct ipmi_request *); static int bt_wait(struct ipmi_softc *, uint8_t, uint8_t); static int bt_reset(struct ipmi_softc *); @@ -247,7 +247,7 @@ bt_loop(void *arg) IPMI_LOCK(sc); while ((req = ipmi_dequeue_request(sc)) != NULL) { IPMI_UNLOCK(sc); - (void)bt_driver_request(sc, req, 0); + (void)bt_driver_request(sc, req); IPMI_LOCK(sc); sc->ipmi_bt_seq++; ipmi_complete_request(sc, req); @@ -265,7 +265,7 @@ bt_startup(struct ipmi_softc *sc) } static int -bt_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo __unused) +bt_driver_request(struct ipmi_softc *sc, struct ipmi_request *req) { int i, ok; diff --git a/sys/dev/ipmi/ipmi_kcs.c b/sys/dev/ipmi/ipmi_kcs.c index 3f1d84d708ce..be8e6664b717 100644 --- a/sys/dev/ipmi/ipmi_kcs.c +++ b/sys/dev/ipmi/ipmi_kcs.c @@ -488,13 +488,13 @@ kcs_startup(struct ipmi_softc *sc) } static int -kcs_driver_request_queue(struct ipmi_softc *sc, struct ipmi_request *req, int timo) +kcs_driver_request_queue(struct ipmi_softc *sc, struct ipmi_request *req) { int error; IPMI_LOCK(sc); ipmi_polled_enqueue_request_highpri(sc, req); - error = msleep(req, &sc->ipmi_requests_lock, 0, "ipmireq", timo); + error = msleep(req, &sc->ipmi_requests_lock, 0, "ipmireq", 0); if (error == 0) error = req->ir_error; IPMI_UNLOCK(sc); @@ -517,13 +517,13 @@ kcs_driver_request_poll(struct ipmi_softc *sc, struct ipmi_request *req) } static int -kcs_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo) +kcs_driver_request(struct ipmi_softc *sc, struct ipmi_request *req) { if (KERNEL_PANICKED() || dumping) return (kcs_driver_request_poll(sc, req)); else - return (kcs_driver_request_queue(sc, req, timo)); + return (kcs_driver_request_queue(sc, req)); } diff --git a/sys/dev/ipmi/ipmi_opal.c b/sys/dev/ipmi/ipmi_opal.c index 084caba45184..ae7583a0d749 100644 --- a/sys/dev/ipmi/ipmi_opal.c +++ b/sys/dev/ipmi/ipmi_opal.c @@ -248,15 +248,14 @@ opal_ipmi_startup(struct ipmi_softc *sc) } static int -opal_ipmi_driver_request(struct ipmi_softc *isc, struct ipmi_request *req, - int timo) +opal_ipmi_driver_request(struct ipmi_softc *isc, struct ipmi_request *req) { struct opal_ipmi_softc *sc = (struct opal_ipmi_softc *)isc; int i, err; for (i = 0; i < 3; i++) { IPMI_LOCK(&sc->ipmi); - err = opal_ipmi_polled_request(sc, req, timo); + err = opal_ipmi_polled_request(sc, req, 0); IPMI_UNLOCK(&sc->ipmi); if (err == 0) break; diff --git a/sys/dev/ipmi/ipmi_smic.c b/sys/dev/ipmi/ipmi_smic.c index 1bcede44f920..0a80562db7dc 100644 --- a/sys/dev/ipmi/ipmi_smic.c +++ b/sys/dev/ipmi/ipmi_smic.c @@ -388,7 +388,7 @@ smic_startup(struct ipmi_softc *sc) } static int -smic_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo) +smic_driver_request(struct ipmi_softc *sc, struct ipmi_request *req) { int i, ok; diff --git a/sys/dev/ipmi/ipmi_ssif.c b/sys/dev/ipmi/ipmi_ssif.c index 0c22d35421ef..c83cccc75123 100644 --- a/sys/dev/ipmi/ipmi_ssif.c +++ b/sys/dev/ipmi/ipmi_ssif.c @@ -359,15 +359,14 @@ ssif_startup(struct ipmi_softc *sc) } static int -ssif_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo) +ssif_driver_request(struct ipmi_softc *sc, struct ipmi_request *req) { int error; IPMI_LOCK(sc); error = ipmi_polled_enqueue_request(sc, req); if (error == 0) - error = msleep(req, &sc->ipmi_requests_lock, 0, "ipmireq", - timo); + error = msleep(req, &sc->ipmi_requests_lock, 0, "ipmireq", 0); if (error == 0) error = req->ir_error; IPMI_UNLOCK(sc); diff --git a/sys/dev/ipmi/ipmivars.h b/sys/dev/ipmi/ipmivars.h index 17227c2053db..6ab8b128b820 100644 --- a/sys/dev/ipmi/ipmivars.h +++ b/sys/dev/ipmi/ipmivars.h @@ -133,7 +133,7 @@ struct ipmi_softc { driver_intr_t *ipmi_intr; int (*ipmi_startup)(struct ipmi_softc *); int (*ipmi_enqueue_request)(struct ipmi_softc *, struct ipmi_request *); - int (*ipmi_driver_request)(struct ipmi_softc *, struct ipmi_request *, int); + int (*ipmi_driver_request)(struct ipmi_softc *, struct ipmi_request *); }; #define ipmi_ssif_smbus_address _iface.ssif.smbus_address @@ -247,8 +247,7 @@ struct ipmi_request *ipmi_dequeue_request(struct ipmi_softc *); void ipmi_free_request(struct ipmi_request *); int ipmi_polled_enqueue_request(struct ipmi_softc *, struct ipmi_request *); int ipmi_polled_enqueue_request_highpri(struct ipmi_softc *, struct ipmi_request *); -int ipmi_submit_driver_request(struct ipmi_softc *, struct ipmi_request *, - int); +int ipmi_submit_driver_request(struct ipmi_softc *, struct ipmi_request *); /* Identify BMC interface via SMBIOS. */ int ipmi_smbios_identify(struct ipmi_get_info *); diff --git a/sys/tools/amd64_ia32_vdso.sh b/sys/tools/amd64_ia32_vdso.sh index 5de34480a5f6..e5865639d398 100644 --- a/sys/tools/amd64_ia32_vdso.sh +++ b/sys/tools/amd64_ia32_vdso.sh @@ -34,9 +34,14 @@ ${CC} -x assembler-with-cpp -DLOCORE -fPIC -nostdinc -c -m32 \ -o ia32_sigtramp.pico -I. -I"${S}" -include opt_global.h \ "${S}"/amd64/ia32/ia32_sigtramp.S +if ${LD} --version | ${AWK} '/^GNU ld/{exit 1}' ; then + RODYNAMIC="-z rodynamic" +else + RODYNAMIC="" +fi ${LD} --shared -Bsymbolic -soname="elf-vdso32.so.1" \ -T "${S}"/conf/vdso_amd64_ia32.ldscript \ - --eh-frame-hdr --no-undefined -z rodynamic -z norelro -nmagic \ + --eh-frame-hdr --no-undefined ${RODYNAMIC} -z norelro -nmagic \ --hash-style=sysv --fatal-warnings --strip-all \ -o elf-vdso32.so.1 ia32_sigtramp.pico diff --git a/sys/tools/amd64_vdso.sh b/sys/tools/amd64_vdso.sh index 5397590c2dcf..ed91ddc8abb5 100644 --- a/sys/tools/amd64_vdso.sh +++ b/sys/tools/amd64_vdso.sh @@ -40,12 +40,17 @@ ${CC} -x assembler-with-cpp -DLOCORE -fPIC -nostdinc -c \ # # -z rodynamic is undocumented lld-specific option, seemingly required # for lld to avoid putting dynamic into dedicated writeable segment, -# despite ldscript placement. It is ignored by ld.bfd but ldscript +# despite ldscript placement. It is omitted for ld.bfd, but ldscript # alone is enough there. # +if ${LD} --version | ${AWK} '/^GNU ld/{exit 1}' ; then + RODYNAMIC="-z rodynamic" +else + RODYNAMIC="" +fi ${LD} --shared -Bsymbolic -soname="elf-vdso.so.1" \ -T "${S}"/conf/vdso_amd64.ldscript \ - --eh-frame-hdr --no-undefined -z rodynamic -z norelro -nmagic \ + --eh-frame-hdr --no-undefined ${RODYNAMIC} -z norelro -nmagic \ --hash-style=sysv --fatal-warnings --strip-all \ -o elf-vdso.so.1 sigtramp.pico diff --git a/tools/build/Makefile b/tools/build/Makefile index 2bf212ce8c61..4430a27dc239 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -303,6 +303,10 @@ SYSINCS+= ${SRCTOP}/sys/sys/ctf.h SYSINCS+= ${SRCTOP}/sys/sys/kbio.h # for kldxref: SYSINCS+= ${SRCTOP}/sys/sys/module.h +.if ${.MAKE.OS} != "FreeBSD" +# for libmd: +SYSINCS+= ${SRCTOP}/sys/sys/md4.h +.endif # We want to run the build with only ${WORLDTMP} in $PATH to ensure we don't # accidentally run tools that are incompatible but happen to be in $PATH. diff --git a/tools/build/cross-build/include/common/sys/md4.h b/tools/build/cross-build/include/common/sys/md4.h deleted file mode 100644 index e00675e9f462..000000000000 --- a/tools/build/cross-build/include/common/sys/md4.h +++ /dev/null @@ -1,91 +0,0 @@ -/* MD4.H - header file for MD4C.C - */ - -/*- - SPDX-License-Identifier: RSA-MD - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - rights reserved. - - License to copy and use this software is granted provided that it - is identified as the "RSA Data Security, Inc. MD4 Message-Digest - Algorithm" in all material mentioning or referencing this software - or this function. - License is also granted to make and use derivative works provided - that such works are identified as "derived from the RSA Data - Security, Inc. MD4 Message-Digest Algorithm" in all material - mentioning or referencing the derived work. - - RSA Data Security, Inc. makes no representations concerning either - the merchantability of this software or the suitability of this - software for any particular purpose. It is provided "as is" - without express or implied warranty of any kind. - - These notices must be retained in any copies of any part of this - documentation and/or software. - */ - -#ifndef _SYS_MD4_H_ -#define _SYS_MD4_H_ -/* MD4 context. */ -typedef struct MD4Context { - u_int32_t state[4]; /* state (ABCD) */ - u_int32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD4_CTX; - -#include - -#ifndef _KERNEL - -/* Ensure libmd symbols do not clash with libcrypto */ - -#ifndef MD4Init -#define MD4Init _libmd_MD4Init -#endif -#ifndef MD4Update -#define MD4Update _libmd_MD4Update -#endif -#ifndef MD4Pad -#define MD4Pad _libmd_MD4Pad -#endif -#ifndef MD4Final -#define MD4Final _libmd_MD4Final -#endif -#ifndef MD4End -#define MD4End _libmd_MD4End -#endif -#ifndef MD4Fd -#define MD4Fd _libmd_MD4Fd -#endif -#ifndef MD4FdChunk -#define MD4FdChunk _libmd_MD4FdChunk -#endif -#ifndef MD4File -#define MD4File _libmd_MD4File -#endif -#ifndef MD4FileChunk -#define MD4FileChunk _libmd_MD4FileChunk -#endif -#ifndef MD4Data -#define MD4Data _libmd_MD4Data -#endif - -#endif - -__BEGIN_DECLS -void MD4Init(MD4_CTX *); -void MD4Update(MD4_CTX *, const unsigned char *, unsigned int); -void MD4Pad(MD4_CTX *); -void MD4Final(unsigned char [__min_size(16)], MD4_CTX *); -#ifndef _KERNEL -char * MD4End(MD4_CTX *, char *); -char * MD4Fd(int, char *); -char * MD4FdChunk(int, char *, off_t, off_t); -char * MD4File(const char *, char *); -char * MD4FileChunk(const char *, char *, off_t, off_t); -char * MD4Data(const void *, unsigned int, char *); -#endif -__END_DECLS - -#endif /* _SYS_MD4_H_ */ diff --git a/tools/build/cross-build/include/linux/limits.h b/tools/build/cross-build/include/linux/limits.h index 5eca34b1120c..4631cabb1104 100644 --- a/tools/build/cross-build/include/linux/limits.h +++ b/tools/build/cross-build/include/linux/limits.h @@ -45,13 +45,11 @@ #if !defined(_GNU_SOURCE) #warning "Attempting to use limits.h with -std=c89/without _GNU_SOURCE, many macros will be missing" #endif +#endif /* C89 */ -#else /* Not C89 */ -/* Not C89 -> check that all macros that we expect are defined */ #ifndef IOV_MAX #error IOV_MAX should be defined #endif -#endif /* C89 */ #ifndef MAXBSIZE #define MAXBSIZE 65536 /* must be power of 2 */ @@ -83,7 +81,6 @@ #endif #include -#include /* For IOV_MAX */ /* Sanity checks for glibc */ #ifndef _GNU_SOURCE diff --git a/tools/build/depend-cleanup.sh b/tools/build/depend-cleanup.sh index 94cafbd9a8d6..001a450bf182 100755 --- a/tools/build/depend-cleanup.sh +++ b/tools/build/depend-cleanup.sh @@ -199,3 +199,19 @@ clean_dep cddl/lib/libzpool zfs_debug c "linux/zfs/zfs_debug\.c" # 20241011 clean_dep cddl/lib/libzpool arc_os c "linux/zfs/arc_os\.c" + +# 20241018 1363acbf25de libc/csu: Support IFUNCs on riscv +if [ ${MACHINE} = riscv ]; then + for f in "$OBJTOP"/lib/libc/.depend.libc_start1.*o; do + if [ ! -f "$f" ]; then + continue + fi + if ! grep -q 'lib/libc/csu/riscv/reloc\.c' "$f"; then + echo "Removing stale dependencies and objects for libc_start1.c" + run rm -f \ + "$OBJTOP"/lib/libc/.depend.libc_start1.* \ + "$OBJTOP"/lib/libc/libc_start1.*o + break + fi + done +fi diff --git a/usr.bin/mididump/mididump.c b/usr.bin/mididump/mididump.c index 9c8fe62c9859..16bd775f10d4 100644 --- a/usr.bin/mididump/mididump.c +++ b/usr.bin/mididump/mididump.c @@ -44,10 +44,10 @@ #define NOTE2FREQ(n) (440 * pow(2.0f, ((float)n - 69) / 12)) #define CHAN_MASK 0x0f -struct note { +static struct note { const char *name; const char *alt; -} static notes[] = { +} notes[] = { { "C", NULL }, { "C#", "Db" }, { "D", NULL }, @@ -211,7 +211,7 @@ main(int argc, char *argv[]) case 0xb0 ... 0xbf: b1 = read_byte(fd); b2 = read_byte(fd); - if (b1 < 0 || b1 > ARRLEN(ctls) - 1) + if (b1 > ARRLEN(ctls) - 1) break; printf("Control/Mode change channel=%d, " "control=%d (%s), value=%d", diff --git a/usr.sbin/kldxref/Makefile b/usr.sbin/kldxref/Makefile index fc9b0b4215fc..ab7b373a45cc 100644 --- a/usr.sbin/kldxref/Makefile +++ b/usr.sbin/kldxref/Makefile @@ -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 diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c index 6bb0469a9ff5..eed754e1e730 100644 --- a/usr.sbin/kldxref/kldxref.c +++ b/usr.sbin/kldxref/kldxref.c @@ -51,7 +51,7 @@ #include #include -#include "ef.h" +#include #define MAXRECSIZE (64 << 10) /* 64k */ #define check(val) if ((error = (val)) != 0) break