scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

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:
Minclude/scc/scc/mach.h | 1+
Msrc/libmach/Makefile | 1+
Msrc/libmach/coff32/coff32.c | 1+
Msrc/libmach/coff32/coff32.h | 1+
Asrc/libmach/coff32/coff32setsym.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/coff32/rules.mk | 1+
Msrc/libmach/libmach.h | 1+
Asrc/libmach/setsym.c | 11+++++++++++
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); +}