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