scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

symbol.c (2447B)


      1 #include <ctype.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 
      6 #include <scc/mach.h>
      7 #include <scc/scc.h>
      8 
      9 #include "ld.h"
     10 
     11 #define NR_SYMBOL 128
     12 
     13 static Symbol *symtab[NR_SYMBOL];
     14 
     15 static Symbol refhead = {
     16 	.next = &refhead,
     17 	.prev = &refhead,
     18 };
     19 
     20 Symbol *
     21 lookup(char *name, int install)
     22 {
     23 	size_t len;
     24 	char *s;
     25 	unsigned h;
     26 	Symbol *sym;
     27 
     28 	h = genhash(name) % NR_SYMBOL;
     29 
     30 	for (sym = symtab[h]; sym; sym = sym->hash) {
     31 		if (!strcmp(name, sym->name))
     32 			return sym;
     33 	}
     34 
     35 	if (!install)
     36 		return NULL;
     37 
     38 	len = strlen(name) + 1;
     39 	sym = malloc(sizeof(*sym));
     40 	s = malloc(len);
     41 	if (!len || !s) {
     42 		error("out of memory");
     43 		exit(EXIT_FAILURE);
     44 	}
     45 
     46 	sym->obj = NULL;
     47 	sym->name = memcpy(s, name, len);
     48 	sym->hash = symtab[h];
     49 	symtab[h] = sym;
     50 	sym->value = 0;
     51 	sym->size = 0;
     52 
     53 	refhead.next->prev = sym;
     54 	sym->next = refhead.next;
     55 	refhead.next = sym;
     56 	sym->prev = &refhead;
     57 
     58 	return sym;
     59 }
     60 
     61 Symbol *
     62 define(Objsym *osym, Obj *obj)
     63 {
     64 	Symbol *sym = lookup(osym->name, INSTALL);
     65 
     66 	if (sym->def && sym->def->type != 'C') {
     67 		error("%s: symbol redefined", osym->name);
     68 		return NULL;
     69 	}
     70 
     71 	sym->obj = obj;
     72 	sym->def = osym;
     73 	sym->size = osym->size;
     74 	sym->value = osym->value;
     75 
     76 	sym->next->prev = sym->prev;
     77 	sym->prev->next = sym->next;
     78 	sym->next = sym->prev = NULL;
     79 
     80 	return sym;
     81 }
     82 
     83 int
     84 newsym(Objsym *osym, Obj *obj)
     85 {
     86 	Symbol *sym;
     87 
     88 	switch (osym->type) {
     89 	case 'U':
     90 		lookup(osym->name, INSTALL);
     91 	case '?':
     92 	case 'N':
     93 		break;
     94 	case 'C':
     95 		sym = lookup(osym->name, NOINSTALL);
     96 		if (!sym || !sym->def) {
     97 			define(osym, obj);
     98 			break;
     99 		}
    100 		if (sym->def->type != 'C')
    101 			break;
    102 		if (sym->size < osym->size)
    103 			sym->size = osym->size;
    104 		break;
    105 	default:
    106 		if (isupper(osym->type))
    107 			define(osym, obj);
    108 		break;
    109 	}
    110 
    111 	return 1;
    112 }
    113 
    114 int
    115 moreundef(void)
    116 {
    117 
    118 	return refhead.next != &refhead;
    119 }
    120 
    121 void
    122 listundef(void)
    123 {
    124 	Symbol *sym, *p;
    125 
    126 	p = &refhead;
    127 	for (sym = p->next; sym != p; sym = sym->next) {
    128 		fprintf(stderr,
    129 		        "ld: symbol '%s' not defined\n",
    130 		        sym->name);
    131 	}
    132 }
    133 
    134 int
    135 defasym(Obj *obj)
    136 {
    137 	Symbol *sym, *p;
    138 
    139 	p = &refhead;
    140 	for (sym = p->next; sym != p; sym = sym->next) {
    141 		if (objlookup(obj, sym->name, 0))
    142 			return 1;
    143 	}
    144 
    145 	return 0;
    146 }
    147 
    148 #ifndef NDEBUG
    149 int
    150 debugsym(void)
    151 {
    152 	Symbol **symp, *sym;
    153 
    154 	for (symp = symtab; symp < &symtab[NR_SYMBOL]; symp++) {
    155 		for (sym = *symp; sym; sym = sym->hash)
    156 			fprintf(stderr,
    157 			        "sym: %s (%#x)\n",
    158 			        sym->name,
    159 			        sym->value);
    160 	}
    161 }
    162 #endif