1#include <limits.h>2#include <stdio.h>3#include <stdlib.h>4#include <string.h>56#include <scc/mach.h>7#include <scc/coff32.h>89#include "../libmach.h"10#include "fun.h"1112static int13defent(Coff32 *coff, SYMENT *ent, Symbol *sym)14{15 ent->n_scnum = sym->section + 1;1617 switch (sym->type) {18 case 'N':19 /*20 * TODO: What happens with .indent ?21 * look if the section is STYP_INFO22 */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 }5152 return 0;53}5455static char *56symname(Coff32 *coff, SYMENT *ent, Symbol *sym)57{58 char *p;59 unsigned long siz = strlen(sym->name);6061 if (siz < SYMNMLEN)62 return strncpy(ent->n_name, sym->name, SYMNMLEN);6364 if (coff->strsiz > ULONG_MAX - siz - 1)65 return NULL;6667 siz += coff->strsiz + 1;68 if ((p = realloc(coff->strtbl, siz)) == NULL)69 return NULL;70 coff->strtbl = p;7172 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}7778Symbol *79coff32setsym(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;8687 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;100101 ent->n_value = sym->value;102 if (defent(coff, ent, sym) < 0)103 return NULL;104105 /*106 * TODO:107 * sym->stype108 */109 ent->n_numaux = 0; /* TODO: debug information */110111 *idx += ent->n_numaux;112113 return sym;114}