klibc-bot for Greg Thelen
2022-Aug-03 22:51 UTC
[klibc] [klibc:master] Revert " remove local insmod.c copy"
Commit-ID: 2f31533dd248f24c8f90a0551cf86b09f144b77c Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=2f31533dd248f24c8f90a0551cf86b09f144b77c Author: Greg Thelen <gthelen at google.com> AuthorDate: Mon, 1 Aug 2022 22:30:12 -0700 Committer: Ben Hutchings <ben at decadent.org.uk> CommitDate: Tue, 2 Aug 2022 22:31:47 +0200 [klibc] Revert " remove local insmod.c copy" This reverts commit fbf8aa559d25685eea12248c76bcc983c68306b2. insmod is useful to load boot drivers prior to calling kinit. Signed-off-by: Greg Thelen <gthelen at google.com> Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/utils/Kbuild | 4 +- usr/utils/insmod.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) diff --git a/usr/utils/Kbuild b/usr/utils/Kbuild index 38abb8fe..002342f7 100644 --- a/usr/utils/Kbuild +++ b/usr/utils/Kbuild @@ -4,7 +4,7 @@ progs := chroot dd mkdir mkfifo mknod mount pivot_root umount progs += true false sleep ln mv nuke minips cat ls losetup -progs += uname halt kill readlink cpio sync dmesg +progs += insmod uname halt kill readlink cpio sync dmesg static-y := $(addprefix static/, $(progs)) shared-y := $(addprefix shared/, $(progs)) @@ -46,6 +46,8 @@ static/minips-y := minips.o shared/minips-y := minips.o static/cat-y := cat.o shared/cat-y := cat.o +static/insmod-y := insmod.o +shared/insmod-y := insmod.o static/uname-y := uname.o shared/uname-y := uname.o static/halt-y := halt.o diff --git a/usr/utils/insmod.c b/usr/utils/insmod.c new file mode 100644 index 00000000..47b58800 --- /dev/null +++ b/usr/utils/insmod.c @@ -0,0 +1,140 @@ +/* insmod.c: insert a module into the kernel. + Copyright (C) 2001 Rusty Russell. + Copyright (C) 2002 Rusty Russell, IBM Corporation. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> + +#define streq(a,b) (strcmp((a),(b)) == 0) + +/* This really needs to be in a header file... */ +extern long init_module(void *, unsigned long, const char *); + +static void print_usage(const char *progname) +{ + fprintf(stderr, "Usage: %s filename [args]\n", progname); + exit(1); +} + +/* We use error numbers in a loose translation... */ +static const char *moderror(int err) +{ + switch (err) { + case ENOEXEC: + return "Invalid module format"; + case ENOENT: + return "Unknown symbol in module"; + case ESRCH: + return "Module has wrong symbol version"; + case EINVAL: + return "Invalid parameters"; + default: + return strerror(err); + } +} + +static void *grab_file(const char *filename, unsigned long *size) +{ + unsigned int max = 16384; + int ret, fd; + void *buffer = malloc(max); + + if (streq(filename, "-")) + fd = dup(STDIN_FILENO); + else + fd = open(filename, O_RDONLY, 0); + + if (fd < 0) + return NULL; + + *size = 0; + while ((ret = read(fd, buffer + *size, max - *size)) > 0) { + *size += ret; + if (*size == max) + buffer = realloc(buffer, max *= 2); + } + if (ret < 0) { + free(buffer); + buffer = NULL; + } + close(fd); + return buffer; +} + +int main(int argc, char *argv[]) +{ + int i; + long int ret; + unsigned long len; + void *file; + char *filename, *options = strdup(""); + char *progname = argv[0]; + + if (argv[1] && (streq(argv[1], "--version") || streq(argv[1], "-V"))) { + puts("klibc insmod"); + exit(0); + } + + /* Ignore old options, for backwards compat. */ + while (argv[1] && (streq(argv[1], "-p") + || streq(argv[1], "-s") + || streq(argv[1], "-f"))) { + argv++; + argc--; + } + + filename = argv[1]; + if (!filename) + print_usage(progname); + + /* Rest is options */ + for (i = 2; i < argc; i++) { + options = realloc(options, + strlen(options) + 2 + strlen(argv[i]) + 2); + /* Spaces handled by "" pairs, but no way of escaping + quotes */ + if (strchr(argv[i], ' ')) + strcat(options, "\""); + strcat(options, argv[i]); + if (strchr(argv[i], ' ')) + strcat(options, "\""); + strcat(options, " "); + } + + file = grab_file(filename, &len); + if (!file) { + fprintf(stderr, "insmod: can't read '%s': %s\n", + filename, strerror(errno)); + exit(1); + } + + ret = init_module(file, len, options); + if (ret != 0) { + fprintf(stderr, "insmod: error inserting '%s': %li %s\n", + filename, ret, moderror(errno)); + exit(1); + } + exit(0); +}