scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

symbol.c (4236B)


      1 static char sccsid[] = "@(#) ./as/symbol.c";
      2 
      3 #include <ctype.h>
      4 #include <stdio.h>
      5 #include <stdint.h>
      6 #include <string.h>
      7 
      8 #include "../inc/scc.h"
      9 #include "as.h"
     10 
     11 #define HASHSIZ 64
     12 #define NALLOC  10
     13 
     14 static Section abss = {
     15 	.name  = (String) {"abs"},
     16 	.flags = TABS|SREAD|SWRITE,
     17 };
     18 
     19 static Section bss = {
     20 	.name  = (String) {"bss"},
     21 	.flags = TBSS|SRELOC|SREAD|SWRITE,
     22 	.next  = &abss,
     23 };
     24 
     25 static Section data = {
     26 	.name  = (String) {"data"},
     27 	.flags = TDATA|SRELOC|SREAD|SWRITE|SFILE,
     28 	.next  = &bss,
     29 };
     30 
     31 static Section text = {
     32 	.name  = (String) {"text"},
     33 	.flags = TTEXT|SRELOC|SFILE,
     34 	.next  = &data,
     35 };
     36 
     37 Section *cursec = &text, *seclist = &text;
     38 
     39 int pass;
     40 
     41 static Symbol *hashtbl[HASHSIZ];
     42 static Alloc *tmpalloc;
     43 
     44 Symbol *linesym, *symlist;
     45 
     46 #ifndef NDEBUG
     47 void
     48 dumpstab(char *msg)
     49 {
     50 	Symbol **bp, *sym;
     51 
     52 	fprintf(stderr, "%s\n", msg);
     53 	for (bp = hashtbl; bp < &hashtbl[HASHSIZ]; ++bp) {
     54 		if (*bp == NULL)
     55 			continue;
     56 
     57 		fprintf(stderr, "[%d]", (int) (bp - hashtbl));
     58 		for (sym = *bp; sym; sym = sym->hash) {
     59 			fprintf(stderr, " -> %s:%0X:%0X",
     60 			       sym->name.buf, sym->flags, sym->argtype);
     61 		}
     62 		putc('\n', stderr);
     63 	}
     64 }
     65 #endif
     66 
     67 Symbol *
     68 lookup(char *name, int type)
     69 {
     70 	unsigned h;
     71 	Symbol *sym, **list;
     72 	int c, symtype;
     73 	char *t, *s;
     74 
     75 	h = 0;
     76 	for (s = name; c = *s; ++s)
     77 		h = h*33 ^ c;
     78 	h &= HASHSIZ-1;
     79 
     80 	c = toupper(*name);
     81 	list = &hashtbl[h];
     82 	for (sym = *list; sym; sym = sym->hash) {
     83 		t = sym->name.buf;
     84 		if (c != toupper(*t) || casecmp(t, name))
     85 			continue;
     86 		symtype = sym->flags & TMASK;
     87 		if (symtype != TUNDEF && symtype != type)
     88 			continue;
     89 		return sym;
     90 	}
     91 
     92 	sym = xmalloc(sizeof(*sym));
     93 	sym->name = newstring(name);
     94 	sym->flags = FLOCAL | FUNDEF | type;
     95 	sym->value = 0;
     96 	sym->hash = *list;
     97 	sym->next = symlist;
     98 
     99 	return symlist = *list = sym;
    100 }
    101 
    102 Symbol *
    103 deflabel(char *name)
    104 {
    105 	static Symbol *cursym;
    106 	Symbol *sym;
    107 	char label[MAXSYM+1];
    108 
    109 	if (*name == '.') {
    110 		int r;
    111 
    112 		if (!cursym) {
    113 			error("local label '%s' without global label", name);
    114 			return NULL;
    115 		}
    116 		r = snprintf(label, sizeof(label),
    117 		             "%s%s",
    118 		             cursym->name.buf, name);
    119 		if (r == sizeof(label)) {
    120 			error("local label '%s' in '%s' produces too long symbol",
    121 			      name, cursym->name.buf);
    122 			return NULL;
    123 		}
    124 		name = label;
    125 	}
    126 
    127 	sym = lookup(name, TUNDEF);
    128 	if (pass == 1 && (sym->flags & FUNDEF) == 0)
    129 		error("redefinition of label '%s'", name);
    130 	sym->flags &= ~FUNDEF;
    131 	sym->value = cursec->curpc;
    132 
    133 	if (*name != '.')
    134 		cursym = sym;
    135 	return sym;
    136 }
    137 
    138 int
    139 toobig(Node *np, int type)
    140 {
    141 	/* TODO */
    142 	return 0;
    143 }
    144 
    145 static void
    146 incpc(int siz)
    147 {
    148 	TUINT pc, curpc;
    149 
    150 	pc = cursec->pc;
    151 	curpc = cursec->curpc;
    152 
    153 	cursec->curpc += siz;
    154 	cursec->pc += siz;
    155 
    156 	if (pass == 2)
    157 		return;
    158 
    159 	if (cursec->pc > cursec->max)
    160 		cursec->max = cursec->pc;
    161 
    162 	if (pc > cursec->pc ||
    163 	    curpc > cursec->curpc ||
    164 	    cursec->curpc > maxaddr ||
    165 	    cursec->pc > maxaddr) {
    166 		die("address overflow");
    167 	}
    168 }
    169 
    170 
    171 static void
    172 isect(Section *sec)
    173 {
    174 	TUINT siz;
    175 
    176 	sec->curpc = sec->pc = sec->base;
    177 	if (pass == 1 || !(sec->flags & SFILE))
    178 		return;
    179 
    180 	siz = sec->max - sec->base;
    181 	if (siz > SIZE_MAX)
    182 		die("out of memory");
    183 	sec->mem = xmalloc(sec->max - sec->base);
    184 }
    185 
    186 Section *
    187 section(char *name)
    188 {
    189 	Section *sec;
    190 
    191 	for (sec = seclist; sec; sec = sec->next) {
    192 		if (!strcmp(sec->name.buf, name))
    193 			break;
    194 	}
    195 	if (!sec) {
    196 		sec = xmalloc(sizeof(*sec));
    197 		sec->name = newstring(name);
    198 		sec->base = sec->max = sec->pc = sec->curpc = 0;
    199 		sec->next = seclist;
    200 		sec->flags = SRELOC|SREAD|SWRITE|SFILE;
    201 		sec->fill = 0;
    202 		sec->aligment = 0;
    203 	}
    204 	return cursec = sec;
    205 }
    206 
    207 void
    208 isections(void)
    209 {
    210 	Section *sec;
    211 
    212 	for (sec = seclist; sec; sec = sec->next)
    213 		isect(sec);
    214 }
    215 
    216 void
    217 emit(Section *sec, char *bytes, int n)
    218 {
    219 	if (sec->mem)
    220 		memcpy(&sec->mem[sec->pc - sec->base], bytes, n);
    221 	incpc(n);
    222 }
    223 
    224 Symbol *
    225 tmpsym(TUINT val)
    226 {
    227 	Symbol *sym;
    228 
    229 	if (!tmpalloc)
    230 		tmpalloc = alloc(sizeof(*sym), NALLOC);
    231 	sym = new(tmpalloc);
    232 	sym->value = val;
    233 	sym->flags = TABS;
    234 
    235 	return sym;
    236 }
    237 
    238 void
    239 killtmp(void)
    240 {
    241 	if (!tmpalloc)
    242 		return;
    243 	dealloc(tmpalloc);
    244 	tmpalloc = NULL;
    245 }
    246 
    247 String
    248 newstring(char *s)
    249 {
    250 	size_t len = strlen(s) + 1;
    251 	String str;
    252 
    253 	str.offset = 0;
    254 	str.buf = xmalloc(len);
    255 	memcpy(str.buf, s, len);
    256 	return str;
    257 }