scc

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

section.c (2606B)


      1 #include <assert.h>
      2 #include <errno.h>
      3 #include <limits.h>
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #include <scc/mach.h>
      9 #include <scc/scc.h>
     10 
     11 #include "ld.h"
     12 
     13 #define NR_SECTION 32
     14 
     15 /*
     16  * struct sectab has a Section as first field because
     17  * the code is going to cast from the sections to the tab.
     18  */
     19 struct sectab {
     20 	Section sec;
     21 	FILE *tmpfp;
     22 	struct sectab *hash;
     23 	struct sectab *next;
     24 };
     25 
     26 static struct sectab *sectab[NR_SECTION];
     27 static struct sectab *secs;
     28 
     29 Section *
     30 lookupsec(char *name)
     31 {
     32 	unsigned h;
     33 	size_t len;
     34 	char *s;
     35 	Section *sec;
     36 	struct sectab *sp;
     37 
     38 	h = genhash(name) % NR_SECTION;
     39 	for (sp = sectab[h]; sp; sp = sp->hash) {
     40 		if (!strcmp(name, sp->sec.name))
     41 			return &sp->sec;
     42 	}
     43 
     44 	len = strlen(name) + 1;
     45 	s = malloc(len);
     46 	sp = malloc(sizeof(*sp));
     47 	if (!s || !sp) {
     48 		error(strerror(errno));
     49 		exit(EXIT_FAILURE);
     50 	}
     51 
     52 	sec = &sp->sec;
     53 	sec->name = memcpy(s, name, len);
     54 	sec->type = 'U';
     55 	sec->base = 0;
     56 	sec->size = 0;
     57 	sec->align = 0;
     58 	sec->index = 0;
     59 	sec->flags = 0;
     60 	sp->tmpfp = NULL;
     61 	sp->hash = sectab[h];
     62 	sectab[h] = sp;
     63 	sp->next = secs;
     64 	secs = sp;
     65 
     66 	return sec;
     67 }
     68 
     69 void
     70 merge(Segment *seg)
     71 {
     72 	struct sectab *sp;
     73 	Section *sec, **p;
     74 	int n = 0;
     75 
     76 	for (sp = secs; sp; sp = sp->next) {
     77 		sec = &sp->sec;
     78 		if (sec->type != seg->type)
     79 			continue;
     80 		p = realloc(seg->sections, (n+1) * sizeof(*p));
     81 		if (!p) {
     82 			error("out of memory");
     83 			exit(EXIT_FAILURE);
     84 		}
     85 		p[n++] = sec;
     86 		seg->sections = p;
     87 
     88 		/* rebase(obj, sec->index, seg->size); */
     89 		seg->size += sec->size;
     90 	}
     91 
     92 	seg->nsec = n;
     93 }
     94 
     95 static FILE *
     96 mkfile(Section *sec, unsigned long long size)
     97 {
     98 	struct sectab *sp = (struct sectab *) sec;
     99 
    100 	if (sec->size > ULLONG_MAX - size) {
    101 		error("%s: section too long", sec->name);
    102 		exit(EXIT_FAILURE);
    103 	}
    104 	sec->size += size;
    105 
    106 	if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
    107 		error(strerror(errno));
    108 		exit(EXIT_FAILURE);
    109 	}
    110 
    111 	return sp->tmpfp;
    112 }
    113 
    114 void
    115 copy(Obj *obj, Section *osec, Section *sec)
    116 {
    117 	FILE *fp;
    118 
    119 	fp = mkfile(sec, osec->size);
    120 /*
    121 	if (mapsec(obj, osec->index, fp) < 0) {
    122 		error(strerror(errno));
    123 		return;
    124 	}
    125 */
    126 }
    127 
    128 void
    129 grow(Section *sec, int nbytes)
    130 {
    131 	FILE *fp;
    132 
    133 	fp = mkfile(sec, nbytes);
    134 	while (nbytes-- > 0)
    135 		putc(0, fp);
    136 }
    137 
    138 #ifndef NDEBUG
    139 void
    140 debugsec(void)
    141 {
    142 	struct sectab **spp, *sp;
    143 	Section *sec;
    144 
    145 	fputs("Sections:\n", stderr);
    146 	for (spp = sectab; spp < &sectab[NR_SECTION]; spp++) {
    147 		for (sp = *spp; sp; sp = sp->hash) {
    148 			sec = &sp->sec;
    149 			fprintf(stderr,
    150 			        "sec: %s - %c (%#llx,%#lx)\n",
    151 			        sec->name,
    152 			        sec->type,
    153 			        sec->base,
    154 			        sec->size);
    155 		}
    156 	}
    157 }
    158 #endif