shithub: scc

Download patch

ref: 206003ef2ae93895c7c7d8b9d4ad0972129fbe42
parent: 75e3bd0450527acabecfad8dd1da8f335991805c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 24 11:07:50 EST 2017

[nm] Add support for object files inside ar files

This is an interesting feature of nm, it deals with ar and
object files.

--- a/nm/main.c
+++ b/nm/main.c
@@ -23,12 +23,21 @@
 myrofile(char *fname, FILE *fp)
 {
 	char magic[MYROMAGIC_SIZ];
+	fpos_t pos;
 
-	rewind(fp);
+	if (fgetpos(fp, &pos) < 0)
+		fdie(fname);
+
 	fread(magic, sizeof(magic), 1, fp);
 	if (ferror(fp))
 		fdie(fname);
-	return strncmp(magic, MYROMAGIC, MYROMAGIC_SIZ) == 0;
+
+	if (!strncmp(magic, MYROMAGIC, MYROMAGIC_SIZ))
+		return 1;
+
+	if (fsetpos(fp, &pos) < 0)
+		fdie(fname);
+	return 0;
 }
 
 static int
@@ -35,12 +44,18 @@
 arfile(char *fname, FILE *fp)
 {
 	char magic[ARMAGIC_SIZ];
+	fpos_t pos;
 
-	rewind(fp);
 	fread(magic, sizeof(magic), 1, fp);
 	if (ferror(fp))
 		fdie(fname);
-	return strncmp(magic, ARMAGIC, ARMAGIC_SIZ) == 0;
+
+	if (!strncmp(magic, ARMAGIC, ARMAGIC_SIZ))
+		return 1;
+
+	if (fsetpos(fp, &pos) < 0)
+		fdie(fname);
+	return 0;
 }
 
 static void
@@ -49,10 +64,9 @@
 	struct myrohdr hdr;
 	size_t n;
 
-	rewind(fp);
-	if (rdmyrohdr(fp, &hdr) == EOF)
+	if (rdmyrohdr(fp, &hdr) < 0)
 		fdie(fname);
-	if (strncmp(hdr.magic, MYROMAGIC, MYROMAGIC_SIZ))
+
 	n = hdr.symsize / MYROSYM_SIZ;
 	if (n == 0) {
 		fprintf(stderr, "nm: %s: no name list\n", member);
@@ -60,11 +74,26 @@
 	}
 }
 
+static void
+ar(char *fname, FILE *fp)
+{
+	struct arhdr hdr;
+
+	while (rdarhdr(fp, &hdr) != EOF) {
+		if (myrofile(fname, fp)) {
+			nm(fname, hdr.name, fp);
+		} else {
+			fprintf(stderr,
+			        "nm: skipping member %s in archive %s\n",
+			        hdr.name, fname);
+		}
+	}
+}
+
 void
 doit(char *fname)
 {
 	FILE *fp;
-	char magic[20];
 
 	if ((fp = fopen(fname, "rb")) == NULL)
 		fdie(fname);
@@ -72,9 +101,9 @@
 	if (myrofile(fname, fp))
 		nm(fname, fname, fp);
 	else if (arfile(fname, fp))
-		/* run over the members */;
+		ar(fname, fp);
 	else
-		die("nm: %s: File format not recognized", fname);
+		fprintf(stderr, "nm: %s: File format not recognized", fname);
 
 	if (fclose(fp) == EOF)
 		fdie(fname);