coff32setsym.c (1946B)
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 #include "fun.h" 11 12 static int 13 defent(Coff32 *coff, SYMENT *ent, Symbol *sym) 14 { 15 ent->n_scnum = sym->section + 1; 16 17 switch (sym->type) { 18 case 'N': 19 /* 20 * TODO: What happens with .indent ? 21 * look if the section is STYP_INFO 22 */ 23 ent->n_scnum = N_DEBUG; 24 break; 25 case 'A': 26 ent->n_sclass = C_EXT; 27 case 'a': 28 ent->n_scnum = N_ABS; 29 break; 30 case 'C': 31 case 'U': 32 ent->n_scnum = N_UNDEF; 33 break; 34 case 'T': 35 case 'D': 36 case 'B': 37 case 'R': 38 ent->n_sclass = C_EXT; 39 break; 40 case 't': 41 case 'd': 42 case 'b': 43 case 'r': 44 ent->n_sclass = C_STAT; 45 break; 46 case '?': 47 default: 48 /* TODO */ 49 return -1; 50 } 51 52 return 0; 53 } 54 55 static char * 56 symname(Coff32 *coff, SYMENT *ent, Symbol *sym) 57 { 58 char *p; 59 unsigned long siz = strlen(sym->name); 60 61 if (siz < SYMNMLEN) 62 return strncpy(ent->n_name, sym->name, SYMNMLEN); 63 64 if (coff->strsiz > ULONG_MAX - siz - 1) 65 return NULL; 66 67 siz += coff->strsiz + 1; 68 if ((p = realloc(coff->strtbl, siz)) == NULL) 69 return NULL; 70 coff->strtbl = p; 71 72 ent->n_zeroes = 0; 73 ent->n_offset = coff->strsiz; 74 coff->strsiz += siz; 75 return strcpy(&coff->strtbl[ent->n_offset], sym->name); 76 } 77 78 Symbol * 79 coff32setsym(Obj *obj, int *idx, Symbol *sym) 80 { 81 int n = *idx; 82 Entry *ep; 83 SYMENT *ent; 84 Coff32 *coff = obj->data; 85 FILHDR *hdr = &coff->hdr; 86 87 hdr->f_flags &= ~F_LSYMS; 88 if (n >= coff->hdr.f_nsyms) { 89 if (n > LONG_MAX-1) 90 return NULL; 91 if ((ep = realloc(coff->ents, (n+1) * sizeof(*ep))) == NULL) 92 return NULL; 93 coff->ents = ep; 94 coff->hdr.f_nsyms = n+1; 95 } 96 ep = &coff->ents[n]; 97 ent = &ep->u.sym; 98 if (!symname(coff, ent, sym)) 99 return NULL; 100 101 ent->n_value = sym->value; 102 if (defent(coff, ent, sym) < 0) 103 return NULL; 104 105 /* 106 * TODO: 107 * sym->stype 108 */ 109 ent->n_numaux = 0; /* TODO: debug information */ 110 111 *idx += ent->n_numaux; 112 113 return sym; 114 }