scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  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 */
 19struct sectab {
 20	Section sec;
 21	FILE *tmpfp;
 22	struct sectab *hash;
 23	struct sectab *next;
 24};
 25
 26static struct sectab *sectab[NR_SECTION];
 27static struct sectab *secs;
 28
 29Section *
 30lookupsec(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
 69void
 70merge(Section *seg)
 71{
 72#if 0
 73	struct sectab *sp;
 74	Section *sec, **p;
 75	int n = 0;
 76
 77	for (sp = secs; sp; sp = sp->next) {
 78		sec = &sp->sec;
 79		if (sec->type != seg->type)
 80			continue;
 81		p = realloc(seg->sections, (n+1) * sizeof(*p));
 82		if (!p) {
 83			error("out of memory");
 84			exit(EXIT_FAILURE);
 85		}
 86		p[n++] = sec;
 87		seg->sections = p;
 88
 89		/* rebase(obj, sec->index, seg->size); */
 90		seg->size += sec->size;
 91	}
 92
 93	seg->nsec = n;
 94#endif
 95}
 96
 97static FILE *
 98mkfile(Section *sec, unsigned long long size)
 99{
100	struct sectab *sp = (struct sectab *) sec;
101
102	if (sec->size > ULLONG_MAX - size) {
103		error("%s: section too long", sec->name);
104		exit(EXIT_FAILURE);
105	}
106	sec->size += size;
107
108	if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
109		error(strerror(errno));
110		exit(EXIT_FAILURE);
111	}
112
113	return sp->tmpfp;
114}
115
116void
117copy(Obj *obj, Section *osec, Section *sec)
118{
119	FILE *fp;
120
121	fp = mkfile(sec, osec->size);
122/*
123	if (mapsec(obj, osec->index, fp) < 0) {
124		error(strerror(errno));
125		return;
126	}
127*/
128}
129
130void
131grow(Section *sec, int nbytes)
132{
133	FILE *fp;
134
135	fp = mkfile(sec, nbytes);
136	while (nbytes-- > 0)
137		putc(0, fp);
138}
139
140#ifndef NDEBUG
141void
142debugsec(void)
143{
144	struct sectab **spp, *sp;
145	Section *sec;
146
147	fputs("Sections:\n", stderr);
148	for (spp = sectab; spp < &sectab[NR_SECTION]; spp++) {
149		for (sp = *spp; sp; sp = sp->hash) {
150			sec = &sp->sec;
151			fprintf(stderr,
152			        "sec: %s - %c (%#llx,%#llx)\n",
153			        sec->name,
154			        sec->type,
155			        sec->base,
156			        sec->size);
157		}
158	}
159}
160#endif