section.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
section.c (2620B)
---
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(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
97 static FILE *
98 mkfile(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
116 void
117 copy(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
130 void
131 grow(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
141 void
142 debugsec(void)
143 {
144 struct sectab **spp, *sp;
145 Section *sec;
146
147 fputs("Sections:\n", stderr);
148 for (spp = sectab; spp < §ab[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