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