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