libmach: Add setsec() - scc - simple c99 compiler (HTM) 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 (HTM) 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); +}