coff32setsym.c (1929B)
1 #include <limits.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include <scc/mach.h> 7 #include <scc/coff32.h> 8 9 #include "../libmach.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 Entry *ep; 82 SYMENT *ent; 83 Coff32 *coff = obj->data; 84 FILHDR *hdr = &coff->hdr; 85 86 hdr->f_flags &= ~F_LSYMS; 87 if (n >= coff->hdr.f_nsyms) { 88 if (n > LONG_MAX-1) 89 return NULL; 90 if ((ep = realloc(coff->ents, (n+1) * sizeof(*ep))) == NULL) 91 return NULL; 92 coff->ents = ep; 93 coff->hdr.f_nsyms = n+1; 94 } 95 ep = &coff->ents[n]; 96 ent = &ep->u.sym; 97 if (!symname(coff, ent, sym)) 98 return NULL; 99 100 ent->n_value = sym->value; 101 if (defent(coff, ent, sym) < 0) 102 return NULL; 103 104 /* 105 * TODO: 106 * sym->stype 107 */ 108 ent->n_numaux = 0; /* TODO: debug information */ 109 110 *idx += ent->n_numaux; 111 112 return sym; 113 }