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);
       +}