coff32setsym.c - 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
       ---
       coff32setsym.c (1946B)
       ---
            1 #include <limits.h>
            2 #include <stdio.h>
            3 #include <stdlib.h>
            4 #include <string.h>
            5 
            6 #include <scc/mach.h>
            7 #include <scc/coff32.h>
            8 
            9 #include "../libmach.h"
           10 #include "fun.h"
           11 
           12 static int
           13 defent(Coff32 *coff, SYMENT *ent, Symbol *sym)
           14 {
           15         ent->n_scnum = sym->section + 1;
           16 
           17         switch (sym->type) {
           18         case 'N':
           19                 /*
           20                  * TODO: What happens with .indent ?
           21                  *       look if the section is STYP_INFO 
           22                  */
           23                 ent->n_scnum = N_DEBUG;
           24                 break;
           25         case 'A':
           26                 ent->n_sclass = C_EXT;
           27         case 'a':
           28                 ent->n_scnum = N_ABS;
           29                 break;
           30         case 'C':
           31         case 'U':
           32                 ent->n_scnum = N_UNDEF;
           33                 break;
           34         case 'T':
           35         case 'D':
           36         case 'B':
           37         case 'R':
           38                 ent->n_sclass = C_EXT;
           39                 break;
           40         case 't':
           41         case 'd':
           42         case 'b':
           43         case 'r':
           44                 ent->n_sclass = C_STAT;
           45                 break;
           46         case '?':
           47         default:
           48                 /* TODO */
           49                 return -1;
           50         }
           51 
           52         return 0;
           53 }
           54 
           55 static char *
           56 symname(Coff32 *coff, SYMENT *ent, Symbol *sym)
           57 {
           58         char *p;
           59         unsigned long siz = strlen(sym->name);
           60 
           61         if (siz < SYMNMLEN)
           62                 return strncpy(ent->n_name, sym->name, SYMNMLEN);
           63 
           64         if (coff->strsiz > ULONG_MAX - siz - 1)
           65                 return NULL;
           66 
           67         siz += coff->strsiz + 1;
           68         if ((p = realloc(coff->strtbl, siz)) == NULL)
           69                 return NULL;
           70         coff->strtbl = p;
           71 
           72         ent->n_zeroes = 0;
           73         ent->n_offset = coff->strsiz;
           74         coff->strsiz += siz;
           75         return strcpy(&coff->strtbl[ent->n_offset], sym->name);
           76 }
           77 
           78 Symbol *
           79 coff32setsym(Obj *obj, int *idx, Symbol *sym)
           80 {
           81         int n = *idx;
           82         Entry *ep;
           83         SYMENT *ent;
           84         Coff32 *coff = obj->data;
           85         FILHDR *hdr = &coff->hdr;
           86 
           87         hdr->f_flags &= ~F_LSYMS;
           88         if (n >= coff->hdr.f_nsyms) {
           89                 if (n > LONG_MAX-1)
           90                         return NULL;
           91                 if ((ep = realloc(coff->ents, (n+1) * sizeof(*ep))) == NULL)
           92                         return NULL;
           93                 coff->ents = ep;
           94                 coff->hdr.f_nsyms = n+1;
           95         }
           96         ep = &coff->ents[n];
           97         ent = &ep->u.sym;
           98         if (!symname(coff, ent, sym))
           99                 return NULL;
          100 
          101         ent->n_value = sym->value;
          102         if (defent(coff, ent, sym) < 0)
          103                 return NULL;
          104 
          105         /*
          106          * TODO: 
          107          *      sym->stype
          108          */
          109         ent->n_numaux = 0; /* TODO: debug information */
          110 
          111         *idx += ent->n_numaux;
          112 
          113         return sym;
          114 }