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 char *13secname(Coff32 *coff, SCNHDR *scn, Section *sec)14{15 char *p;16 unsigned long siz = strlen(sec->name);1718 if (siz < SCNNMLEN)19 return strncpy(scn->s_name, sec->name, SCNNMLEN);2021 if (coff->strsiz > ULONG_MAX - siz - 1)22 return NULL;2324 siz += coff->strsiz + 1;25 if ((p = realloc(coff->strtbl, siz)) == NULL)26 return NULL;27 coff->strtbl = p;2829 scn->s_zeroes = 0;30 scn->s_offset = coff->strsiz;31 coff->strsiz += siz;32 return strcpy(&coff->strtbl[scn->s_offset], sec->name);33}3435Section *36coff32setsec(Obj *obj, int *idx, Section *sec)37{38 long flags, n = *idx;39 SCNHDR *scn;40 Coff32 *coff = obj->data;41 FILHDR *hdr = &coff->hdr;4243 /* TODO: what happens with SABS? */44 switch (sec->type) {45 case 'D':46 switch (sec->flags) {47 case SALLOC | SRELOC | SLOAD | SWRITE | SREAD:48 if (strcmp(sec->name ,".data") == 0)49 flags = STYP_DATA;50 else51 flags = STYP_REG;52 break;53 case SALLOC | SREAD | SWRITE:54 flags = STYP_NOLOAD;55 break;56 case SALLOC | SRELOC | SLOAD | SREAD:57 flags = STYP_RDATA;58 break;59 case SEXEC | SALLOC | SRELOC | SLOAD | SREAD:60 flags = STYP_TEXT | STYP_DATA;61 break;62 default:63 goto invalid;64 }65 break;66 case 'T':67 flags = STYP_TEXT;68 break;69 case 'B':70 flags = STYP_BSS;71 break;72 case 'N':73 case '?':74 default:75 invalid:76 /* TODO */77 return NULL;78 }7980 if (strlen(sec->name) >= SCNNMLEN)81 return NULL;8283 if (n >= hdr->f_nscns) {84 if (n > SHRT_MAX - 1)85 return NULL;86 scn = realloc(coff->scns, (n+1) * sizeof(SCNHDR));87 if (!scn)88 return NULL;89 coff->scns = scn;90 hdr->f_nscns = n + 1;91 }9293 scn = &coff->scns[n];94 if (!secname(coff, scn, sec))95 return NULL;9697 /*98 * sec->offset is ignored because it is very unlikely99 * that the vaule is meaningful here. The field offset100 * was added only to allow getsec to retrive the information101 * in a generic way, but it was never expected to be a 2 way102 * relation. That pointer is updated when the object file103 * is written using a mapping.104 */105 scn->s_paddr = sec->load;106 scn->s_vaddr = sec->base;107 scn->s_size = sec->size;108 scn->s_scnptr = 0;109 scn->s_relptr = 0;110 scn->s_lnnoptr = 0;111 scn->s_nrelloc = 0;112 scn->s_nlnno = 0;113 scn->s_flags = flags;114115 return sec;116}