Blame


1 7a4ee46d 2003-11-23 devnull #include "stdinc.h"
2 7a4ee46d 2003-11-23 devnull #include "dat.h"
3 7a4ee46d 2003-11-23 devnull #include "fns.h"
4 7a4ee46d 2003-11-23 devnull
5 7a4ee46d 2003-11-23 devnull typedef struct AHash AHash;
6 7a4ee46d 2003-11-23 devnull
7 7a4ee46d 2003-11-23 devnull /*
8 7a4ee46d 2003-11-23 devnull * hash table for finding arena's based on their names.
9 7a4ee46d 2003-11-23 devnull */
10 7a4ee46d 2003-11-23 devnull struct AHash
11 7a4ee46d 2003-11-23 devnull {
12 7a4ee46d 2003-11-23 devnull AHash *next;
13 7a4ee46d 2003-11-23 devnull Arena *arena;
14 7a4ee46d 2003-11-23 devnull };
15 7a4ee46d 2003-11-23 devnull
16 7a4ee46d 2003-11-23 devnull enum
17 7a4ee46d 2003-11-23 devnull {
18 7a4ee46d 2003-11-23 devnull AHashSize = 512
19 7a4ee46d 2003-11-23 devnull };
20 7a4ee46d 2003-11-23 devnull
21 7a4ee46d 2003-11-23 devnull static AHash *ahash[AHashSize];
22 7a4ee46d 2003-11-23 devnull
23 7a4ee46d 2003-11-23 devnull static u32int
24 7a4ee46d 2003-11-23 devnull hashstr(char *s)
25 7a4ee46d 2003-11-23 devnull {
26 7a4ee46d 2003-11-23 devnull u32int h;
27 7a4ee46d 2003-11-23 devnull int c;
28 7a4ee46d 2003-11-23 devnull
29 7a4ee46d 2003-11-23 devnull h = 0;
30 7a4ee46d 2003-11-23 devnull for(; c = *s; s++){
31 7a4ee46d 2003-11-23 devnull c ^= c << 6;
32 7a4ee46d 2003-11-23 devnull h += (c << 11) ^ (c >> 1);
33 7a4ee46d 2003-11-23 devnull c = *s;
34 7a4ee46d 2003-11-23 devnull h ^= (c << 14) + (c << 7) + (c << 4) + c;
35 7a4ee46d 2003-11-23 devnull }
36 7a4ee46d 2003-11-23 devnull return h;
37 7a4ee46d 2003-11-23 devnull }
38 7a4ee46d 2003-11-23 devnull
39 7a4ee46d 2003-11-23 devnull int
40 7a4ee46d 2003-11-23 devnull addarena(Arena *arena)
41 7a4ee46d 2003-11-23 devnull {
42 7a4ee46d 2003-11-23 devnull AHash *a;
43 7a4ee46d 2003-11-23 devnull u32int h;
44 7a4ee46d 2003-11-23 devnull
45 7a4ee46d 2003-11-23 devnull h = hashstr(arena->name) & (AHashSize - 1);
46 7a4ee46d 2003-11-23 devnull a = MK(AHash);
47 7a4ee46d 2003-11-23 devnull if(a == nil)
48 7a4ee46d 2003-11-23 devnull return -1;
49 7a4ee46d 2003-11-23 devnull a->arena = arena;
50 7a4ee46d 2003-11-23 devnull a->next = ahash[h];
51 7a4ee46d 2003-11-23 devnull ahash[h] = a;
52 7a4ee46d 2003-11-23 devnull return 0;
53 7a4ee46d 2003-11-23 devnull }
54 7a4ee46d 2003-11-23 devnull
55 7a4ee46d 2003-11-23 devnull Arena*
56 7a4ee46d 2003-11-23 devnull findarena(char *name)
57 7a4ee46d 2003-11-23 devnull {
58 7a4ee46d 2003-11-23 devnull AHash *a;
59 7a4ee46d 2003-11-23 devnull u32int h;
60 7a4ee46d 2003-11-23 devnull
61 7a4ee46d 2003-11-23 devnull h = hashstr(name) & (AHashSize - 1);
62 7a4ee46d 2003-11-23 devnull for(a = ahash[h]; a != nil; a = a->next)
63 7a4ee46d 2003-11-23 devnull if(strcmp(a->arena->name, name) == 0)
64 7a4ee46d 2003-11-23 devnull return a->arena;
65 7a4ee46d 2003-11-23 devnull return nil;
66 7a4ee46d 2003-11-23 devnull }
67 7a4ee46d 2003-11-23 devnull
68 7a4ee46d 2003-11-23 devnull int
69 7a4ee46d 2003-11-23 devnull delarena(Arena *arena)
70 7a4ee46d 2003-11-23 devnull {
71 7a4ee46d 2003-11-23 devnull AHash *a, *last;
72 7a4ee46d 2003-11-23 devnull u32int h;
73 7a4ee46d 2003-11-23 devnull
74 7a4ee46d 2003-11-23 devnull h = hashstr(arena->name) & (AHashSize - 1);
75 7a4ee46d 2003-11-23 devnull last = nil;
76 7a4ee46d 2003-11-23 devnull for(a = ahash[h]; a != nil; a = a->next){
77 7a4ee46d 2003-11-23 devnull if(a->arena == arena){
78 7a4ee46d 2003-11-23 devnull if(last != nil)
79 7a4ee46d 2003-11-23 devnull last->next = a->next;
80 7a4ee46d 2003-11-23 devnull else
81 7a4ee46d 2003-11-23 devnull ahash[h] = a->next;
82 7a4ee46d 2003-11-23 devnull free(a);
83 7a4ee46d 2003-11-23 devnull return 0;
84 7a4ee46d 2003-11-23 devnull }
85 7a4ee46d 2003-11-23 devnull last = a;
86 7a4ee46d 2003-11-23 devnull }
87 7a4ee46d 2003-11-23 devnull return -1;
88 7a4ee46d 2003-11-23 devnull }
89 7a4ee46d 2003-11-23 devnull
90 7a4ee46d 2003-11-23 devnull ArenaPart*
91 7a4ee46d 2003-11-23 devnull initarenapart(Part *part)
92 7a4ee46d 2003-11-23 devnull {
93 7a4ee46d 2003-11-23 devnull AMapN amn;
94 7a4ee46d 2003-11-23 devnull ArenaPart *ap;
95 7a4ee46d 2003-11-23 devnull ZBlock *b;
96 7a4ee46d 2003-11-23 devnull u32int i;
97 7a4ee46d 2003-11-23 devnull int ok;
98 7a4ee46d 2003-11-23 devnull
99 7a4ee46d 2003-11-23 devnull b = alloczblock(HeadSize, 0);
100 7a4ee46d 2003-11-23 devnull if(b == nil || readpart(part, PartBlank, b->data, HeadSize) < 0){
101 7a4ee46d 2003-11-23 devnull seterr(EAdmin, "can't read arena partition header: %r");
102 7a4ee46d 2003-11-23 devnull return nil;
103 7a4ee46d 2003-11-23 devnull }
104 7a4ee46d 2003-11-23 devnull
105 7a4ee46d 2003-11-23 devnull ap = MKZ(ArenaPart);
106 7a4ee46d 2003-11-23 devnull if(ap == nil){
107 7a4ee46d 2003-11-23 devnull freezblock(b);
108 7a4ee46d 2003-11-23 devnull return nil;
109 7a4ee46d 2003-11-23 devnull }
110 7a4ee46d 2003-11-23 devnull ap->part = part;
111 7a4ee46d 2003-11-23 devnull ok = unpackarenapart(ap, b->data);
112 7a4ee46d 2003-11-23 devnull freezblock(b);
113 7a4ee46d 2003-11-23 devnull if(ok < 0){
114 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "corrupted arena partition header: %r");
115 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
116 7a4ee46d 2003-11-23 devnull return nil;
117 7a4ee46d 2003-11-23 devnull }
118 7a4ee46d 2003-11-23 devnull
119 7a4ee46d 2003-11-23 devnull ap->tabbase = (PartBlank + HeadSize + ap->blocksize - 1) & ~(ap->blocksize - 1);
120 7a4ee46d 2003-11-23 devnull if(ap->version != ArenaPartVersion){
121 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "unknown arena partition version %d", ap->version);
122 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
123 7a4ee46d 2003-11-23 devnull return nil;
124 7a4ee46d 2003-11-23 devnull }
125 7a4ee46d 2003-11-23 devnull if(ap->blocksize & (ap->blocksize - 1)){
126 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "illegal non-power-of-2 block size %d\n", ap->blocksize);
127 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
128 7a4ee46d 2003-11-23 devnull return nil;
129 7a4ee46d 2003-11-23 devnull }
130 7a4ee46d 2003-11-23 devnull if(ap->tabbase >= ap->arenabase){
131 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "arena partition table overlaps with arena storage");
132 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
133 7a4ee46d 2003-11-23 devnull return nil;
134 7a4ee46d 2003-11-23 devnull }
135 7a4ee46d 2003-11-23 devnull ap->tabsize = ap->arenabase - ap->tabbase;
136 7a4ee46d 2003-11-23 devnull partblocksize(part, ap->blocksize);
137 7a4ee46d 2003-11-23 devnull ap->size = ap->part->size & ~(u64int)(ap->blocksize - 1);
138 7a4ee46d 2003-11-23 devnull
139 7a4ee46d 2003-11-23 devnull if(readarenamap(&amn, part, ap->tabbase, ap->tabsize) < 0){
140 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
141 7a4ee46d 2003-11-23 devnull return nil;
142 7a4ee46d 2003-11-23 devnull }
143 7a4ee46d 2003-11-23 devnull ap->narenas = amn.n;
144 7a4ee46d 2003-11-23 devnull ap->map = amn.map;
145 7a4ee46d 2003-11-23 devnull if(okamap(ap->map, ap->narenas, ap->arenabase, ap->size, "arena table") < 0){
146 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
147 7a4ee46d 2003-11-23 devnull return nil;
148 7a4ee46d 2003-11-23 devnull }
149 7a4ee46d 2003-11-23 devnull
150 7a4ee46d 2003-11-23 devnull ap->arenas = MKNZ(Arena*, ap->narenas);
151 7a4ee46d 2003-11-23 devnull for(i = 0; i < ap->narenas; i++){
152 7a4ee46d 2003-11-23 devnull ap->arenas[i] = initarena(part, ap->map[i].start, ap->map[i].stop - ap->map[i].start, ap->blocksize);
153 7a4ee46d 2003-11-23 devnull if(ap->arenas[i] == nil){
154 7a4ee46d 2003-11-23 devnull freearenapart(ap, 1);
155 7a4ee46d 2003-11-23 devnull return nil;
156 7a4ee46d 2003-11-23 devnull }
157 7a4ee46d 2003-11-23 devnull if(namecmp(ap->map[i].name, ap->arenas[i]->name) != 0){
158 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "arena name mismatches with expected name: %s vs. %s",
159 7a4ee46d 2003-11-23 devnull ap->map[i].name, ap->arenas[i]->name);
160 7a4ee46d 2003-11-23 devnull freearenapart(ap, 1);
161 7a4ee46d 2003-11-23 devnull return nil;
162 7a4ee46d 2003-11-23 devnull }
163 7a4ee46d 2003-11-23 devnull if(findarena(ap->arenas[i]->name)){
164 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "duplicate arena name %s in %s",
165 7a4ee46d 2003-11-23 devnull ap->map[i].name, ap->part->name);
166 7a4ee46d 2003-11-23 devnull freearenapart(ap, 1);
167 7a4ee46d 2003-11-23 devnull return nil;
168 7a4ee46d 2003-11-23 devnull }
169 7a4ee46d 2003-11-23 devnull }
170 7a4ee46d 2003-11-23 devnull
171 7a4ee46d 2003-11-23 devnull for(i = 0; i < ap->narenas; i++)
172 7a4ee46d 2003-11-23 devnull addarena(ap->arenas[i]);
173 7a4ee46d 2003-11-23 devnull
174 7a4ee46d 2003-11-23 devnull return ap;
175 7a4ee46d 2003-11-23 devnull }
176 7a4ee46d 2003-11-23 devnull
177 7a4ee46d 2003-11-23 devnull ArenaPart*
178 7a4ee46d 2003-11-23 devnull newarenapart(Part *part, u32int blocksize, u32int tabsize)
179 7a4ee46d 2003-11-23 devnull {
180 7a4ee46d 2003-11-23 devnull ArenaPart *ap;
181 7a4ee46d 2003-11-23 devnull
182 7a4ee46d 2003-11-23 devnull if(blocksize & (blocksize - 1)){
183 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "illegal non-power-of-2 block size %d\n", blocksize);
184 7a4ee46d 2003-11-23 devnull return nil;
185 7a4ee46d 2003-11-23 devnull }
186 7a4ee46d 2003-11-23 devnull ap = MKZ(ArenaPart);
187 7a4ee46d 2003-11-23 devnull if(ap == nil)
188 7a4ee46d 2003-11-23 devnull return nil;
189 7a4ee46d 2003-11-23 devnull
190 7a4ee46d 2003-11-23 devnull ap->version = ArenaPartVersion;
191 7a4ee46d 2003-11-23 devnull ap->part = part;
192 7a4ee46d 2003-11-23 devnull ap->blocksize = blocksize;
193 7a4ee46d 2003-11-23 devnull partblocksize(part, blocksize);
194 7a4ee46d 2003-11-23 devnull ap->size = part->size & ~(u64int)(blocksize - 1);
195 7a4ee46d 2003-11-23 devnull ap->tabbase = (PartBlank + HeadSize + blocksize - 1) & ~(blocksize - 1);
196 7a4ee46d 2003-11-23 devnull ap->arenabase = (ap->tabbase + tabsize + blocksize - 1) & ~(blocksize - 1);
197 7a4ee46d 2003-11-23 devnull ap->tabsize = ap->arenabase - ap->tabbase;
198 7a4ee46d 2003-11-23 devnull ap->narenas = 0;
199 7a4ee46d 2003-11-23 devnull
200 7a4ee46d 2003-11-23 devnull if(wbarenapart(ap) < 0){
201 7a4ee46d 2003-11-23 devnull freearenapart(ap, 0);
202 7a4ee46d 2003-11-23 devnull return nil;
203 7a4ee46d 2003-11-23 devnull }
204 7a4ee46d 2003-11-23 devnull
205 7a4ee46d 2003-11-23 devnull return ap;
206 7a4ee46d 2003-11-23 devnull }
207 7a4ee46d 2003-11-23 devnull
208 7a4ee46d 2003-11-23 devnull int
209 7a4ee46d 2003-11-23 devnull wbarenapart(ArenaPart *ap)
210 7a4ee46d 2003-11-23 devnull {
211 7a4ee46d 2003-11-23 devnull ZBlock *b;
212 7a4ee46d 2003-11-23 devnull
213 7a4ee46d 2003-11-23 devnull if(okamap(ap->map, ap->narenas, ap->arenabase, ap->size, "arena table") < 0)
214 7a4ee46d 2003-11-23 devnull return -1;
215 7a4ee46d 2003-11-23 devnull b = alloczblock(HeadSize, 1);
216 7a4ee46d 2003-11-23 devnull if(b == nil)
217 7a4ee46d 2003-11-23 devnull //ZZZ set error message?
218 7a4ee46d 2003-11-23 devnull return -1;
219 7a4ee46d 2003-11-23 devnull
220 7a4ee46d 2003-11-23 devnull if(packarenapart(ap, b->data) < 0){
221 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "can't make arena partition header: %r");
222 7a4ee46d 2003-11-23 devnull freezblock(b);
223 7a4ee46d 2003-11-23 devnull return -1;
224 7a4ee46d 2003-11-23 devnull }
225 7a4ee46d 2003-11-23 devnull if(writepart(ap->part, PartBlank, b->data, HeadSize) < 0){
226 7a4ee46d 2003-11-23 devnull seterr(EAdmin, "can't write arena partition header: %r");
227 7a4ee46d 2003-11-23 devnull freezblock(b);
228 7a4ee46d 2003-11-23 devnull return -1;
229 7a4ee46d 2003-11-23 devnull }
230 7a4ee46d 2003-11-23 devnull freezblock(b);
231 7a4ee46d 2003-11-23 devnull
232 7a4ee46d 2003-11-23 devnull return wbarenamap(ap->map, ap->narenas, ap->part, ap->tabbase, ap->tabsize);
233 7a4ee46d 2003-11-23 devnull }
234 7a4ee46d 2003-11-23 devnull
235 7a4ee46d 2003-11-23 devnull void
236 7a4ee46d 2003-11-23 devnull freearenapart(ArenaPart *ap, int freearenas)
237 7a4ee46d 2003-11-23 devnull {
238 7a4ee46d 2003-11-23 devnull int i;
239 7a4ee46d 2003-11-23 devnull
240 7a4ee46d 2003-11-23 devnull if(ap == nil)
241 7a4ee46d 2003-11-23 devnull return;
242 7a4ee46d 2003-11-23 devnull if(freearenas){
243 7a4ee46d 2003-11-23 devnull for(i = 0; i < ap->narenas; i++){
244 7a4ee46d 2003-11-23 devnull if(ap->arenas[i] == nil)
245 7a4ee46d 2003-11-23 devnull continue;
246 7a4ee46d 2003-11-23 devnull delarena(ap->arenas[i]);
247 7a4ee46d 2003-11-23 devnull freearena(ap->arenas[i]);
248 7a4ee46d 2003-11-23 devnull }
249 7a4ee46d 2003-11-23 devnull }
250 7a4ee46d 2003-11-23 devnull free(ap->map);
251 7a4ee46d 2003-11-23 devnull free(ap->arenas);
252 7a4ee46d 2003-11-23 devnull free(ap);
253 7a4ee46d 2003-11-23 devnull }
254 7a4ee46d 2003-11-23 devnull
255 7a4ee46d 2003-11-23 devnull int
256 7a4ee46d 2003-11-23 devnull okamap(AMap *am, int n, u64int start, u64int stop, char *what)
257 7a4ee46d 2003-11-23 devnull {
258 7a4ee46d 2003-11-23 devnull u64int last;
259 7a4ee46d 2003-11-23 devnull u32int i;
260 7a4ee46d 2003-11-23 devnull
261 7a4ee46d 2003-11-23 devnull last = start;
262 7a4ee46d 2003-11-23 devnull for(i = 0; i < n; i++){
263 7a4ee46d 2003-11-23 devnull if(am[i].start < last){
264 7a4ee46d 2003-11-23 devnull if(i == 0)
265 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "invalid start address in %s", what);
266 7a4ee46d 2003-11-23 devnull else
267 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "overlapping ranges in %s", what);
268 7a4ee46d 2003-11-23 devnull return -1;
269 7a4ee46d 2003-11-23 devnull }
270 7a4ee46d 2003-11-23 devnull if(am[i].stop < am[i].start){
271 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "invalid range in %s", what);
272 7a4ee46d 2003-11-23 devnull return -1;
273 7a4ee46d 2003-11-23 devnull }
274 7a4ee46d 2003-11-23 devnull last = am[i].stop;
275 7a4ee46d 2003-11-23 devnull }
276 7a4ee46d 2003-11-23 devnull if(last > stop){
277 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "invalid ending address in %s", what);
278 7a4ee46d 2003-11-23 devnull return -1;
279 7a4ee46d 2003-11-23 devnull }
280 7a4ee46d 2003-11-23 devnull return 0;
281 7a4ee46d 2003-11-23 devnull }
282 7a4ee46d 2003-11-23 devnull
283 7a4ee46d 2003-11-23 devnull int
284 7a4ee46d 2003-11-23 devnull maparenas(AMap *am, Arena **arenas, int n, char *what)
285 7a4ee46d 2003-11-23 devnull {
286 7a4ee46d 2003-11-23 devnull u32int i;
287 7a4ee46d 2003-11-23 devnull
288 7a4ee46d 2003-11-23 devnull for(i = 0; i < n; i++){
289 7a4ee46d 2003-11-23 devnull arenas[i] = findarena(am[i].name);
290 7a4ee46d 2003-11-23 devnull if(arenas[i] == nil){
291 7a4ee46d 2003-11-23 devnull seterr(EAdmin, "can't find arena '%s' for '%s'\n", am[i].name, what);
292 7a4ee46d 2003-11-23 devnull return -1;
293 7a4ee46d 2003-11-23 devnull }
294 7a4ee46d 2003-11-23 devnull }
295 7a4ee46d 2003-11-23 devnull return 0;
296 7a4ee46d 2003-11-23 devnull }
297 7a4ee46d 2003-11-23 devnull
298 7a4ee46d 2003-11-23 devnull int
299 7a4ee46d 2003-11-23 devnull readarenamap(AMapN *amn, Part *part, u64int base, u32int size)
300 7a4ee46d 2003-11-23 devnull {
301 7a4ee46d 2003-11-23 devnull IFile f;
302 7a4ee46d 2003-11-23 devnull u32int ok;
303 7a4ee46d 2003-11-23 devnull
304 7a4ee46d 2003-11-23 devnull if(partifile(&f, part, base, size) < 0)
305 7a4ee46d 2003-11-23 devnull return -1;
306 7a4ee46d 2003-11-23 devnull ok = parseamap(&f, amn);
307 7a4ee46d 2003-11-23 devnull freeifile(&f);
308 7a4ee46d 2003-11-23 devnull return ok;
309 7a4ee46d 2003-11-23 devnull }
310 7a4ee46d 2003-11-23 devnull
311 7a4ee46d 2003-11-23 devnull int
312 7a4ee46d 2003-11-23 devnull wbarenamap(AMap *am, int n, Part *part, u64int base, u64int size)
313 7a4ee46d 2003-11-23 devnull {
314 7a4ee46d 2003-11-23 devnull Fmt f;
315 7a4ee46d 2003-11-23 devnull ZBlock *b;
316 7a4ee46d 2003-11-23 devnull
317 7a4ee46d 2003-11-23 devnull b = alloczblock(size, 1);
318 7a4ee46d 2003-11-23 devnull if(b == nil)
319 7a4ee46d 2003-11-23 devnull return -1;
320 7a4ee46d 2003-11-23 devnull
321 7a4ee46d 2003-11-23 devnull fmtzbinit(&f, b);
322 7a4ee46d 2003-11-23 devnull
323 7a4ee46d 2003-11-23 devnull if(outputamap(&f, am, n) < 0){
324 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "arena set size too small");
325 7a4ee46d 2003-11-23 devnull freezblock(b);
326 7a4ee46d 2003-11-23 devnull return -1;
327 7a4ee46d 2003-11-23 devnull }
328 7a4ee46d 2003-11-23 devnull if(writepart(part, base, b->data, size) < 0){
329 7a4ee46d 2003-11-23 devnull seterr(EAdmin, "can't write arena set: %r");
330 7a4ee46d 2003-11-23 devnull freezblock(b);
331 7a4ee46d 2003-11-23 devnull return -1;
332 7a4ee46d 2003-11-23 devnull }
333 7a4ee46d 2003-11-23 devnull freezblock(b);
334 7a4ee46d 2003-11-23 devnull return 0;
335 7a4ee46d 2003-11-23 devnull }
336 7a4ee46d 2003-11-23 devnull
337 7a4ee46d 2003-11-23 devnull /*
338 7a4ee46d 2003-11-23 devnull * amap: n '\n' amapelem * n
339 7a4ee46d 2003-11-23 devnull * n: u32int
340 7a4ee46d 2003-11-23 devnull * amapelem: name '\t' astart '\t' asize '\n'
341 7a4ee46d 2003-11-23 devnull * astart, asize: u64int
342 7a4ee46d 2003-11-23 devnull */
343 7a4ee46d 2003-11-23 devnull int
344 7a4ee46d 2003-11-23 devnull parseamap(IFile *f, AMapN *amn)
345 7a4ee46d 2003-11-23 devnull {
346 7a4ee46d 2003-11-23 devnull AMap *am;
347 7a4ee46d 2003-11-23 devnull u64int v64;
348 7a4ee46d 2003-11-23 devnull u32int v;
349 7a4ee46d 2003-11-23 devnull char *s, *flds[4];
350 7a4ee46d 2003-11-23 devnull int i, n;
351 7a4ee46d 2003-11-23 devnull
352 7a4ee46d 2003-11-23 devnull /*
353 7a4ee46d 2003-11-23 devnull * arenas
354 7a4ee46d 2003-11-23 devnull */
355 7a4ee46d 2003-11-23 devnull if(ifileu32int(f, &v) < 0){
356 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "syntax error: bad number of elements in %s", f->name);
357 7a4ee46d 2003-11-23 devnull return -1;
358 7a4ee46d 2003-11-23 devnull }
359 7a4ee46d 2003-11-23 devnull n = v;
360 7a4ee46d 2003-11-23 devnull if(n > MaxAMap){
361 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "illegal number of elements in %s", f->name);
362 7a4ee46d 2003-11-23 devnull return -1;
363 7a4ee46d 2003-11-23 devnull }
364 7a4ee46d 2003-11-23 devnull am = MKNZ(AMap, n);
365 7a4ee46d 2003-11-23 devnull if(am == nil)
366 7a4ee46d 2003-11-23 devnull return -1;
367 7a4ee46d 2003-11-23 devnull for(i = 0; i < n; i++){
368 7a4ee46d 2003-11-23 devnull s = ifileline(f);
369 7a4ee46d 2003-11-23 devnull if(s == nil || getfields(s, flds, 4, 0, "\t") != 3)
370 7a4ee46d 2003-11-23 devnull return -1;
371 7a4ee46d 2003-11-23 devnull if(nameok(flds[0]) < 0)
372 7a4ee46d 2003-11-23 devnull return -1;
373 7a4ee46d 2003-11-23 devnull namecp(am[i].name, flds[0]);
374 7a4ee46d 2003-11-23 devnull if(stru64int(flds[1], &v64) < 0){
375 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "syntax error: bad arena base address in %s", f->name);
376 7a4ee46d 2003-11-23 devnull free(am);
377 7a4ee46d 2003-11-23 devnull return -1;
378 7a4ee46d 2003-11-23 devnull }
379 7a4ee46d 2003-11-23 devnull am[i].start = v64;
380 7a4ee46d 2003-11-23 devnull if(stru64int(flds[2], &v64) < 0){
381 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "syntax error: bad arena size in %s", f->name);
382 7a4ee46d 2003-11-23 devnull free(am);
383 7a4ee46d 2003-11-23 devnull return -1;
384 7a4ee46d 2003-11-23 devnull }
385 7a4ee46d 2003-11-23 devnull am[i].stop = v64;
386 7a4ee46d 2003-11-23 devnull }
387 7a4ee46d 2003-11-23 devnull
388 7a4ee46d 2003-11-23 devnull amn->map = am;
389 7a4ee46d 2003-11-23 devnull amn->n = n;
390 7a4ee46d 2003-11-23 devnull return 0;
391 7a4ee46d 2003-11-23 devnull }
392 7a4ee46d 2003-11-23 devnull
393 7a4ee46d 2003-11-23 devnull int
394 7a4ee46d 2003-11-23 devnull outputamap(Fmt *f, AMap *am, int n)
395 7a4ee46d 2003-11-23 devnull {
396 7a4ee46d 2003-11-23 devnull int i;
397 7a4ee46d 2003-11-23 devnull
398 7a4ee46d 2003-11-23 devnull if(fmtprint(f, "%ud\n", n) < 0)
399 7a4ee46d 2003-11-23 devnull return -1;
400 7a4ee46d 2003-11-23 devnull for(i = 0; i < n; i++)
401 7a4ee46d 2003-11-23 devnull if(fmtprint(f, "%s\t%llud\t%llud\n", am[i].name, am[i].start, am[i].stop) < 0)
402 7a4ee46d 2003-11-23 devnull return -1;
403 7a4ee46d 2003-11-23 devnull return 0;
404 7a4ee46d 2003-11-23 devnull }