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);
+}