Home
       libmach/coff32: Add setsym() - 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 7e58afa199c101cf286652c305ba91e63a8fc40c
   DIR parent 089001cf022662342949760e254ee19f09123350
  HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
       Date:   Thu, 21 Mar 2024 07:43:35 +0100
       
       libmach/coff32: Add setsym()
       
       This function is used to add a symbol to an object. Currently only
       coff32 is supported and there are a lot of things that have to  be
       fixed, like for example the auxiliary entries.
       
       Diffstat:
         M include/scc/scc/mach.h              |       1 +
         M src/libmach/Makefile                |       1 +
         M src/libmach/coff32/coff32.c         |       1 +
         M src/libmach/coff32/coff32.h         |       1 +
         A src/libmach/coff32/coff32setsym.c   |     114 +++++++++++++++++++++++++++++++
         M src/libmach/coff32/rules.mk         |       1 +
         M src/libmach/libmach.h               |       1 +
         A src/libmach/setsym.c                |      11 +++++++++++
       
       8 files changed, 131 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h
       @@ -122,5 +122,6 @@ extern int rebase(Obj *, int, unsigned long long);
        extern int findsec(Map *, char *);
        
        extern Symbol *getsym(Obj *, int *, Symbol *);
       +extern Symbol *setsym(Obj *, int *, Symbol *);
        extern Section *getsec(Obj *, int *, Section *);
        extern Section *setsec(Obj *, int *, Section *);
   DIR diff --git a/src/libmach/Makefile b/src/libmach/Makefile
       @@ -32,6 +32,7 @@ OBJS =\
                setindex.o\
                setmap.o\
                setsec.o\
       +        setsym.o\
                strip.o\
                unpack.o\
                writeobj.o\
   DIR diff --git a/src/libmach/coff32/coff32.c b/src/libmach/coff32/coff32.c
       @@ -17,6 +17,7 @@ struct objops coff32 = {
                .del = coff32del,
                .write = coff32write,
                .getsym = coff32getsym,
       +        .setsym = coff32setsym,
                .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 coff32xsetidx(int, long , char *[], long[], FILE *);
        extern int coff32xgetidx(int, long *, char ***, long **, FILE *);
        
        extern Symbol *coff32getsym(Obj *, int *, Symbol *);
       +extern Symbol *coff32setsym(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/coff32setsym.c b/src/libmach/coff32/coff32setsym.c
       @@ -0,0 +1,114 @@
       +#include <limits.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <string.h>
       +
       +#include <scc/mach.h>
       +
       +#include "../libmach.h"
       +#include "coff32.h"
       +
       +static int
       +defent(Coff32 *coff, SYMENT *ent, Symbol *sym)
       +{
       +        ent->n_scnum = sym->section + 1;
       +
       +        switch (sym->type) {
       +        case 'N':
       +                /*
       +                 * TODO: What happens with .indent ?
       +                 *       look if the section is STYP_INFO 
       +                 */
       +                ent->n_scnum = N_DEBUG;
       +                break;
       +        case 'A':
       +                ent->n_sclass = C_EXT;
       +        case 'a':
       +                ent->n_scnum = N_ABS;
       +                break;
       +        case 'C':
       +        case 'U':
       +                ent->n_scnum = N_UNDEF;
       +                break;
       +        case 'T':
       +        case 'D':
       +        case 'B':
       +        case 'R':
       +                ent->n_sclass = C_EXT;
       +                break;
       +        case 't':
       +        case 'd':
       +        case 'b':
       +        case 'r':
       +                ent->n_sclass = C_STAT;
       +                break;
       +        case '?':
       +        default:
       +                /* TODO */
       +                return -1;
       +        }
       +
       +        return 0;
       +}
       +
       +static char *
       +symname(Coff32 *coff, SYMENT *ent, Symbol *sym)
       +{
       +        char *p;
       +        unsigned long siz = strlen(sym->name);
       +
       +        if (siz < SYMNMLEN)
       +                return strncpy(ent->n_name, sym->name, SYMNMLEN);
       +
       +        if (coff->strsiz > ULONG_MAX - siz - 1)
       +                return NULL;
       +
       +        siz += coff->strsiz + 1;
       +        if ((p = realloc(coff->strtbl, siz)) == NULL)
       +                return NULL;
       +        coff->strtbl = p;
       +
       +        ent->n_zeroes = 0;
       +        ent->n_offset = coff->strsiz;
       +        coff->strsiz += siz;
       +        return strcpy(&coff->strtbl[ent->n_offset], sym->name);
       +}
       +
       +Symbol *
       +coff32setsym(Obj *obj, int *idx, Symbol *sym)
       +{
       +        int n = *idx;
       +        SYMENT *ent, *p;
       +        Coff32 *coff = obj->data;
       +        FILHDR *hdr = &coff->hdr;
       +
       +        hdr->f_flags |= F_SYMS;
       +        if (n >= coff->hdr.f_nsyms) {
       +                if (n > LONG_MAX-1)
       +                        return NULL;
       +                if ((p = realloc(coff->ents, (n+1) * sizeof(*p))) == NULL)
       +                        return NULL;
       +                coff->ents = p;
       +                coff->hdr.f_nsyms = n+1;
       +        }
       +        ent = &coff->ents[n];
       +        if (!symname(coff, ent, sym))
       +                return NULL;
       +
       +        ent->n_value = sym->value;
       +        if (defent(coff, ent, sym) < 0)
       +                return NULL;
       +
       +        /*
       +         * TODO: 
       +         *         sym->type
       +         *      sym->stype
       +         */
       +        ent->n_type = 0;  /* TODO: debug information */
       +        ent->n_sclass = 0; /* TODO: debug information */
       +        ent->n_numaux = 0; /* TODO: debug information */
       +
       +        *idx += ent->n_numaux;
       +
       +        return sym;
       +}
   DIR diff --git a/src/libmach/coff32/rules.mk b/src/libmach/coff32/rules.mk
       @@ -16,6 +16,7 @@ COFF32_OBJS =\
                coff32/coff32getidx.o \
                coff32/coff32pc2line.o \
                coff32/coff32getsym.o \
       +        coff32/coff32setsym.o \
                coff32/coff32getsec.o \
                coff32/coff32setsec.o \
                coff32/coff32loadmap.o\
   DIR diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h
       @@ -48,6 +48,7 @@ struct objops {
                Map *(*loadmap)(Obj *, FILE *);
        
                Symbol *(*getsym)(Obj *, int *, Symbol *);
       +        Symbol *(*setsym)(Obj *, int *, Symbol *);
                Section *(*getsec)(Obj *, int *, Section *);
                Section *(*setsec)(Obj *, int *, Section *);
        
   DIR diff --git a/src/libmach/setsym.c b/src/libmach/setsym.c
       @@ -0,0 +1,11 @@
       +#include <stdio.h>
       +
       +#include <scc/mach.h>
       +
       +#include "libmach.h"
       +
       +Symbol *
       +setsym(Obj *obj, int *index, Symbol *sym)
       +{
       +        return (*obj->ops->setsym)(obj, index, sym);
       +}