commit 7e58afa199c101cf286652c305ba91e63a8fc40c
parent 089001cf022662342949760e254ee19f09123350
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 21 Mar 2024 07:43:35 +0100
libmach/coff32: Add setsym()
This function is used to add a symbol to an object. Currently only
coff32 is supported and there are a lot of things that have to be
fixed, like for example the auxiliary entries.
Diffstat:
8 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h
@@ -122,5 +122,6 @@ extern int rebase(Obj *, int, unsigned long long);
extern int findsec(Map *, char *);
extern Symbol *getsym(Obj *, int *, Symbol *);
+extern Symbol *setsym(Obj *, int *, Symbol *);
extern Section *getsec(Obj *, int *, Section *);
extern Section *setsec(Obj *, int *, Section *);
diff --git a/src/libmach/Makefile b/src/libmach/Makefile
@@ -32,6 +32,7 @@ OBJS =\
setindex.o\
setmap.o\
setsec.o\
+ setsym.o\
strip.o\
unpack.o\
writeobj.o\
diff --git a/src/libmach/coff32/coff32.c b/src/libmach/coff32/coff32.c
@@ -17,6 +17,7 @@ struct objops coff32 = {
.del = coff32del,
.write = coff32write,
.getsym = coff32getsym,
+ .setsym = coff32setsym,
.getsec = coff32getsec,
.setsec = coff32setsec,
.loadmap = coff32loadmap,
diff --git a/src/libmach/coff32/coff32.h b/src/libmach/coff32/coff32.h
@@ -40,6 +40,7 @@ extern int coff32xsetidx(int, long , char *[], long[], FILE *);
extern int coff32xgetidx(int, long *, char ***, long **, FILE *);
extern Symbol *coff32getsym(Obj *, int *, Symbol *);
+extern Symbol *coff32setsym(Obj *, int *, Symbol *);
extern Section *coff32getsec(Obj *, int *, Section *);
extern Section *coff32setsec(Obj *, int *, Section *);
extern Map *coff32loadmap(Obj *, FILE *);
diff --git a/src/libmach/coff32/coff32setsym.c b/src/libmach/coff32/coff32setsym.c
@@ -0,0 +1,114 @@
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/mach.h>
+
+#include "../libmach.h"
+#include "coff32.h"
+
+static int
+defent(Coff32 *coff, SYMENT *ent, Symbol *sym)
+{
+ ent->n_scnum = sym->section + 1;
+
+ switch (sym->type) {
+ case 'N':
+ /*
+ * TODO: What happens with .indent ?
+ * look if the section is STYP_INFO
+ */
+ ent->n_scnum = N_DEBUG;
+ break;
+ case 'A':
+ ent->n_sclass = C_EXT;
+ case 'a':
+ ent->n_scnum = N_ABS;
+ break;
+ case 'C':
+ case 'U':
+ ent->n_scnum = N_UNDEF;
+ break;
+ case 'T':
+ case 'D':
+ case 'B':
+ case 'R':
+ ent->n_sclass = C_EXT;
+ break;
+ case 't':
+ case 'd':
+ case 'b':
+ case 'r':
+ ent->n_sclass = C_STAT;
+ break;
+ case '?':
+ default:
+ /* TODO */
+ return -1;
+ }
+
+ return 0;
+}
+
+static char *
+symname(Coff32 *coff, SYMENT *ent, Symbol *sym)
+{
+ char *p;
+ unsigned long siz = strlen(sym->name);
+
+ if (siz < SYMNMLEN)
+ return strncpy(ent->n_name, sym->name, SYMNMLEN);
+
+ if (coff->strsiz > ULONG_MAX - siz - 1)
+ return NULL;
+
+ siz += coff->strsiz + 1;
+ if ((p = realloc(coff->strtbl, siz)) == NULL)
+ return NULL;
+ coff->strtbl = p;
+
+ ent->n_zeroes = 0;
+ ent->n_offset = coff->strsiz;
+ coff->strsiz += siz;
+ return strcpy(&coff->strtbl[ent->n_offset], sym->name);
+}
+
+Symbol *
+coff32setsym(Obj *obj, int *idx, Symbol *sym)
+{
+ int n = *idx;
+ SYMENT *ent, *p;
+ Coff32 *coff = obj->data;
+ FILHDR *hdr = &coff->hdr;
+
+ hdr->f_flags |= F_SYMS;
+ if (n >= coff->hdr.f_nsyms) {
+ if (n > LONG_MAX-1)
+ return NULL;
+ if ((p = realloc(coff->ents, (n+1) * sizeof(*p))) == NULL)
+ return NULL;
+ coff->ents = p;
+ coff->hdr.f_nsyms = n+1;
+ }
+ ent = &coff->ents[n];
+ if (!symname(coff, ent, sym))
+ return NULL;
+
+ ent->n_value = sym->value;
+ if (defent(coff, ent, sym) < 0)
+ return NULL;
+
+ /*
+ * TODO:
+ * sym->type
+ * sym->stype
+ */
+ ent->n_type = 0; /* TODO: debug information */
+ ent->n_sclass = 0; /* TODO: debug information */
+ ent->n_numaux = 0; /* TODO: debug information */
+
+ *idx += ent->n_numaux;
+
+ return sym;
+}
diff --git a/src/libmach/coff32/rules.mk b/src/libmach/coff32/rules.mk
@@ -16,6 +16,7 @@ COFF32_OBJS =\
coff32/coff32getidx.o \
coff32/coff32pc2line.o \
coff32/coff32getsym.o \
+ coff32/coff32setsym.o \
coff32/coff32getsec.o \
coff32/coff32setsec.o \
coff32/coff32loadmap.o\
diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h
@@ -48,6 +48,7 @@ struct objops {
Map *(*loadmap)(Obj *, FILE *);
Symbol *(*getsym)(Obj *, int *, Symbol *);
+ Symbol *(*setsym)(Obj *, int *, Symbol *);
Section *(*getsec)(Obj *, int *, Section *);
Section *(*setsec)(Obj *, int *, Section *);
diff --git a/src/libmach/setsym.c b/src/libmach/setsym.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+Symbol *
+setsym(Obj *obj, int *index, Symbol *sym)
+{
+ return (*obj->ops->setsym)(obj, index, sym);
+}