shithub: scc

Download patch

ref: 42da25d1f1b2108c6fb982129e8a749a5f5d2000
parent: 381a14fc9775e9f2cabbac45a4586f55feefc39c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Feb 10 09:05:51 EST 2019

[ld] Implement newidx()

This function is a callback called from foridx().

--- a/src/cmd/ld/main.c
+++ b/src/cmd/ld/main.c
@@ -183,7 +183,7 @@
 newobject(FILE *fp, int type, int inlib)
 {
 	Obj *obj;
-	Symbol *sym;
+	Symbol *sym, *p;
 
 	if ((obj = objnew(type)) == NULL) {
 		error("out of memory");
@@ -196,11 +196,12 @@
 	}
 
 	if (inlib) {
-		for (sym = refhead.next; sym != &refhead; sym = sym->next) {
+		p = &refhead;
+		for (sym = p->next; sym != p; sym = sym->next) {
 			if (objlookup(obj, sym->name, 0))
 				break;
 		}
-		if (sym == &refhead)
+		if (sym == p)
 			goto  delete;
 	}
 	load(obj);
@@ -217,9 +218,12 @@
 {
 	int t;
 
+	membname = data;
+
 	if ((t = objtype(fp, NULL)) == -1)
 		return 1;
 	newobject(fp, t, INLIB);
+
 	return 1;
 }
 
@@ -226,7 +230,32 @@
 static int
 newidx(Objsymdef *def, void *data)
 {
-	/* TODO */
+	int t;
+	Symbol *sym, *p;
+	FILE *fp = data;
+
+	p = &refhead;
+	if (p->next == p)
+		return 0;
+
+	for (sym = p->next; sym != p; sym = sym->next) {
+		if (strcmp(sym->name, def->name))
+			continue;
+
+		if (fseek(fp, def->offset, SEEK_SET) == EOF) {
+			error(errstr());
+			return 0;
+		}
+
+		if ((t = objtype(fp, NULL)) == -1) {
+			error("library file corrupted");
+			return 0;
+		}
+
+		newobject(fp, t, OUTLIB);
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -287,9 +316,10 @@
 	}
 
 	if (refhead.next != &refhead) {
-		Symbol *sym;
+		Symbol *sym, *p;
 
-		for (sym = refhead.next; sym != &refhead; sym = sym->next) {
+		p = &refhead;
+		for (sym = p->next; sym != p; sym = sym->next) {
 			fprintf(stderr,
 			        "ld: symbol '%s' not defined\n",
 			        sym->name);
@@ -313,11 +343,13 @@
 static void
 Lpath(char *path)
 {
-	char **bp;
+	char **bp, **base, **end;
 
-	for (bp = syslibs; bp < &syslibs[MAX_LIB_PATHS] && *bp; ++bp)
+	base = syslibs;
+	end = &syslibs[MAX_LIB_PATHS];
+	for (bp = base; bp < end && *bp; ++bp)
 		;
-	if (bp == &syslibs[MAX_LIB_PATHS]) {
+	if (bp == end) {
 		fputs("ld: too many -L options\n", stderr);
 		exit(1);
 	}