shithub: scc

Download patch

ref: a7553c3dc80894ae69ff122d45725131c9606231
parent: bf06512e77f04190d1f1ed54faced3ee8f1097d5
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Sep 1 08:30:55 EDT 2019

[libmach] Add findsec()

This function returns the index of the Mapsec inside of a
Map.

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -4,6 +4,7 @@
 typedef struct objops Objops;
 typedef struct obj Obj;
 typedef struct map Map;
+typedef struct mapsec Mapsec;
 
 enum sectype {
 	SREAD   = 1 << 0,
@@ -70,7 +71,13 @@
 
 extern Map *loadmap(Obj *obj, FILE *fp);
 extern Map *newmap(int n, FILE *fp);
-extern int setmap(Map *map, char *name, long off);
+extern int findsec(Map *map, char *name);
+extern int setmap(Map *map,
+                  char *name,
+                  FILE *fp,
+                  unsigned long long begin,
+                  unsigned long long end,
+                  long off);
 
 extern Symbol *getsym(Obj *obj, int *index, Symbol *sym);
 extern Section *getsec(Obj *obj, int *index, Section *sec);
--- a/src/cmd/strip.c
+++ b/src/cmd/strip.c
@@ -42,28 +42,50 @@
 		error("%s: name too long", fname);
 		return;
 	}
-	if ((src = fopen(fname, "rb")) == NULL)
+	if ((src = fopen(fname, "rb")) == NULL) {
+		error("opening src file");
 		goto err0;
-	if ((type = objtype(src, NULL)) < 0)
+	}
+	if ((type = objtype(src, NULL)) < 0) {
+		error("getting object type");
 		goto err1;
-	if ((obj = newobj(type)) == NULL)
+	}
+	if ((obj = newobj(type)) == NULL) {
+		error("creating object");
 		goto err1;
-	if (readobj(obj, src) < 0)
+	}
+	if (readobj(obj, src) < 0) {
+		error("reading object");
 		goto err2;
-	if ((map = loadmap(obj, src)) == NULL)
+	}
+	if ((map = loadmap(obj, src)) == NULL) {
+		error("loading map");
 		goto err3;
-	if (strip(obj) < 0)
+	}
+	if (strip(obj) < 0) {
+		error("stripping");
 		goto err3;
-	if ((dst = fopen(tmpname, "wb")) == NULL)
+	}
+	if ((dst = fopen(tmpname, "wb")) == NULL) {
+		error("opening dst");
 		goto err3;
-	if (writeobj(obj, map, dst) < 0)
+	}
+	if (writeobj(obj, map, dst) < 0) {
+		error("writing object");
 		goto err5;
-	if (fclose(dst) == EOF)
+	}
+	if (fclose(dst) == EOF) {
+		error("closing dst");
 		goto err4;
-	if (remove(fname) == EOF)
+	}
+	if (remove(fname) == EOF) {
+		error("removing fname");
 		goto err4;
-	if (rename(tmpname, fname) == EOF)
+	}
+	if (rename(tmpname, fname) == EOF) {
+		error("rename fname");
 		goto err4;
+	}
 
 	goto err3;
 
@@ -78,8 +100,7 @@
 err1:
 	fclose(src);
 err0:
-	if (errno)
-		error(strerror(errno));
+	error("cannot strip it");
 }
 
 static void
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -20,6 +20,7 @@
 	loadmap.o\
 	newmap.o\
 	setmap.o\
+	findsec.o\
 	strip.o\
 	pc2line.o\
 	pack.o\
--- a/src/libmach/coff32/coff32.h
+++ b/src/libmach/coff32/coff32.h
@@ -31,7 +31,7 @@
 extern int coff32pc2line(Obj *, unsigned long long , char *, int *);
 extern int coff32strip(Obj *obj);
 extern void coff32del(Obj *obj);
-extern int coff32write(Obj *obj, FILE *fp);
+extern int coff32write(Obj *obj, Map * map, FILE *fp);
 extern int coff32probe(unsigned char *buf, char **name);
 
 extern int coff32xsetidx(int order,
--- a/src/libmach/coff32/coff32loadmap.c
+++ b/src/libmach/coff32/coff32loadmap.c
@@ -10,16 +10,22 @@
 {
 	long i;
 	Map *map;
+	long nsec;
 	SCNHDR *scn;
 	struct coff32 *coff = obj->data;
 	FILHDR *hdr = &coff->hdr;
-	long nsec = hdr->f_nscns;
 
+	nsec = hdr->f_nscns;
 	if ((map = newmap(nsec, fp)) == NULL)
 		return NULL;
 
-	for (scn = coff->scns; nsec--; ++scn)
-		setmap(map, scn->s_name, obj->pos + scn->s_scnptr);
+	for (scn = coff->scns; nsec--; ++scn) {
+		unsigned long o = obj->pos + scn->s_scnptr;
+		unsigned long long b = scn->s_paddr;
+		unsigned long long e = b + scn->s_size;
+
+		setmap(map, scn->s_name, fp, b, e, o);
+	}
 
 	return map;
 }
--- a/src/libmach/coff32/coff32write.c
+++ b/src/libmach/coff32/coff32write.c
@@ -273,15 +273,12 @@
 {
 	int i;
 	long j;
-	FILHDR *hdr;
 	LINENO *lp;
 	SCNHDR *scn;
-	struct coff32 *coff;
+	struct coff32 *coff = obj->data;
+	FILHDR *hdr = &coff->hdr;
 	unsigned char buf[LINESZ];
 
-	coff  = obj->data;
-	hdr = &coff->hdr;
-
 	if (!coff->lines)
 		return 1;
 
@@ -300,14 +297,70 @@
 	return 1;
 }
 
+static int
+writedata(Obj *obj, Map *map, FILE *fp)
+{
+	int id;
+	long nsec;
+	unsigned long long n;
+	struct coff32 *coff = obj->data;
+	FILHDR *hdr = &coff->hdr;
+	SCNHDR *scn;
+	Mapsec *sec;
+
+	nsec = hdr->f_nscns;
+	for (scn = coff->scns; nsec--; scn++) {
+		if ((id = findsec(map, scn->s_name)) < 0)
+			return 0;
+		sec = &map->sec[id];
+		fseek(sec->fp, sec->offset, SEEK_SET);
+
+		for (n = sec->end - sec->begin; n > 0; n--)
+			putc(getc(sec->fp), fp);
+	}
+
+	return !ferror(fp);
+}
+
 int
-coff32write(Obj *obj, FILE *fp)
+coff32write(Obj *obj, Map *map, FILE *fp)
 {
+	long ptr, n;
+	SCNHDR *scn;
+	struct coff32 *coff = obj->data;
+	FILHDR *hdr = &coff->hdr;
+
+	ptr = ftell(fp);
+	obj->pos = ptr;
+	ptr += FILHSZ + AOUTSZ + n*hdr->f_nscns;
+
+	n = hdr->f_nscns;
+	for (scn = coff->scns; n--; scn++) {
+		scn->s_scnptr = ptr;
+		ptr += scn->s_size;
+	}
+
+	n = hdr->f_nscns;
+	for (scn = coff->scns; n--; scn++) {
+		scn->s_relptr = ptr;
+		ptr += scn->s_nrelloc * RELSZ;
+	}
+
+	n = hdr->f_nscns;
+	for (scn = coff->scns; n--; scn++) {
+		scn->s_lnnoptr = ptr;
+		ptr += scn->s_nlnno * RELSZ;
+	}
+
+	/* and now update symbols */
+
 	if (!writehdr(obj, fp))
 		return -1;
 	if (!writeaout(obj, fp))
 		return -1;
 	if (!writescns(obj, fp))
+		return -1;
+	if (!writedata(obj, map, fp))
 		return -1;
 	if (!writereloc(obj, fp))
 		return -1;
--- /dev/null
+++ b/src/libmach/findsec.c
@@ -1,0 +1,20 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+int
+findsec(Map *map, char *name)
+{
+	int i;
+	struct mapsec *sec;
+
+	for (i = 0; i < map->sec; i++) {
+		char *s = map->sec[i].name;
+		if (s && strcmp(s, name) == 0)
+			return i;
+	}
+
+	return -1;
+}
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -31,7 +31,7 @@
 	void (*del)(Obj *obj);
 
 	int (*read)(Obj *obj, FILE *fp);
-	int (*write)(Obj *obj, FILE *fp);
+	int (*write)(Obj *obj, Map *map, FILE *fp);
 
 	int (*strip)(Obj *obj);
 	int (*pc2line)(Obj *, unsigned long long , char *, int *);
@@ -51,6 +51,8 @@
 	struct mapsec {
 		char *name;
 		FILE *fp;
+		unsigned long long begin;
+		unsigned long long end;
 		long offset;
 	} sec[];
 };
--- a/src/libmach/setmap.c
+++ b/src/libmach/setmap.c
@@ -6,28 +6,27 @@
 #include "libmach.h"
 
 int
-setmap(Map *map, char *name, long off)
+setmap(Map *map,
+       char *name,
+       FILE *fp,
+       unsigned long long begin,
+       unsigned long long end,
+       long off)
 {
 	int n;
-	struct mapsec *sec;
+	Mapsec *sec;
 
 	n = map->n;
 	for (sec = map->sec; n--; sec++) {
-		if (sec->name && strcmp(sec->name, name) == 0)
-			goto found;
+		if (!sec->name) {
+			sec->name = name;
+			sec->fp = fp,
+			sec->begin = begin;
+			sec->end = end;
+			sec->offset = off;
+			return 0;
+		}
 	}
 
-	n = map->n;
-	for (sec = map->sec; n--; sec++) {
-		if (!sec->name)
-			goto found;
-	}
-
-	/* TODO: Set some errno here */
 	return -1;
-
-found:
-	sec->name = name;
-	sec->offset = off;
-	return 0;
 }
\ No newline at end of file
--- a/src/libmach/writeobj.c
+++ b/src/libmach/writeobj.c
@@ -7,5 +7,5 @@
 int
 writeobj(Obj *obj, Map *map, FILE *fp)
 {
-	return (obj->ops->write)(obj, fp);
-}
\ No newline at end of file
+	return (obj->ops->write)(obj, map, fp);
+}