shithub: scc

Download patch

ref: b5f8e196aa5692b1ed355de2c772b88816d89d44
parent: 10f5b25b7e6e3fda240c7b7046712c33e667fc33
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Jan 30 05:53:59 EST 2019

[ranlib] Build index file

Until now, ranlib was only a placeholder because
it didn't build the actual index. After this change
it actually did it.

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -2,6 +2,7 @@
 
 typedef struct section Section;
 typedef struct symbol Symbol;
+typedef struct symdef Symdef;
 typedef struct object Obj;
 
 enum sectype {
@@ -17,6 +18,10 @@
 struct section {
 	char *name;
 	unsigned flags;
+	FILE *fp;
+	long offset;
+	unsigned long long size;
+	Section *next;
 };
 
 struct symbol {
@@ -28,11 +33,19 @@
 	Symbol *hash;
 };
 
+struct symdef {
+	char *name;
+	int type;
+	long offset;
+	Symdef *hash, *next;
+};
+
 struct object {
 	int type;
 	Symbol *htab[NR_SYMHASH];
 	Symbol *head;
 	fpos_t pos;
+	Section *sections;
 	void *data;
 };
 
@@ -55,6 +68,7 @@
                    unsigned long long *text,
                    unsigned long long *data,
                    unsigned long long *bss);
+extern long arindex(int type, long nsyms, Symdef *def, FILE *fp);
 
 /* TODO */
 extern int objload(Obj *obj, Obj *to);
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -31,8 +31,8 @@
 $(BINDIR)/size: size.o
 	$(CC) $(SCC_LDFLAGS) size.o -lmach -o $@
 
-$(BINDIR)/ranlib: ranlib.o
-	$(CC) $(SCC_LDFLAGS) ranlib.o -lmach -o $@
+$(BINDIR)/ranlib: ranlib.o $(DRIVER).o
+	$(CC) $(SCC_LDFLAGS) ranlib.o $(DRIVER).o -lmach -o $@
 
 $(BINDIR)/objdump: objdump.o
 	$(CC) $(SCC_LDFLAGS) objdump.o -lmach -o $@
--- a/src/cmd/ar.c
+++ b/src/cmd/ar.c
@@ -123,15 +123,16 @@
 		error("opening member '%s': %s", pname, errstr());
 	if (getstat(pname, &prop) < 0)
 		error("error getting '%s' attributes", pname);
+
 	strftime(mtime, sizeof(mtime), "%s", gmtime(&prop.time));
 	fprintf(to,
-	        "%-16.16s%-12s%-6u%-6u%-8lo%-10llu`\n",
+	        "%-16.16s%-12s%-6u%-6u%-8lo%-10ld`\n",
 	        fname,
 	        mtime,
 	        prop.uid,
 	        prop.gid,
 	        prop.mode,
-	        (unsigned long long) prop.size);
+	        prop.size);
 	for (n = 0; (c = getc(from)) != EOF; n++)
 		putc(c, to);
 	if (n & 1)
--- a/src/cmd/posix.c
+++ b/src/cmd/posix.c
@@ -7,6 +7,8 @@
 #include <unistd.h>
 #include <utime.h>
 
+#include <limits.h>
+
 #include "sys.h"
 
 const char invalidchars[] = " ";
@@ -30,6 +32,8 @@
 	struct stat st;
 
 	if (stat(fname, &st) < 0)
+		return -1;
+	if (st.st_size > LONG_MAX)
 		return -1;
 	prop->uid = st.st_uid;
 	prop->gid = st.st_gid;
--- a/src/cmd/ranlib.c
+++ b/src/cmd/ranlib.c
@@ -1,27 +1,24 @@
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
+#include <scc/ar.h>
 #include <scc/arg.h>
 #include <scc/mach.h>
 
-#define NR_NAMES 32
+#include "sys.h"
 
-typedef struct name Name;
+#define NR_SYMDEF 32
 
-struct name {
-	char *name;
-	int type;
-	long offset;
-	Name *hash, *next;
-};
-
-static int status, tflag, artype, nolib;
+static long nsymbols;
+static int status, artype, nolib;
 static char *filename, *membname;
-static Name *htab[NR_NAMES], *head;
+static Symdef *htab[NR_SYMDEF], *head;
 static long offset;
 char *argv0;
 
@@ -47,11 +44,11 @@
 	status = EXIT_FAILURE;
 }
 
-Name *
+Symdef *
 lookup(char *name)
 {
 	unsigned h;
-	Name *np;
+	Symdef *dp;
 	char *s;
 	size_t len;
 
@@ -58,39 +55,41 @@
 	h = 0;
 	for (s = name; *s; s++)
 		h += *s;
-	h %= NR_NAMES;
+	h %= NR_SYMDEF;
 
-	for (np = htab[h]; np; np = np->next) {
-		if (!strcmp(np->name, name))
-			return np;
+	for (dp = htab[h]; dp; dp = dp->next) {
+		if (!strcmp(dp->name, name))
+			return dp;
 	}
 
 	len = strlen(name) + 1;
-	np = malloc(sizeof(*np));
+	dp = malloc(sizeof(*dp));
 	s = malloc(len);
-	if (!np || !s) {
+	if (!dp || !s) {
 		free(s);
-		free(np);
+		free(dp);
 		return NULL;
 	}
 
-	memcpy(np->name, s, len);
-	np->type = 'U';
-	np->offset = -1;
-	np->hash = htab[h];
-	htab[h] = np;
-	np->next = head;
-	head = np;
+	nsymbols++;
+	dp->name = s;
+	memcpy(dp->name, name, len);
+	dp->type = 'U';
+	dp->offset = -1;
+	dp->hash = htab[h];
+	htab[h] = dp;
+	dp->next = head;
+	head = dp;
 
-	return np;
+	return dp;
 }
 
 static int
 newsymbol(Symbol *sym, void *data)
 {
-	Name *np;
+	Symdef *np;
 
-	if (!isupper(sym->type))
+	if (!isupper(sym->type) || sym->type == 'N')
 		return 1;
 
 	if ((np = lookup(sym->name)) == NULL) {
@@ -117,13 +116,16 @@
 }
 
 static int
-newmember(FILE *fp, char *name, void *data)
+newmember(FILE *fp, char *nam, void *data)
 {
 
 	int t, ret = 0;
 	Obj *obj;
 
-	membname = name;
+	if (artype == -1 && (!strcmp(nam, "/") || !strcmp(nam, "__.SYMDEF")))
+		return 1;
+
+	membname = nam;
 	offset = ftell(fp);
 
 	if (offset == EOF) {
@@ -132,8 +134,7 @@
 	}
 
 	t = objtype(fp, NULL);
-
-	if(t == -1 || artype != -1 && artype != t) {
+	if (t == -1 || artype != -1 && artype != t) {
 		nolib = 1;
 		return 0;
 	}
@@ -162,11 +163,11 @@
 }
 
 static void
-freenames(void)
+freehash(void)
 {
-	Name **npp, *next, *np;
+	Symdef **npp, *next, *np;
 
-	for (npp = htab; npp < &htab[NR_NAMES]; npp++)
+	for (npp = htab; npp < &htab[NR_SYMDEF]; npp++)
 		*npp = NULL;
 
 	for (np = head; np; np = next) {
@@ -179,97 +180,154 @@
 }
 
 static int
-readsyms(char *fname)
+readsyms(FILE *fp)
 {
-	FILE *fp;
-
-	if ((fp = fopen(fname, "rb")) == NULL) {
-		error(errstr());
-		goto error;
-	}
-
+	/* TODO: Change archive to returns -1 */
 	if (!archive(fp)) {
 		error("file format not recognized");
-		goto error;
+		return 0;
 	}
 
-	if (!artraverse(fp, newmember, NULL)) {
+	if (artraverse(fp, newmember, NULL) < 0) {
 		error("while traversing archive");
-		goto error;
-	}
-
-	if (fclose(fp)) {
-		error(errstr());
 		return 0;
 	}
-	return 1;
 
-error:
-	fclose(fp);
-	return 0;
+	return 1;
 }
 
 static int
-writeidx(char *fname)
+merge(FILE *to, struct fprop *prop, FILE *lib, FILE *idx)
 {
-	int r;
-	FILE *fp;
-	Name *np;
+	int c;
+	char mtime[13];
+	struct ar_hdr first;
 
-	if ((fp = fopen(fname, "wb")) == NULL) {
-		error("index file: %s", errstr());
+	rewind(lib);
+	rewind(idx);
+	fseek(lib, SARMAG, SEEK_SET);
+
+	if (fread(&first, sizeof(first), 1, lib) != 1)
 		return 0;
-	}
 
-	for (np = head; np; np = np->next) {
-		/* TODO: write out */
+	if (!strncmp(first.ar_name, "/", SARNAM) ||
+	    !strncmp(first.ar_name, "__.SYMDEF", SARNAM)) {
+		fseek(lib, atol(first.ar_size), SEEK_CUR);
 	}
-	fflush(fp);
-	r = ferror(fp);
-	fclose(fp);
 
-	if (!r)
-		return 1;
+	fwrite(ARMAG, SARMAG, 1, to);
 
-	error("index file: %s", errstr());
-	return 0;
+        strftime(mtime, sizeof(mtime), "%s", gmtime(&prop->time));
+        fprintf(to,
+                "%-16.16s%-12s%-6u%-6u%-8lo%-10ld`\n",
+                "/",
+                mtime,
+                prop->uid,
+                prop->gid,
+                prop->mode,
+                prop->size);
+
+	while ((c = getc(idx)) != EOF)
+		putc(c, to);
+
+	while ((c = getc(lib)) != EOF)
+		putc(c, to);
+
+	fflush(to);
+
+	if (ferror(to) || ferror(lib) || ferror(idx))
+		return 0;
+
+	return 1;
 }
 
 static int
-insertidx(char *archive, char *idx)
+copy(FILE *from, char *fname)
 {
-	return 0;
+	int c, ret;
+	FILE *fp;
+
+	if ((fp = fopen(fname, "wb")) == NULL)
+		return 0;
+
+	rewind(from);
+	while ((c = getc(from)) != EOF)
+		putc(c, fp);
+	fflush(fp);
+
+	ret = !ferror(fp) && !ferror(from);
+
+	fclose(fp);
+
+	return ret;
 }
 
 static void
 ranlib(char *fname)
 {
-	static char symdef[] = "__.SYMDEF";
+	int c;
+	FILE *fp, *idx, *out;
+	long siz;
+	struct fprop prop;
 
+	errno = 0;
 	nolib = 0;
 	artype = -1;
+	nsymbols = 0;
 	filename = fname;
-	freenames();
+	freehash();
 
-	if (!readsyms(fname))
-		return;
+	fp = fopen(fname, "rb");
+	idx = tmpfile();
+	out = tmpfile();
+	if (!fp || !idx || !out)
+		goto error;
 
+	if (!readsyms(fp))
+		goto error;
+
 	if (nolib)
-		return;
+		goto error;
 
-	if (!writeidx(symdef))
-		return;
+	/* TODO: Change arindex to returns -1 */
+	siz = arindex(artype, nsymbols, head, idx);
+	if (siz <= 0)
+		goto error;
 
-	if (!insertidx(fname, symdef))
-		remove(symdef);
+	if (getstat(fname, &prop) < 0)
+		goto error;
+	prop.size = siz;
+	prop.time = time(NULL);
 
+	if (!merge(out, &prop, fp, idx))
+		goto error;
+
+	fclose(fp);
+	fclose(idx);
+	fp = idx = NULL;
+
+	if (!copy(out, fname))
+		goto error;
+
+	fclose(out);
+
 	return;
+
+error:
+	if (errno)
+		error(errstr());
+	if (idx)
+		fclose(idx);
+	if (out)
+		fclose(out);
+	if (fp)
+		fclose(fp);
 }
 
 static void
 usage(void)
 {
-	fputs("usage: ranlib [-t] [file...]\n", stderr);
+	fputs("usage: ranlib [-t] file...\n", stderr);
 	exit(EXIT_FAILURE);
 }
 
@@ -278,18 +336,16 @@
 {
 	ARGBEGIN {
 	case 't':
-		tflag = 1; /* TODO */
 		break;
 	default:
 		usage();
 	} ARGEND
 
-	if (argc == 0) {
-		ranlib("a.out");
-	} else {
-		for (; *argv; ++argv)
-			ranlib(*argv);
-	}
+	if (argc == 0)
+		usage();
+
+	for (; *argv; ++argv)
+		ranlib(*argv);
 
 	return status;
 }
--- /dev/null
+++ b/src/cmd/scc/posix/.gitignore
@@ -1,0 +1,1 @@
+config.h
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -11,6 +11,7 @@
        armember.o \
        objfmt.o \
        coff32.o \
+       coffelf32.o \
 
 all: $(TARGET)
 
--- a/src/libmach/artraverse.c
+++ b/src/libmach/artraverse.c
@@ -17,7 +17,7 @@
 		if ((off = armember(fp, name)) <= 0)
 			return off;
 		r = (*fn)(fp, name, data);
-		if (!r)
+		if (r <= 0)
 			return r;
 
 		fsetpos(fp, &pos);
--- a/src/libmach/coff32.c
+++ b/src/libmach/coff32.c
@@ -165,7 +165,7 @@
 }
 
 static int
-mkindex(Obj *obj)
+loadsyms(Obj *obj)
 {
 	int t;
 	long i;
@@ -310,6 +310,37 @@
 }
 
 static int
+loadsections(Obj *obj, FILE *fp)
+{
+	size_t len;
+	int i;
+	FILHDR *hdr;
+	struct coff32 *coff;
+	SCNHDR *scn;
+	Section *p;
+
+	coff  = obj->data;
+	hdr = &coff->hdr;
+	scn = coff->scns;
+	for (i = 0; i < hdr->f_nscns; i++) {
+		if ((p = malloc(sizeof(*p))) == NULL)
+			return 0;
+		len = strlen(scn->s_name) + 1;
+		if ((p->name = malloc(len)) == NULL) {
+			free(p);
+			return 0;
+		}
+		memcpy(p->name, scn->s_name, len);
+		p->fp = fp;
+		p->offset = scn->s_scnptr;
+		p->size = scn->s_size;
+		p->next = obj->sections;
+		obj->sections = p->next;
+	}
+	return 1;
+}
+
+static int
 read(Obj *obj, FILE *fp)
 {
 	if (fgetpos(fp, &obj->pos))
@@ -322,8 +353,10 @@
 		goto error;
 	if (!readstr(obj, fp))
 		goto error;
-	if (!mkindex(obj))
+	if (!loadsyms(obj))
 		goto error;
+	if (!loadsections(obj, fp))
+		goto error;
 	return 0;
 
 error:
@@ -413,6 +446,12 @@
 	return 0;
 }
 
+static long
+mkindex(int type, long nsymbols, Symdef *head, FILE *fp)
+{
+	return coff32idx(BIG_ENDIAN, nsymbols, head, fp);
+}
+
 struct format objcoff32 = {
 	.probe = probe,
 	.new = new,
@@ -421,4 +460,5 @@
 	.write = write,
 	.strip = strip,
 	.size = size,
+	.index = mkindex,
 };
--- /dev/null
+++ b/src/libmach/coffelf32.c
@@ -1,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+long
+coff32idx(int order, long nsyms, Symdef *head, FILE *fp)
+{
+	long i, n;
+	size_t len;
+	Symdef *def;
+	unsigned char buff[4];
+
+	pack(order, buff, "l", nsyms);
+	fwrite(buff, 4, 1, fp);
+	n = 4;
+
+	for (def = head; def; def = def->next) {
+		pack(order, buff, "l", (long) def->offset);
+		fwrite(buff, 4, 1, fp);
+		n += 4;
+	}
+
+	for (def = head; def; def = def->next) {
+		len = strlen(def->name);
+		fwrite(def->name, len+1, 1, fp);
+		n += len;
+	}
+
+	return fflush(fp) == EOF ? -1 : n;
+}
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -37,10 +37,14 @@
                 unsigned long long *,
                 unsigned long long *,
                 unsigned long long *);
+	long (*index)(int type, long nsyms, Symdef *def, FILE *fp);
 };
 
 extern int pack(int order, unsigned char *dst, char *fmt, ...);
 extern int unpack(int order, unsigned char *src, char *fmt, ...);
+
+/* idx functions */
+extern long coff32idx(int order, long nsyms, Symdef *def, FILE *fp);
 
 
 /* globals */
--- a/src/libmach/object.c
+++ b/src/libmach/object.c
@@ -121,6 +121,7 @@
 
 	obj->type = type;
 	obj->head = NULL;
+	obj->sections = NULL;
 	memset(obj->htab, 0, sizeof(obj->htab));
 
 	op = objfmt[fmt];
@@ -211,6 +212,19 @@
 		return -1;
 	op = objfmt[fmt];
 	return (*op->size)(obj, text, data, bss);
+}
+
+long
+arindex(int type, long nsyms, Symdef *head, FILE *fp)
+{
+	int fmt;
+	struct format *op;
+
+	fmt = FORMAT(type);
+	if (fmt >= NFORMATS)
+		return -1;
+	op = objfmt[fmt];
+	return (*op->index)(type, nsyms, head, fp);
 }
 
 int