Home
libmach: Add setsec() - scc - simple c99 compiler HTML git clone git://git.simple-cc.org/scc DIR Log DIR Files DIR Refs DIR Submodules DIR README DIR LICENSE --- DIR commit 5fb4bf82c962c831624ee7d1c1c1e75bf67291d8 DIR parent a5b21461738ce6ca8c80071ef594e931c77ffbe4 HTML 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: M include/scc/scc/mach.h | 1 + M src/cmd/as/as.h | 2 +- M src/cmd/as/ins.c | 2 +- M src/cmd/as/symbol.c | 14 +++++++------- M src/libmach/Makefile | 1 + M src/libmach/coff32/coff32.c | 1 + M src/libmach/coff32/coff32.h | 1 + A src/libmach/coff32/coff32setsec.c | 61 +++++++++++++++++++++++++++++++ M src/libmach/coff32/rules.mk | 1 + M src/libmach/libmach.h | 1 + A src/libmach/setsec.c | 11 +++++++++++ 11 files changed, 87 insertions(+), 9 deletions(-) --- DIR 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 *); DIR 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); DIR 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 DIR 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 DIR 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\ DIR 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, }; DIR 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 *); DIR 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; +} DIR 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\ DIR 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 *); DIR 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); +}