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