aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/ndiscvt/ndiscvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ndiscvt/ndiscvt.c')
-rw-r--r--usr.sbin/ndiscvt/ndiscvt.c155
1 files changed, 144 insertions, 11 deletions
diff --git a/usr.sbin/ndiscvt/ndiscvt.c b/usr.sbin/ndiscvt/ndiscvt.c
index d1a29b3a0cfe..8c78d5434afa 100644
--- a/usr.sbin/ndiscvt/ndiscvt.c
+++ b/usr.sbin/ndiscvt/ndiscvt.c
@@ -42,7 +42,9 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <libgen.h>
#include <err.h>
+#include <ctype.h>
#include <compat/ndis/pe_var.h>
@@ -157,25 +159,130 @@ int insert_padding(imgbase, imglen)
static void
usage(void)
{
- fprintf(stderr, "Usage: %s [-i <inffile>] -s <sysfile> "
+ fprintf(stderr, "Usage: %s [-O] [-i <inffile>] -s <sysfile> "
"[-n devname] [-o outfile]\n", __progname);
+ fprintf(stderr, " %s -f <firmfile>\n", __progname);
+
exit(1);
}
+static void
+bincvt(char *sysfile, char *outfile, void *img, int fsize)
+{
+ char *ptr;
+ char tname[] = "/tmp/ndiscvt.XXXXXX";
+ char sysbuf[1024];
+ FILE *binfp;
+
+ mkstemp(tname);
+
+ binfp = fopen(tname, "a+");
+ if (binfp == NULL)
+ err(1, "opening %s failed", tname);
+
+ if (fwrite(img, fsize, 1, binfp) != 1)
+ err(1, "failed to output binary image");
+
+ fclose(binfp);
+
+ outfile = strdup(basename(outfile));
+ if (strchr(outfile, '.'))
+ *strchr(outfile, '.') = '\0';
+
+ snprintf(sysbuf, sizeof(sysbuf),
+ "objcopy -I binary -O elf32-i386-freebsd -B i386 %s %s.o\n",
+ tname, outfile);
+ printf("%s", sysbuf);
+ system(sysbuf);
+ unlink(tname);
+
+ ptr = tname;
+ while (*ptr) {
+ if (*ptr == '/' || *ptr == '.')
+ *ptr = '_';
+ ptr++;
+ }
+
+ snprintf(sysbuf, sizeof(sysbuf),
+ "objcopy --redefine-sym _binary_%s_start=%s_drv_data_start "
+ "--strip-symbol _binary_%s_size "
+ "--redefine-sym _binary_%s_end=%s_drv_data_end %s.o %s.o\n",
+ tname, sysfile, tname, tname, sysfile, outfile, outfile);
+ printf("%s", sysbuf);
+ system(sysbuf);
+
+ return;
+}
+
+static void
+firmcvt(char *firmfile)
+{
+ char *basefile, *outfile, *ptr;
+ char sysbuf[1024];
+
+ outfile = basename(firmfile);
+ basefile = strdup(outfile);
+
+ snprintf(sysbuf, sizeof(sysbuf),
+ "objcopy -I binary -O elf32-i386-freebsd -B i386 %s %s.o\n",
+ firmfile, outfile);
+ printf("%s", sysbuf);
+ system(sysbuf);
+
+ ptr = firmfile;
+ while (*ptr) {
+ if (*ptr == '/' || *ptr == '.')
+ *ptr = '_';
+ ptr++;
+ }
+ ptr = basefile;
+ while (*ptr) {
+ if (*ptr == '/' || *ptr == '.')
+ *ptr = '_';
+ else
+ *ptr = tolower(*ptr);
+ ptr++;
+ }
+
+ snprintf(sysbuf, sizeof(sysbuf),
+ "objcopy --redefine-sym _binary_%s_start=%s_start "
+ "--strip-symbol _binary_%s_size "
+ "--redefine-sym _binary_%s_end=%s_end %s.o %s.o\n",
+ firmfile, basefile, firmfile, firmfile,
+ basefile, outfile, outfile);
+ ptr = sysbuf;
+ printf("%s", sysbuf);
+ system(sysbuf);
+
+ snprintf(sysbuf, sizeof(sysbuf),
+ "ld -Bshareable -d -warn-common -o %s.ko %s.o\n",
+ outfile, outfile);
+ printf("%s", sysbuf);
+ system(sysbuf);
+
+ free(basefile);
+
+ exit(0);
+}
+
int
main(int argc, char *argv[])
{
- FILE *fp, *outfp;
- void *img;
- int n, fsize, cnt;
- unsigned char *ptr;
- int i;
- char *inffile = NULL, *sysfile = NULL, *outfile = NULL;
- char *dname = NULL;
- int ch;
-
- while((ch = getopt(argc, argv, "i:s:o:n:")) != -1) {
+ FILE *fp, *outfp;
+ int i, bin = 0;
+ void *img;
+ int n, fsize, cnt;
+ unsigned char *ptr;
+ char *inffile = NULL, *sysfile = NULL;
+ char *outfile = NULL, *firmfile = NULL;
+ char *dname = NULL;
+ int ch;
+
+ while((ch = getopt(argc, argv, "i:s:o:n:f:O")) != -1) {
switch(ch) {
+ case 'f':
+ firmfile = optarg;
+ break;
case 'i':
inffile = optarg;
break;
@@ -188,12 +295,18 @@ main(int argc, char *argv[])
case 'n':
dname = optarg;
break;
+ case 'O':
+ bin = 1;
+ break;
default:
usage();
break;
}
}
+ if (firmfile != NULL)
+ firmcvt(firmfile);
+
if (sysfile == NULL)
usage();
@@ -253,6 +366,25 @@ main(int argc, char *argv[])
}
fprintf(outfp, "\n#ifdef NDIS_IMAGE\n");
+
+ if (bin) {
+ sysfile = strdup(basename(sysfile));
+ ptr = sysfile;
+ while (*ptr) {
+ if (*ptr == '.')
+ *ptr = '_';
+ ptr++;
+ }
+ fprintf(outfp,
+ "\nextern unsigned char %s_drv_data_start[];\n",
+ sysfile);
+ fprintf(outfp, "static unsigned char *drv_data = "
+ "%s_drv_data_start;\n\n", sysfile);
+ bincvt(sysfile, outfile, img, fsize);
+ goto done;
+ }
+
+
fprintf(outfp, "\nextern unsigned char drv_data[];\n\n");
fprintf(outfp, "__asm__(\".data\");\n");
@@ -282,6 +414,7 @@ main(int argc, char *argv[])
done:
fprintf(outfp, "#endif /* NDIS_IMAGE */\n");
+
if (fp != NULL)
fclose(fp);
fclose(outfp);