scc

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

commit 5fb4bf82c962c831624ee7d1c1c1e75bf67291d8
parent a5b21461738ce6ca8c80071ef594e931c77ffbe4
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  5 Mar 2024 09:35:45 +0100

libmach: Add setsec()

This function allows to inject a section in the object
described by the generic section interface. As there is
not a perfect mach between the generic struct and the
object struct then some heuristics have to be applied
to be able to transform between then. Anyway, there will
be cases when the assembler and the loader will have to
uses directly object types.

Diffstat:
Minclude/scc/scc/mach.h | 1+
Msrc/cmd/as/as.h | 2+-
Msrc/cmd/as/ins.c | 2+-
Msrc/cmd/as/symbol.c | 14+++++++-------
Msrc/libmach/Makefile | 1+
Msrc/libmach/coff32/coff32.c | 1+
Msrc/libmach/coff32/coff32.h | 1+
Asrc/libmach/coff32/coff32setsec.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/coff32/rules.mk | 1+
Msrc/libmach/libmach.h | 1+
Asrc/libmach/setsec.c | 11+++++++++++
11 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -123,3 +123,4 @@ extern int findsec(Map *, char *); extern Symbol *getsym(Obj *, int *, Symbol *); extern Section *getsec(Obj *, int *, Section *); +extern Section *setsec(Obj *, int *, Section *); diff --git a/src/cmd/as/as.h b/src/cmd/as/as.h @@ -113,7 +113,7 @@ union yylval { extern void cleansecs(void); extern void isecs(void); extern void emit(char *, int); -extern Section *setsec(char *, char *); +extern Section *defsec(char *, char *); extern Symbol *tmpsym(TUINT); extern void killtmp(void); extern int toobig(Node *, int); diff --git a/src/cmd/as/ins.c b/src/cmd/as/ins.c @@ -189,7 +189,7 @@ section(Op *op, Node **args) if (args[1]) attr = args[1]->sym->name; - setsec(sym->name, attr); + defsec(sym->name, attr); } void diff --git a/src/cmd/as/symbol.c b/src/cmd/as/symbol.c @@ -260,7 +260,7 @@ secflags(char *attr) } static Section * -newsect(Symbol *sym) +newsec(Symbol *sym) { Section *sec; struct lsection *lsec; @@ -294,7 +294,7 @@ newsect(Symbol *sym) } Section * -setsec(char *name, char *attr) +defsec(char *name, char *attr) { struct lsymbol *lsym; Section *sec; @@ -308,7 +308,7 @@ setsec(char *name, char *attr) lsym = (struct lsymbol *) sym; sec = lsym->sec; if (sec == NULL) { - sec = newsect(sym); + sec = newsec(sym); lsym->sec = sec; sym->section = sec->index; sym->flags = FSECT; @@ -326,10 +326,10 @@ isecs(void) exit(EXIT_FAILURE); } - sabs = setsec(".abs", "rwxa"); - sbss = setsec(".bss", "rw"); - sdata = setsec(".data", "rwc"); - stext = setsec(".text", "rxc"); + sabs = defsec(".abs", "rwxa"); + sbss = defsec(".bss", "rw"); + sdata = defsec(".data", "rwc"); + stext = defsec(".text", "rxc"); } void diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -31,6 +31,7 @@ OBJS =\ rebase.o\ setindex.o\ setmap.o\ + setsec.o\ strip.o\ unpack.o\ writeobj.o\ diff --git a/src/libmach/coff32/coff32.c b/src/libmach/coff32/coff32.c @@ -18,5 +18,6 @@ struct objops coff32 = { .write = coff32write, .getsym = coff32getsym, .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 coff32xgetidx(int, long *, char ***, long **, FILE *); extern Symbol *coff32getsym(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/coff32setsec.c b/src/libmach/coff32/coff32setsec.c @@ -0,0 +1,61 @@ +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "coff32.h" + +Section * +coff32setsec(Obj *obj, int *idx, Section *sec) +{ + long flags, n = *idx; + SCNHDR *scn; + Coff32 *coff = obj->data; + FILHDR *hdr = &coff->hdr; + + switch (sec->type) { + case 'D': + flags = (sec->flags & SWRITE) ? STYP_DATA : STYP_RDATA; + break; + case 'T': + flags = STYP_TEXT; + break; + case 'B': + flags = STYP_BSS; + break; + case 'N': + case '?': + default: + return NULL; + } + + if (strlen(sec->name) >= SCNNMLEN) + return NULL; + + if (n >= hdr->f_nscns) { + if (n > SHRT_MAX - 1) + return NULL; + scn = realloc(coff->scns, (n+1) * sizeof(SCNHDR)); + if (!scn) + return NULL; + coff->scns = scn; + hdr->f_nscns = n + 1; + } + scn = &coff->scns[n]; + + strncpy(scn->s_name, sec->name, SCNNMLEN); + scn->s_paddr = 0; + scn->s_vaddr = sec->base; + scn->s_size = sec->size; + scn->s_scnptr = 0; + scn->s_relptr = 0; + scn->s_lnnoptr = 0; + scn->s_nrelloc = 0; + scn->s_nlnno = 0; + scn->s_flags = flags; + + return sec; +} diff --git a/src/libmach/coff32/rules.mk b/src/libmach/coff32/rules.mk @@ -17,4 +17,5 @@ COFF32_OBJS =\ coff32/coff32pc2line.o \ coff32/coff32getsym.o \ coff32/coff32getsec.o \ + coff32/coff32setsec.o \ coff32/coff32loadmap.o\ diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -49,6 +49,7 @@ struct objops { Symbol *(*getsym)(Obj *, int *, Symbol *); Section *(*getsec)(Obj *, int *, Section *); + Section *(*setsec)(Obj *, int *, Section *); int (*setidx)(long, char *[], long[], FILE *); int (*getidx)(long *, char ***, long **, FILE *); diff --git a/src/libmach/setsec.c b/src/libmach/setsec.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +Section * +setsec(Obj *obj, int *idx, Section *sec) +{ + return (*obj->ops->setsec)(obj, idx, sec); +}