symbol.c (3023B)
1 #include <assert.h> 2 #include <errno.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #include <scc/mach.h> 8 #include <scc/scc.h> 9 10 #include "ld.h" 11 12 #define NR_SYMBOL 128 13 14 /* 15 * struct symtab has a Symbol as first field because 16 * the code is going to cast from the symbols to the tab. 17 */ 18 struct symtab { 19 Symbol sym; 20 Obj *where; 21 struct symtab *hash; 22 struct symtab *next, *prev; 23 }; 24 25 static struct symtab *symtab[NR_SYMBOL]; 26 static struct symtab undef = {.next = &undef, .prev = &undef}; 27 static struct symtab def = {.next = &def, .prev = &def}; 28 static struct symtab common = {.next = &common, .prev = &common}; 29 30 static Symbol * 31 unlinksym(Symbol *sym) 32 { 33 struct symtab *sp = (struct symtab *) sym; 34 35 sp->next->prev = sp->prev; 36 sp->prev->next = sp->next; 37 38 return sym; 39 } 40 41 static Symbol * 42 linksym(struct symtab *lst, Symbol *sym) 43 { 44 struct symtab *sp = (struct symtab *) sym; 45 46 sp->next = lst; 47 sp->prev = lst->prev; 48 lst->prev->next = sp; 49 lst->prev = sp; 50 51 return sym; 52 } 53 54 int 55 hasref(char *name) 56 { 57 unsigned h; 58 struct symtab *sp; 59 60 h = genhash(name) % NR_SYMBOL; 61 for (sp = symtab[h]; sp; sp = sp->hash) { 62 if (!strcmp(name, sp->sym.name)) 63 return sp->sym.type == 'U'; 64 } 65 return 0; 66 } 67 68 Symbol * 69 lookupsym(char *name) 70 { 71 unsigned h; 72 size_t len; 73 char *s; 74 Symbol *sym; 75 struct symtab *sp; 76 77 h = genhash(name) % NR_SYMBOL; 78 for (sp = symtab[h]; sp; sp = sp->hash) { 79 if (!strcmp(name, sp->sym.name)) 80 return &sp->sym; 81 } 82 83 len = strlen(name) + 1; 84 s = malloc(len); 85 sp = malloc(sizeof(*sp)); 86 if (!s || !sp) { 87 error(strerror(errno)); 88 exit(EXIT_FAILURE); 89 } 90 91 sym = &sp->sym; 92 sym->name = memcpy(s, name, len); 93 sym->value = 0; 94 sym->size = 0; 95 sym->index = 0; 96 sym->type = 'U'; 97 sp->where = NULL; 98 sp->hash = symtab[h]; 99 symtab[h] = sp; 100 101 return linksym(&undef, sym); 102 } 103 104 105 int 106 moreundef(void) 107 { 108 return undef.next != &undef; 109 } 110 111 void 112 listundef(void) 113 { 114 struct symtab *sp; 115 116 for (sp = undef.next; sp != &undef; sp = sp->next) 117 error("ld: symbol '%s' not defined", sp->sym.name); 118 } 119 120 Symbol * 121 define(Symbol *osym, Obj *obj) 122 { 123 struct symtab *lst; 124 Symbol *sym = lookupsym(osym->name); 125 struct symtab *sp = (struct symtab *) sym; 126 127 assert(osym->type != 'U'); 128 sp->where = obj; 129 130 switch (sym->type) { 131 case 'U': 132 sym->value = osym->value; 133 sym->size = osym->size; 134 lst = (osym->type == 'C') ? &common : &def; 135 linksym(lst, unlinksym(sym)); 136 break; 137 case 'C': 138 if (osym->type != 'C') { 139 sym->size = osym->size; 140 sym->value = osym->size; 141 linksym(&def, unlinksym(sym)); 142 } else if (sym->size < osym->size) { 143 sym->value = osym->value; 144 sym->size = osym->size; 145 } 146 break; 147 defaul: 148 error("%s: symbol redefined", sym->name); 149 break; 150 } 151 152 return sym; 153 } 154 155 #ifndef NDEBUG 156 void 157 debugsym(void) 158 { 159 struct symtab **spp, *sp; 160 Symbol*sym; 161 162 fputs("Symbols:\n", stderr); 163 for (spp = symtab; spp < &symtab[NR_SYMBOL]; spp++) { 164 for (sp = *spp; sp; sp = sp->hash) { 165 sym = &sp->sym; 166 fprintf(stderr, 167 "sym: %s (%#llx)\n", 168 sym->name, 169 sym->value); 170 } 171 } 172 } 173 #endif