ref: 2d1b151c900071e5362b23e2e673c3cc0221c166
parent: 26e92fcaa069bac388b1d0571e14957e012fdc4d
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Aug 30 07:24:40 EDT 2019
[libmach] Add loadmap() This function creates a map with all the information needed to map a section to a specific file and offset.
--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -3,6 +3,7 @@
typedef struct symbol Symbol;
typedef struct objops Objops;
typedef struct obj Obj;
+typedef struct map Map;
enum sectype {
SREAD = 1 << 0,
@@ -61,12 +62,15 @@
extern void delobj(Obj *obj);
extern int readobj(Obj *obj, FILE *fp);
-extern int writeobj(Obj *obj, FILE *fp);
+extern int writeobj(Obj *obj, Map *map, FILE *fp);
extern int strip(Obj *obj);
extern int pc2line(Obj *obj, unsigned long long pc, char *fname, int *ln);
extern int rebase(Obj *obj, int index, unsigned long long offset);
-extern int mapsec(Obj *obj, int idx, FILE *fp);
+
+extern Map *loadmap(Obj *obj, FILE *fp);
+extern Map *newmap(int n, FILE *fp);
+extern int setmap(Map *map, char *name, long off);
extern Symbol *getsym(Obj *obj, int *index, Symbol *sym);
extern Section *getsec(Obj *obj, int *index, Section *sec);
--- a/src/cmd/ld/section.c
+++ b/src/cmd/ld/section.c
@@ -12,6 +12,10 @@
#define NR_SECTION 32
+/*
+ * struct sectab has a Section as first field because
+ * the code is going to cast from the sections to the tab.
+ */
struct sectab {
Section sec;
FILE *tmpfp;
@@ -88,10 +92,12 @@
exit(EXIT_FAILURE);
}
+/*
if (mapsec(obj, osec->index, sp->tmpfp) < 0) {
error(strerror(errno));
return;
}
+*/
sec->size += osec->size;
}
--- a/src/cmd/ld/symbol.c
+++ b/src/cmd/ld/symbol.c
@@ -12,9 +12,8 @@
#define NR_SYMBOL 128
/*
- * struct symtab and struct sectab have a Symbol and a
- * Section as first field because the code is going to
- * cast from the symbols and the sections to the tab.
+ * struct symtab has a Symbol as first field because
+ * the code is going to cast from the symbols to the tab.
*/
struct symtab {
Symbol sym;
--- a/src/cmd/strip.c
+++ b/src/cmd/strip.c
@@ -29,51 +29,57 @@
static void
doit(char *fname)
{
- int type;
+ int type;;
size_t r;
- FILE *fp;
+ FILE *src, *dst;
+ Map *map;
Obj *obj;
+ errno = 0;
filename = fname;
- if ((fp = fopen(fname, "rb")) == NULL)
+ r = snprintf(tmpname, sizeof(tmpname), "%s.tmp", fname);
+ if (r >= sizeof(tmpname)) {
+ error("%s: name too long", fname);
+ return;
+ }
+ if ((src = fopen(fname, "rb")) == NULL)
+ goto err0;
+ if ((type = objtype(src, NULL)) < 0)
goto err1;
- if ((type = objtype(fp, NULL)) < 0)
- goto err2;
if ((obj = newobj(type)) == NULL)
+ goto err1;
+ if (readobj(obj, src) < 0)
goto err2;
- if (readobj(obj, fp) < 0)
+ if ((map = loadmap(obj, src)) == NULL)
goto err3;
- fclose(fp);
-
if (strip(obj) < 0)
- goto err2;
-
- r = snprintf(tmpname, sizeof(tmpname), "%s.tmp", fname);
- if (r >= sizeof(tmpname)) {
- errno = ERANGE;
- goto err2;
- }
-
- if ((fp = fopen(tmpname, "wb")) == NULL)
- goto err2;
-
- if (writeobj(obj, fp) < 0)
goto err3;
- fclose(fp);
- delobj(obj);
-
+ if ((dst = fopen(tmpname, "wb")) == NULL)
+ goto err3;
+ if (writeobj(obj, map, dst) < 0)
+ goto err5;
+ if (fclose(dst) == EOF)
+ goto err4;
+ if (remove(fname) == EOF)
+ goto err4;
if (rename(tmpname, fname) == EOF)
- goto err1;
+ goto err4;
- return;
+ goto err3;
+err5:
+ fclose(dst);
+err4:
+ remove(tmpname);
err3:
- fclose(fp);
+ free(map);
err2:
delobj(obj);
err1:
- error(strerror(errno));
- remove(tmpname);
+ fclose(src);
+err0:
+ if (errno)
+ error(strerror(errno));
}
static void
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -17,7 +17,9 @@
getsym.o\
getsec.o\
rebase.o\
- mapsec.o\
+ loadmap.o\
+ newmap.o\
+ setmap.o\
strip.o\
pc2line.o\
pack.o\
--- a/src/libmach/coff32/Makefile
+++ b/src/libmach/coff32/Makefile
@@ -18,6 +18,7 @@
coff32pc2line.o \
coff32getsym.o \
coff32getsec.o \
+ coff32loadmap.o\
all: $(OBJS)
--- a/src/libmach/coff32/coff32.c
+++ b/src/libmach/coff32/coff32.c
@@ -17,4 +17,5 @@
.write = coff32write,
.getsym = coff32getsym,
.getsec = coff32getsec,
+ .loadmap = coff32loadmap,
};
--- a/src/libmach/coff32/coff32.h
+++ b/src/libmach/coff32/coff32.h
@@ -41,3 +41,4 @@
extern Symbol *coff32getsym(Obj *obj, int *idx, Symbol *sym);
extern Section *coff32getsec(Obj *obj, int *idx, Section *sec);
+extern Map *coff32loadmap(Obj *obj, FILE *fp);
--- /dev/null
+++ b/src/libmach/coff32/coff32loadmap.c
@@ -1,0 +1,25 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "../libmach.h"
+#include "coff32.h"
+
+Map *
+coff32loadmap(Obj *obj, FILE *fp)
+{
+ long i;
+ Map *map;
+ SCNHDR *scn;
+ struct coff32 *coff = obj->data;
+ FILHDR *hdr = &coff->hdr;
+ long 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);
+
+ return map;
+}
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -36,11 +36,23 @@
int (*strip)(Obj *obj);
int (*pc2line)(Obj *, unsigned long long , char *, int *);
+ Map *(*loadmap)(Obj *obj, FILE *fp);
+
Symbol *(*getsym)(Obj *obj, int *index, Symbol *sym);
Section *(*getsec)(Obj *obj, int *index, Section *sec);
int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp);
int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp);
+};
+
+
+struct map {
+ int n;
+ struct mapsec {
+ char *name;
+ FILE *fp;
+ long offset;
+ } sec[];
};
/* common functions */
--- /dev/null
+++ b/src/libmach/loadmap.c
@@ -1,0 +1,11 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+Map *
+loadmap(Obj *obj, FILE *fp)
+{
+ return (*obj->ops->loadmap)(obj, fp);
+}
--- a/src/libmach/mapsec.c
+++ /dev/null
@@ -1,11 +1,0 @@
-#include <stdio.h>
-
-#include <scc/mach.h>
-
-#include "libmach.h"
-
-int
-mapsec(Obj *obj, int idx, FILE *fp)
-{
- return 0;
-}
--- /dev/null
+++ b/src/libmach/newmap.c
@@ -1,0 +1,39 @@
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+Map *
+newmap(int n, FILE *fp)
+{
+ size_t siz, vsiz;
+ struct mapsec *p;
+ Map *map;
+
+ siz = sizeof(*map);
+ if (n > SIZE_MAX/sizeof(struct mapsec))
+ goto out_range;
+
+ vsiz = n * sizeof(struct mapsec);
+ if (vsiz > SIZE_MAX - siz)
+ goto out_range;
+
+ if ((map = malloc(siz + vsiz)) == NULL)
+ return NULL;
+
+ map->n = n;
+ memset(map->sec, 0, vsiz);
+
+ for (p = map->sec; n--; ++p)
+ p->fp = fp;
+ return map;
+
+out_range:
+ errno = ERANGE;
+ return NULL;
+}
--- /dev/null
+++ b/src/libmach/setmap.c
@@ -1,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+int
+setmap(Map *map, char *name, long off)
+{
+ int n;
+ struct mapsec *sec;
+
+ n = map->n;
+ for (sec = map->sec; n--; sec++) {
+ if (sec->name && strcmp(sec->name, name) == 0)
+ goto found;
+ }
+
+ 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
@@ -5,7 +5,7 @@
#include "libmach.h"
int
-writeobj(Obj *obj, FILE *fp)
+writeobj(Obj *obj, Map *map, FILE *fp)
{
return (obj->ops->write)(obj, fp);
}
\ No newline at end of file