scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | 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 }