shithub: scc

Download patch

ref: da8a8c7392b7176a11fd7eab84d6f9b2d27ae590
parent: 4f93908533138a0efbdffd880003438f98af736e
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Aug 9 19:31:07 EDT 2019

[ld] Make undef() private

Undef() was public only because we had to parse the options
in main, but the actions were totally private to the 1st pass.
This patch makes pass1 to rescan the arguments to locate
the options that are interesting for it, and giving a positional
value to -u. -U was evaluated before scanning any file, but ater
this change it is evaluated just where it is found.

--- a/src/cmd/ld/ld.h
+++ b/src/cmd/ld/ld.h
@@ -5,11 +5,6 @@
 typedef struct symbol Symbol;
 typedef struct section Section;
 
-enum {
-	OUTLIB,
-	INLIB,
-};
-
 struct section {
 	char *name;
 	unsigned long base;
@@ -36,7 +31,6 @@
 
 /* passes */
 extern void pass1(int argc, char *argv[]);
-extern Symbol *undef(char *name);
 extern void pass2(int argc, char *argv[]);
 extern void pass3(int argc, char *argv[]);
 extern void pass4(int argc, char *argv[]);
--- a/src/cmd/ld/main.c
+++ b/src/cmd/ld/main.c
@@ -92,16 +92,15 @@
 int
 main(int argc, char *argv[])
 {
-	char *cp, **p;
+	int files = 0;
+	char *cp, *arg, **ap;
 
-	for (--argc; *++argv; --argc) {
-		if (argv[0][0] != '-' || argv[0][1] == 'l')
-			break;
-		if (argv[0][1] == '-') {
-			--argc, ++argv;
-			break;
+	for (ap = argv+1; *ap; ++ap) {
+		if (ap[0][0] != '-') {
+			files = 1;
+			continue;
 		}
-		for (cp = &argv[0][1]; *cp; ++cp) {
+		for (cp = &ap[0][1]; *cp; ++cp) {
 			switch (*cp) {
 			case 's':
 				sflag = 1;
@@ -122,47 +121,50 @@
 			case 'n':
 				/* TODO */
 				break;
-			case 'L':
-				if (argc == 0)
-					goto usage;
-				++argv, --argc;
-				Lpath(*argv);
-				break;
 			case 'u':
-				if (argc == 0)
+			case 'l':
+				arg = (cp[1]) ? cp+1 : *++ap;
+				if (!arg)
 					goto usage;
-				++argv, --argc;
-				undef(*argv);
-				break;
+				goto next_arg;
+			case 'L':
+				arg = (cp[1]) ? cp+1 : *++ap;
+				if (!arg)
+					goto usage;
+				Lpath(arg);
+				goto next_arg;
 			case 'o':
-				if (argc == 0)
+				arg = (cp[1]) ? cp+1 : *++ap;
+				if (!arg)
 					goto usage;
-				++argv, --argc;
-				output = *argv;
-				break;
+				output = arg;
+				goto next_arg;
 			case 'e':
-				if (argc == 0)
+				arg = (cp[1]) ? cp+1 : *++ap;
+				if (!arg)
 					goto usage;
-				++argv, --argc;
-				entry = *argv;
-				break;
+				entry = arg;
+				goto next_arg;
 			case 'D':
-				if (argc == 0)
+				arg = (cp[1]) ? cp+1 : *++ap;
+				if (!arg)
 					goto usage;
-				++argv, --argc;
-				Dflag = *argv;
-				break;
+				Dflag = arg;
+				goto next_arg;
 			default:
 			usage:
 				usage();
 			}
 		}
+
+		next_arg:
+			continue;
 	}
 
-	if (argc == 0)
+	if (!files)
 		usage();
-	atexit(cleanup);
 
+	atexit(cleanup);
 	ld(argc, argv);
 
 	return status;
--- a/src/cmd/ld/pass1.c
+++ b/src/cmd/ld/pass1.c
@@ -10,6 +10,11 @@
 
 #include "ld.h"
 
+enum {
+	OUTLIB,
+	INLIB,
+};
+
 static int bintype = -1;
 static Symbol refhead = {
 	.next = &refhead,
@@ -42,7 +47,7 @@
 	return sym;
 }
 
-Symbol *
+static Symbol *
 undef(char *name)
 {
 	Symbol *sym = install(name);
@@ -176,9 +181,10 @@
 
 	/*
 	 * we add the object to the list of objects
-	 * if we are not in a library without index,
-	 * or in that case if the library defines
-	 * some symbol needed.
+	 * if we are in an object file. If we are in
+	 * a library (without index) then we check
+	 * if the object defines some symbol in the
+	 * undefined list.
 	 */
 	if (!inlib || defasym(obj)) {
 		addobj(obj, fp);
@@ -203,8 +209,7 @@
 		return;
 	}
 
-	for (added = 1; moreundef() && added; ) {
-		added = 0;
+	for (added = 0; moreundef(); added = 0) {
 		for (dp = def; dp; dp = dp->next) {
 			sym = lookup(dp->name);
 			if (!sym || sym->def)
@@ -228,6 +233,8 @@
 			newobject(fp, t, OUTLIB);
 			added = 1;
 		}
+		if (!added)
+			break;
 	}
 clean:
 	free(def);
@@ -319,6 +326,24 @@
 	return NULL;
 }
 
+static void
+load(char *name)
+{
+	int t;
+	FILE *fp;
+	char buff[FILENAME_MAX];
+
+	if ((fp = openfile(name, buff)) == NULL)
+		return;
+
+	if ((t = objtype(fp, NULL)) != -1)
+		newobject(fp, t, OUTLIB);
+	else if (archive(fp))
+		newlibrary(fp);
+	else
+		error("bad format");
+}
+
 /*
  * Get the list of object files that are going to be linked
  */
@@ -325,20 +350,25 @@
 void
 pass1(int argc, char *argv[])
 {
-	int t;
-	FILE *fp;
-	char buff[FILENAME_MAX];
+	char **ap, *cp, *arg;
 
-	for ( ; *argv; ++argv) {
-		if ((fp = openfile(*argv, buff)) == NULL)
+	for (ap = argv+1; *ap; ++ap) {
+		if (ap[0][0] != '-') {
+			load(*ap);
 			continue;
-
-		if ((t = objtype(fp, NULL)) != -1)
-			newobject(fp, t, OUTLIB);
-		else if (archive(fp))
-			newlibrary(fp);
-		else
-			error("bad format");
+		}
+		for (cp = &ap[0][1]; *cp; ++cp) {
+			switch (*cp) {
+			case 'l':
+				arg = (cp[1]) ? cp+1 : *++ap;
+				load(arg);
+				continue;
+			case 'u':
+				arg = (cp[1]) ? cp+1 : *++ap;
+				undef(arg);
+				continue;
+			}
+		}
 	}
 
 	if (moreundef()) {