scc

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