scc

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

section.c (2682B)


      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 		seg->size += sec->size;
     88 	}
     89 
     90 	seg->nsec = n;
     91 }
     92 
     93 void
     94 copy(Obj *obj, Section *osec, Section *sec)
     95 {
     96 	struct sectab *sp = (struct sectab *) sec;
     97 
     98 	if (sec->size > ULLONG_MAX - osec->size) {
     99 		error("%s: section too long", sec->name);
    100 		return;
    101 	}
    102 
    103 	if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
    104 		error(strerror(errno));
    105 		exit(EXIT_FAILURE);
    106 	}
    107 
    108 /*
    109 	if (mapsec(obj, osec->index, sp->tmpfp) < 0) {
    110 		error(strerror(errno));
    111 		return;
    112 	}
    113 */
    114 
    115 	sec->size += osec->size;
    116 }
    117 
    118 void
    119 grow(Section *sec, int nbytes)
    120 {
    121 	struct sectab *sp = (struct sectab *) sec;
    122 
    123 	if (sec->size > ULLONG_MAX - nbytes) {
    124 		error("%s: section too long", sec->name);
    125 		return;
    126 	}
    127 
    128 	if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
    129 		error(strerror(errno));
    130 		exit(EXIT_FAILURE);
    131 	}
    132 
    133 	while (nbytes-- > 0)
    134 		putc(0, sp->tmpfp);
    135 
    136 	sec->size += nbytes;
    137 }
    138 
    139 #ifndef NDEBUG
    140 void
    141 debugsec(void)
    142 {
    143 	struct sectab **spp, *sp;
    144 	Section *sec;
    145 
    146 	fputs("Sections:\n", stderr);
    147 	for (spp = sectab; spp < &sectab[NR_SECTION]; spp++) {
    148 		for (sp = *spp; sp; sp = sp->hash) {
    149 			sec = &sp->sec;
    150 			fprintf(stderr,
    151 			        "sec: %s - %c (%#llx,%#lx)\n",
    152 			        sec->name,
    153 			        sec->type,
    154 			        sec->base,
    155 			        sec->size);
    156 		}
    157 	}
    158 }
    159 #endif