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 }