scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

coff32setsec.c (1462B)


      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 Section *
     12 coff32setsec(Obj *obj, int *idx, Section *sec)
     13 {
     14 	long flags, n = *idx;
     15 	SCNHDR *scn;
     16 	Coff32 *coff = obj->data;
     17 	FILHDR *hdr = &coff->hdr;
     18 
     19 	switch (sec->type) {
     20 	case 'D':
     21 		switch (sec->flags) {
     22 		case SALLOC | SRELOC | SLOAD | SWRITE | SREAD:
     23 			if (strcmp(sec->name ,".data") == 0)
     24 				flags = STYP_DATA;
     25 			else
     26 				flags = STYP_REG;
     27 			break;
     28 		case SALLOC | SREAD | SWRITE:
     29 			flags = STYP_NOLOAD;
     30 			break;
     31 		case SALLOC | SRELOC | SLOAD | SREAD:
     32 			flags = STYP_RDATA;
     33 			break;
     34 		case SEXEC | SALLOC | SRELOC | SLOAD | SREAD:
     35 			flags = STYP_TEXT | STYP_DATA;
     36 			break;
     37 		default:
     38 			goto invalid;
     39 		}
     40 		break;
     41 	case 'T':
     42 		flags = STYP_TEXT;
     43 		break;
     44 	case 'B':
     45 		flags = STYP_BSS;
     46 		break;
     47 	case 'N':
     48 	case '?':
     49 	default:
     50 	invalid:
     51 		/* TODO */
     52 		return NULL;
     53 	}
     54 
     55 	if (strlen(sec->name) >= SCNNMLEN)
     56 		return NULL;
     57 
     58 	if (n >= hdr->f_nscns) {
     59 		if (n > SHRT_MAX - 1)
     60 			return NULL;
     61 		scn = realloc(coff->scns, (n+1) * sizeof(SCNHDR));
     62 		if (!scn)
     63 			return NULL;
     64 		coff->scns = scn;
     65 		hdr->f_nscns = n + 1;
     66 	}
     67 	scn = &coff->scns[n];
     68 
     69 	strncpy(scn->s_name, sec->name, SCNNMLEN);
     70 	scn->s_paddr = 0;
     71 	scn->s_vaddr = sec->base;
     72 	scn->s_size = sec->size;
     73 	scn->s_scnptr = 0;
     74 	scn->s_relptr = 0;
     75 	scn->s_lnnoptr = 0;
     76 	scn->s_nrelloc = 0;
     77 	scn->s_nlnno = 0;
     78 	scn->s_flags = flags; 
     79 
     80 	return sec;
     81 }