scc

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

section.c (2521B)


      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, *prev;
     24 };
     25 
     26 static struct sectab *sectab[NR_SECTION];
     27 static struct sectab secs = {.next = &secs, .prev = &secs};
     28 
     29 static Section *
     30 linksec(struct sectab *lst, Section *sec)
     31 {
     32 	struct sectab *sp = (struct sectab *) sec;
     33 
     34 	sp->next = lst;
     35 	sp->prev = lst->prev;
     36 	lst->prev->next = sp;
     37 	lst->prev = sp;
     38 
     39 	return sec;
     40 }
     41 
     42 Section *
     43 lookupsec(char *name)
     44 {
     45 	unsigned h;
     46 	size_t len;
     47 	char *s;
     48 	Section *sec;
     49 	struct sectab *sp;
     50 
     51 	h = genhash(name) % NR_SECTION;
     52 	for (sp = sectab[h]; sp; sp = sp->hash) {
     53 		if (!strcmp(name, sp->sec.name))
     54 			return &sp->sec;
     55 	}
     56 
     57 	len = strlen(name) + 1;
     58 	s = malloc(len);
     59 	sp = malloc(sizeof(*sp));
     60 	if (!s || !sp) {
     61 		error(strerror(errno));
     62 		exit(EXIT_FAILURE);
     63 	}
     64 
     65 	sec = &sp->sec;
     66 	sec->name = memcpy(s, name, len);
     67 	sec->type = 'U';
     68 	sec->base = 0;
     69 	sec->size = 0;
     70 	sec->align = 0;
     71 	sec->index = 0;
     72 	sec->flags = 0;
     73 	sp->tmpfp;
     74 	sp->hash = sectab[h];
     75 	sectab[h] = sp;
     76 
     77 	return linksec(&secs, sec);
     78 }
     79 
     80 void
     81 copy(Obj *obj, Section *osec, Section *sec)
     82 {
     83 	struct sectab *sp = (struct sectab *) sec;
     84 
     85 	if (sec->size > ULLONG_MAX - osec->size) {
     86 		error("%s: section too long", sec->name);
     87 		return;
     88 	}
     89 
     90 	if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
     91 		error(strerror(errno));
     92 		exit(EXIT_FAILURE);
     93 	}
     94 
     95 /*
     96 	if (mapsec(obj, osec->index, sp->tmpfp) < 0) {
     97 		error(strerror(errno));
     98 		return;
     99 	}
    100 */
    101 
    102 	sec->size += osec->size;
    103 }
    104 
    105 void
    106 grow(Section *sec, int nbytes)
    107 {
    108 	struct sectab *sp = (struct sectab *) sec;
    109 
    110 	if (sec->size > ULLONG_MAX - nbytes) {
    111 		error("%s: section too long", sec->name);
    112 		return;
    113 	}
    114 
    115 	if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
    116 		error(strerror(errno));
    117 		exit(EXIT_FAILURE);
    118 	}
    119 
    120 	while (nbytes-- > 0)
    121 		putc(0, sp->tmpfp);
    122 
    123 	sec->size += nbytes;
    124 }
    125 
    126 #ifndef NDEBUG
    127 void
    128 debugsec(void)
    129 {
    130 	struct sectab **spp, *sp;
    131 	Section *sec;
    132 
    133 	fputs("Sections:\n", stderr);
    134 	for (spp = sectab; spp < &sectab[NR_SECTION]; spp++) {
    135 		for (sp = *spp; sp; sp = sp->hash) {
    136 			sec = &sp->sec;
    137 			fprintf(stderr,
    138 			        "sec: %s - %c (%#llx,%#lx)\n",
    139 			        sec->name,
    140 			        sec->type,
    141 			        sec->base,
    142 			        sec->size);
    143 		}
    144 	}
    145 }
    146 #endif