]>
Commit | Line | Data |
---|---|---|
fecd2382 | 1 | /* subsegs.c - subsegments - |
cc886e3d SS |
2 | Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994 |
3 | Free Software Foundation, Inc. | |
604633ae | 4 | |
a39116f1 | 5 | This file is part of GAS, the GNU Assembler. |
604633ae | 6 | |
a39116f1 RP |
7 | GAS is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
604633ae | 11 | |
a39116f1 RP |
12 | GAS is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
604633ae | 16 | |
a39116f1 RP |
17 | You should have received a copy of the GNU General Public License |
18 | along with GAS; see the file COPYING. If not, write to | |
1356d77d | 19 | the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
fecd2382 RP |
20 | |
21 | /* | |
22 | * Segments & sub-segments. | |
23 | */ | |
24 | ||
25 | #include "as.h" | |
26 | ||
27 | #include "subsegs.h" | |
28 | #include "obstack.h" | |
29 | ||
604633ae ILT |
30 | frchainS *frchain_root, *frchain_now; |
31 | ||
d19dcb67 KR |
32 | static struct obstack frchains; |
33 | ||
604633ae | 34 | #ifndef BFD_ASSEMBLER |
a39116f1 RP |
35 | #ifdef MANY_SEGMENTS |
36 | segment_info_type segment_info[SEG_MAXIMUM_ORDINAL]; | |
37 | ||
a39116f1 | 38 | #else |
604633ae ILT |
39 | /* Commented in "subsegs.h". */ |
40 | frchainS *data0_frchainP, *bss0_frchainP; | |
fecd2382 | 41 | |
604633ae | 42 | #endif /* MANY_SEGMENTS */ |
1356d77d | 43 | char const *const seg_name[] = |
604633ae ILT |
44 | { |
45 | "absolute", | |
a39116f1 | 46 | #ifdef MANY_SEGMENTS |
604633ae | 47 | "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", |
a39116f1 | 48 | #else |
604633ae ILT |
49 | "text", |
50 | "data", | |
51 | "bss", | |
52 | #endif /* MANY_SEGMENTS */ | |
53 | "unknown", | |
54 | "ASSEMBLER-INTERNAL-LOGIC-ERROR!", | |
55 | "expr", | |
56 | "debug", | |
57 | "transfert vector preload", | |
58 | "transfert vector postload", | |
59 | "register", | |
60 | "", | |
61 | }; /* Used by error reporters, dumpers etc. */ | |
dff770c8 ILT |
62 | #else /* BFD_ASSEMBLER */ |
63 | ||
64 | /* Gas segment information for bfd_abs_section_ptr and | |
65 | bfd_und_section_ptr. */ | |
66 | static segment_info_type *abs_seg_info; | |
67 | static segment_info_type *und_seg_info; | |
68 | ||
604633ae | 69 | #endif /* BFD_ASSEMBLER */ |
fecd2382 | 70 | |
604633ae | 71 | static void subseg_set_rest PARAMS ((segT, subsegT)); |
d19dcb67 KR |
72 | |
73 | static fragS dummy_frag; | |
74 | ||
75 | static frchainS absolute_frchain; | |
fecd2382 RP |
76 | \f |
77 | void | |
604633ae | 78 | subsegs_begin () |
fecd2382 | 79 | { |
604633ae ILT |
80 | /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */ |
81 | #if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER) | |
82 | know (SEG_ABSOLUTE == 0); | |
83 | know (SEG_TEXT == 1); | |
84 | know (SEG_DATA == 2); | |
85 | know (SEG_BSS == 3); | |
86 | know (SEG_UNKNOWN == 4); | |
87 | know (SEG_GOOF == 5); | |
88 | know (SEG_EXPR == 6); | |
89 | know (SEG_DEBUG == 7); | |
90 | know (SEG_NTV == 8); | |
91 | know (SEG_PTV == 9); | |
92 | know (SEG_REGISTER == 10); | |
93 | know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER); | |
a39116f1 | 94 | #endif |
604633ae | 95 | |
d19dcb67 KR |
96 | obstack_begin (&frchains, chunksize); |
97 | #if __GNUC__ >= 2 | |
98 | obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1; | |
99 | #endif | |
100 | ||
604633ae ILT |
101 | frchain_root = NULL; |
102 | frchain_now = NULL; /* Warn new_subseg() that we are booting. */ | |
d19dcb67 KR |
103 | |
104 | frag_now = &dummy_frag; | |
604633ae ILT |
105 | |
106 | #ifndef BFD_ASSEMBLER | |
604633ae | 107 | now_subseg = 42; /* Lie for 1st call to subseg_new. */ |
a39116f1 | 108 | #ifdef MANY_SEGMENTS |
604633ae ILT |
109 | { |
110 | int i; | |
111 | for (i = SEG_E0; i < SEG_UNKNOWN; i++) | |
112 | { | |
113 | subseg_set (i, 0); | |
114 | segment_info[i].frchainP = frchain_now; | |
115 | } | |
116 | } | |
a39116f1 | 117 | #else |
604633ae ILT |
118 | subseg_set (SEG_DATA, 0); /* .data 0 */ |
119 | data0_frchainP = frchain_now; | |
65bfcf2e | 120 | |
604633ae ILT |
121 | subseg_set (SEG_BSS, 0); |
122 | bss0_frchainP = frchain_now; | |
123 | ||
124 | #endif /* ! MANY_SEGMENTS */ | |
125 | #endif /* ! BFD_ASSEMBLER */ | |
65bfcf2e | 126 | |
d19dcb67 KR |
127 | absolute_frchain.frch_seg = absolute_section; |
128 | absolute_frchain.frch_subseg = 0; | |
129 | absolute_frchain.fix_root = absolute_frchain.fix_tail = 0; | |
130 | absolute_frchain.frch_frag_now = &zero_address_frag; | |
131 | absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag; | |
fecd2382 RP |
132 | } |
133 | \f | |
134 | /* | |
135 | * subseg_change() | |
136 | * | |
137 | * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the | |
138 | * subsegment. If we are already in the correct subsegment, change nothing. | |
604633ae | 139 | * This is used eg as a worker for subseg_set [which does make a new frag_now] |
fecd2382 RP |
140 | * and for changing segments after we have read the source. We construct eg |
141 | * fixSs even after the source file is read, so we do have to keep the | |
142 | * segment context correct. | |
143 | */ | |
144 | void | |
604633ae ILT |
145 | subseg_change (seg, subseg) |
146 | register segT seg; | |
147 | register int subseg; | |
fecd2382 | 148 | { |
604633ae ILT |
149 | now_seg = seg; |
150 | now_subseg = subseg; | |
151 | ||
d19dcb67 KR |
152 | if (now_seg == absolute_section) |
153 | return; | |
154 | ||
604633ae ILT |
155 | #ifdef BFD_ASSEMBLER |
156 | { | |
157 | segment_info_type *seginfo; | |
158 | seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg); | |
159 | if (! seginfo) | |
160 | { | |
161 | seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); | |
3c498933 | 162 | memset ((PTR) seginfo, 0, sizeof (*seginfo)); |
dff770c8 ILT |
163 | seginfo->fix_root = NULL; |
164 | seginfo->fix_tail = NULL; | |
604633ae ILT |
165 | seginfo->bfd_section = seg; |
166 | seginfo->sym = 0; | |
dff770c8 ILT |
167 | if (seg == bfd_abs_section_ptr) |
168 | abs_seg_info = seginfo; | |
169 | else if (seg == bfd_und_section_ptr) | |
170 | und_seg_info = seginfo; | |
171 | else | |
172 | bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo); | |
604633ae ILT |
173 | } |
174 | } | |
175 | #else | |
a39116f1 | 176 | #ifdef MANY_SEGMENTS |
604633ae ILT |
177 | seg_fix_rootP = &segment_info[seg].fix_root; |
178 | seg_fix_tailP = &segment_info[seg].fix_tail; | |
a39116f1 | 179 | #else |
604633ae ILT |
180 | if (seg == SEG_DATA) |
181 | { | |
182 | seg_fix_rootP = &data_fix_root; | |
183 | seg_fix_tailP = &data_fix_tail; | |
184 | } | |
185 | else if (seg == SEG_TEXT) | |
186 | { | |
187 | seg_fix_rootP = &text_fix_root; | |
188 | seg_fix_tailP = &text_fix_tail; | |
189 | } | |
190 | else | |
191 | { | |
192 | know (seg == SEG_BSS); | |
193 | seg_fix_rootP = &bss_fix_root; | |
194 | seg_fix_tailP = &bss_fix_tail; | |
195 | } | |
196 | ||
197 | #endif | |
a39116f1 | 198 | #endif |
fecd2382 RP |
199 | } |
200 | \f | |
604633ae ILT |
201 | static void |
202 | subseg_set_rest (seg, subseg) | |
203 | segT seg; | |
204 | subsegT subseg; | |
205 | { | |
206 | long tmp; /* JF for obstack alignment hacking */ | |
207 | register frchainS *frcP; /* crawl frchain chain */ | |
208 | register frchainS **lastPP; /* address of last pointer */ | |
209 | frchainS *newP; /* address of new frchain */ | |
210 | register fragS *former_last_fragP; | |
211 | register fragS *new_fragP; | |
212 | ||
d19dcb67 KR |
213 | mri_common_symbol = NULL; |
214 | ||
215 | if (frag_now && frchain_now) | |
216 | frchain_now->frch_frag_now = frag_now; | |
217 | ||
218 | assert (frchain_now == 0 | |
219 | || now_seg == undefined_section | |
220 | || now_seg == absolute_section | |
221 | || frchain_now->frch_last == frag_now); | |
222 | ||
223 | subseg_change (seg, (int) subseg); | |
224 | ||
225 | if (seg == absolute_section) | |
604633ae | 226 | { |
d19dcb67 KR |
227 | frchain_now = &absolute_frchain; |
228 | frag_now = &zero_address_frag; | |
229 | return; | |
604633ae | 230 | } |
d19dcb67 KR |
231 | |
232 | assert (frchain_now == 0 | |
233 | || now_seg == undefined_section | |
234 | || frchain_now->frch_last == frag_now); | |
235 | ||
604633ae ILT |
236 | /* |
237 | * Attempt to find or make a frchain for that sub seg. | |
238 | * Crawl along chain of frchainSs, begins @ frchain_root. | |
239 | * If we need to make a frchainS, link it into correct | |
240 | * position of chain rooted in frchain_root. | |
241 | */ | |
242 | for (frcP = *(lastPP = &frchain_root); | |
3b6d6f71 | 243 | frcP && frcP->frch_seg <= seg; |
604633ae ILT |
244 | frcP = *(lastPP = &frcP->frch_next)) |
245 | { | |
3b6d6f71 | 246 | if (frcP->frch_seg == seg |
604633ae ILT |
247 | && frcP->frch_subseg >= subseg) |
248 | { | |
249 | break; | |
250 | } | |
251 | } | |
252 | /* | |
253 | * frcP: Address of the 1st frchainS in correct segment with | |
254 | * frch_subseg >= subseg. | |
255 | * We want to either use this frchainS, or we want | |
256 | * to insert a new frchainS just before it. | |
257 | * | |
258 | * If frcP==NULL, then we are at the end of the chain | |
259 | * of frchainS-s. A NULL frcP means we fell off the end | |
260 | * of the chain looking for a | |
261 | * frch_subseg >= subseg, so we | |
262 | * must make a new frchainS. | |
263 | * | |
264 | * If we ever maintain a pointer to | |
265 | * the last frchainS in the chain, we change that pointer | |
266 | * ONLY when frcP==NULL. | |
267 | * | |
268 | * lastPP: Address of the pointer with value frcP; | |
269 | * Never NULL. | |
270 | * May point to frchain_root. | |
271 | * | |
272 | */ | |
273 | if (!frcP | |
3b6d6f71 | 274 | || (frcP->frch_seg > seg |
604633ae ILT |
275 | || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */ |
276 | { | |
277 | /* | |
278 | * This should be the only code that creates a frchainS. | |
279 | */ | |
d19dcb67 KR |
280 | extern fragS *frag_alloc (); |
281 | newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS)); | |
1356d77d | 282 | newP->frch_subseg = subseg; |
604633ae | 283 | newP->frch_seg = seg; |
cc886e3d SS |
284 | #ifdef BFD_ASSEMBLER |
285 | newP->fix_root = NULL; | |
286 | newP->fix_tail = NULL; | |
287 | #endif | |
1356d77d | 288 | obstack_begin (&newP->frch_obstack, 5000); |
d19dcb67 KR |
289 | #if __GNUC__ >= 2 |
290 | obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1; | |
291 | #endif | |
292 | newP->frch_frag_now = frag_alloc (&newP->frch_obstack); | |
293 | newP->frch_frag_now->fr_type = rs_fill; | |
294 | ||
295 | newP->frch_root = newP->frch_last = newP->frch_frag_now; | |
1356d77d ILT |
296 | |
297 | *lastPP = newP; | |
298 | newP->frch_next = frcP; /* perhaps NULL */ | |
299 | frcP = newP; | |
604633ae ILT |
300 | } |
301 | /* | |
1356d77d | 302 | * Here with frcP pointing to the frchainS for subseg. |
604633ae ILT |
303 | */ |
304 | frchain_now = frcP; | |
d19dcb67 | 305 | frag_now = frcP->frch_frag_now; |
1356d77d | 306 | |
d19dcb67 | 307 | assert (frchain_now->frch_last == frag_now); |
604633ae ILT |
308 | } |
309 | ||
fecd2382 | 310 | /* |
604633ae | 311 | * subseg_set(segT, subsegT) |
fecd2382 RP |
312 | * |
313 | * If you attempt to change to the current subsegment, nothing happens. | |
314 | * | |
315 | * In: segT, subsegT code for new subsegment. | |
316 | * frag_now -> incomplete frag for current subsegment. | |
317 | * If frag_now==NULL, then there is no old, incomplete frag, so | |
318 | * the old frag is not closed off. | |
319 | * | |
320 | * Out: now_subseg, now_seg updated. | |
321 | * Frchain_now points to the (possibly new) struct frchain for this | |
322 | * sub-segment. | |
323 | * Frchain_root updated if needed. | |
324 | */ | |
325 | ||
604633ae ILT |
326 | #ifndef BFD_ASSEMBLER |
327 | ||
328 | segT | |
329 | subseg_new (segname, subseg) | |
330 | const char *segname; | |
331 | subsegT subseg; | |
fecd2382 | 332 | { |
604633ae ILT |
333 | int i; |
334 | ||
335 | for (i = 0; i < (int) SEG_MAXIMUM_ORDINAL; i++) | |
336 | { | |
337 | const char *s; | |
338 | ||
339 | s = segment_name ((segT) i); | |
340 | if (strcmp (segname, s) == 0 | |
341 | || (segname[0] == '.' | |
342 | && strcmp (segname + 1, s) == 0)) | |
f8701a3f | 343 | { |
604633ae ILT |
344 | subseg_set ((segT) i, subseg); |
345 | return (segT) i; | |
346 | } | |
347 | #ifdef obj_segment_name | |
348 | s = obj_segment_name ((segT) i); | |
349 | if (strcmp (segname, s) == 0 | |
350 | || (segname[0] == '.' | |
351 | && strcmp (segname + 1, s) == 0)) | |
352 | { | |
353 | subseg_set ((segT) i, subseg); | |
354 | return (segT) i; | |
f8701a3f | 355 | } |
a39116f1 | 356 | #endif |
604633ae | 357 | } |
fecd2382 | 358 | |
604633ae ILT |
359 | #ifdef obj_add_segment |
360 | { | |
361 | segT new_seg; | |
362 | new_seg = obj_add_segment (segname); | |
363 | subseg_set (new_seg, subseg); | |
364 | return new_seg; | |
365 | } | |
366 | #else | |
367 | as_bad ("Attempt to switch to nonexistent segment \"%s\"", segname); | |
368 | return now_seg; | |
369 | #endif | |
370 | } | |
371 | ||
372 | void | |
373 | subseg_set (seg, subseg) /* begin assembly for a new sub-segment */ | |
374 | register segT seg; /* SEG_DATA or SEG_TEXT */ | |
375 | register subsegT subseg; | |
376 | { | |
377 | #ifndef MANY_SEGMENTS | |
d19dcb67 KR |
378 | know (seg == SEG_DATA |
379 | || seg == SEG_TEXT | |
380 | || seg == SEG_BSS | |
381 | || seg == SEG_ABSOLUTE); | |
604633ae ILT |
382 | #endif |
383 | ||
384 | if (seg != now_seg || subseg != now_subseg) | |
385 | { /* we just changed sub-segments */ | |
386 | subseg_set_rest (seg, subseg); | |
387 | } | |
1356d77d | 388 | mri_common_symbol = NULL; |
604633ae ILT |
389 | } |
390 | ||
391 | #else /* BFD_ASSEMBLER */ | |
392 | ||
393 | segT | |
d025bc7b | 394 | subseg_get (segname, force_new) |
604633ae | 395 | const char *segname; |
d025bc7b | 396 | int force_new; |
604633ae ILT |
397 | { |
398 | segT secptr; | |
399 | segment_info_type *seginfo; | |
400 | const char *now_seg_name = (now_seg | |
401 | ? bfd_get_section_name (stdoutput, now_seg) | |
402 | : 0); | |
403 | ||
d025bc7b JL |
404 | if (!force_new |
405 | && now_seg_name | |
604633ae | 406 | && (now_seg_name == segname |
d025bc7b | 407 | || !strcmp (now_seg_name, segname))) |
604633ae ILT |
408 | return now_seg; |
409 | ||
d025bc7b JL |
410 | if (!force_new) |
411 | secptr = bfd_make_section_old_way (stdoutput, segname); | |
412 | else | |
413 | secptr = bfd_make_section_anyway (stdoutput, segname); | |
414 | ||
604633ae ILT |
415 | seginfo = seg_info (secptr); |
416 | if (! seginfo) | |
417 | { | |
dff770c8 ILT |
418 | /* Check whether output_section is set first because secptr may |
419 | be bfd_abs_section_ptr. */ | |
420 | if (secptr->output_section != secptr) | |
421 | secptr->output_section = secptr; | |
604633ae | 422 | seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); |
3c498933 | 423 | memset ((PTR) seginfo, 0, sizeof (*seginfo)); |
cc886e3d | 424 | seginfo->fix_root = NULL; |
dff770c8 | 425 | seginfo->fix_tail = NULL; |
604633ae | 426 | seginfo->bfd_section = secptr; |
dff770c8 ILT |
427 | if (secptr == bfd_abs_section_ptr) |
428 | abs_seg_info = seginfo; | |
429 | else if (secptr == bfd_und_section_ptr) | |
430 | und_seg_info = seginfo; | |
431 | else | |
432 | bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo); | |
cc886e3d SS |
433 | seginfo->frchainP = NULL; |
434 | seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL; | |
435 | seginfo->sym = NULL; | |
436 | seginfo->dot = NULL; | |
604633ae | 437 | } |
d025bc7b JL |
438 | return secptr; |
439 | } | |
440 | ||
441 | segT | |
442 | subseg_new (segname, subseg) | |
443 | const char *segname; | |
444 | subsegT subseg; | |
445 | { | |
446 | segT secptr; | |
447 | segment_info_type *seginfo; | |
448 | ||
449 | secptr = subseg_get (segname, 0); | |
450 | subseg_set_rest (secptr, subseg); | |
451 | seginfo = seg_info (secptr); | |
452 | if (! seginfo->frchainP) | |
453 | seginfo->frchainP = frchain_now; | |
454 | return secptr; | |
455 | } | |
456 | ||
457 | /* Like subseg_new, except a new section is always created, even if | |
458 | a section with that name already exists. */ | |
459 | segT | |
460 | subseg_force_new (segname, subseg) | |
461 | const char *segname; | |
462 | subsegT subseg; | |
463 | { | |
464 | segT secptr; | |
465 | segment_info_type *seginfo; | |
466 | ||
467 | secptr = subseg_get (segname, 1); | |
468 | subseg_set_rest (secptr, subseg); | |
469 | seginfo = seg_info (secptr); | |
470 | if (! seginfo->frchainP) | |
471 | seginfo->frchainP = frchain_now; | |
604633ae ILT |
472 | return secptr; |
473 | } | |
474 | ||
475 | void | |
476 | subseg_set (secptr, subseg) | |
477 | segT secptr; | |
478 | subsegT subseg; | |
479 | { | |
480 | if (! (secptr == now_seg && subseg == now_subseg)) | |
481 | subseg_set_rest (secptr, subseg); | |
1356d77d | 482 | mri_common_symbol = NULL; |
604633ae ILT |
483 | } |
484 | ||
cc886e3d SS |
485 | #ifndef obj_sec_sym_ok_for_reloc |
486 | #define obj_sec_sym_ok_for_reloc(SEC) 0 | |
487 | #endif | |
488 | ||
dff770c8 ILT |
489 | /* Get the gas information we are storing for a section. */ |
490 | ||
491 | segment_info_type * | |
492 | seg_info (sec) | |
493 | segT sec; | |
494 | { | |
495 | if (sec == bfd_abs_section_ptr) | |
496 | return abs_seg_info; | |
497 | else if (sec == bfd_und_section_ptr) | |
498 | return und_seg_info; | |
499 | else | |
500 | return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec); | |
501 | } | |
502 | ||
d025bc7b JL |
503 | symbolS * |
504 | section_symbol (sec) | |
505 | segT sec; | |
506 | { | |
507 | segment_info_type *seginfo = seg_info (sec); | |
cc886e3d | 508 | symbolS *s; |
d025bc7b JL |
509 | |
510 | if (seginfo == 0) | |
511 | abort (); | |
512 | if (seginfo->sym) | |
513 | return seginfo->sym; | |
cc886e3d SS |
514 | s = symbol_find (sec->name); |
515 | if (!s) | |
d025bc7b | 516 | { |
3c498933 KR |
517 | #ifndef EMIT_SECTION_SYMBOLS |
518 | #define EMIT_SECTION_SYMBOLS 1 | |
519 | #endif | |
520 | ||
1356d77d | 521 | if (! EMIT_SECTION_SYMBOLS |
3c498933 KR |
522 | #ifdef BFD_ASSEMBLER |
523 | && symbol_table_frozen | |
524 | #endif | |
525 | ) | |
1356d77d | 526 | /* Here we know it won't be going into the symbol table. */ |
3c498933 | 527 | s = symbol_create (sec->name, sec, 0, &zero_address_frag); |
1356d77d ILT |
528 | else |
529 | s = symbol_new (sec->name, sec, 0, &zero_address_frag); | |
cc886e3d SS |
530 | S_CLEAR_EXTERNAL (s); |
531 | ||
532 | /* Use the BFD section symbol, if possible. */ | |
533 | if (obj_sec_sym_ok_for_reloc (sec)) | |
534 | s->bsym = sec->symbol; | |
d025bc7b | 535 | } |
cc886e3d SS |
536 | seginfo->sym = s; |
537 | return s; | |
d025bc7b JL |
538 | } |
539 | ||
604633ae | 540 | #endif /* BFD_ASSEMBLER */ |
fecd2382 | 541 | |
8b228fe9 | 542 | /* end of subsegs.c */ |