13d8817e4Smiod /* subsegs.c - subsegments -
23d8817e4Smiod Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
33d8817e4Smiod 1999, 2000, 2001, 2002, 2003, 2004, 2005
43d8817e4Smiod Free Software Foundation, Inc.
53d8817e4Smiod
63d8817e4Smiod This file is part of GAS, the GNU Assembler.
73d8817e4Smiod
83d8817e4Smiod GAS is free software; you can redistribute it and/or modify
93d8817e4Smiod it under the terms of the GNU General Public License as published by
103d8817e4Smiod the Free Software Foundation; either version 2, or (at your option)
113d8817e4Smiod any later version.
123d8817e4Smiod
133d8817e4Smiod GAS is distributed in the hope that it will be useful,
143d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
153d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
163d8817e4Smiod GNU General Public License for more details.
173d8817e4Smiod
183d8817e4Smiod You should have received a copy of the GNU General Public License
193d8817e4Smiod along with GAS; see the file COPYING. If not, write to the Free
203d8817e4Smiod Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
213d8817e4Smiod 02110-1301, USA. */
223d8817e4Smiod
233d8817e4Smiod /* Segments & sub-segments. */
243d8817e4Smiod
253d8817e4Smiod #include "as.h"
263d8817e4Smiod
273d8817e4Smiod #include "subsegs.h"
283d8817e4Smiod #include "obstack.h"
293d8817e4Smiod
303d8817e4Smiod frchainS *frchain_root, *frchain_now;
313d8817e4Smiod
323d8817e4Smiod static struct obstack frchains;
333d8817e4Smiod
343d8817e4Smiod /* Gas segment information for bfd_abs_section_ptr and
353d8817e4Smiod bfd_und_section_ptr. */
363d8817e4Smiod static segment_info_type *abs_seg_info;
373d8817e4Smiod static segment_info_type *und_seg_info;
383d8817e4Smiod
393d8817e4Smiod static void subseg_set_rest (segT, subsegT);
403d8817e4Smiod
413d8817e4Smiod static fragS dummy_frag;
423d8817e4Smiod
433d8817e4Smiod static frchainS absolute_frchain;
443d8817e4Smiod
453d8817e4Smiod void
subsegs_begin(void)463d8817e4Smiod subsegs_begin (void)
473d8817e4Smiod {
483d8817e4Smiod obstack_begin (&frchains, chunksize);
493d8817e4Smiod #if __GNUC__ >= 2
503d8817e4Smiod obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
513d8817e4Smiod #endif
523d8817e4Smiod
533d8817e4Smiod frchain_root = NULL;
543d8817e4Smiod frchain_now = NULL; /* Warn new_subseg() that we are booting. */
553d8817e4Smiod
563d8817e4Smiod frag_now = &dummy_frag;
573d8817e4Smiod
583d8817e4Smiod absolute_frchain.frch_seg = absolute_section;
593d8817e4Smiod absolute_frchain.frch_subseg = 0;
603d8817e4Smiod absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
613d8817e4Smiod absolute_frchain.frch_frag_now = &zero_address_frag;
623d8817e4Smiod absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
633d8817e4Smiod }
643d8817e4Smiod
653d8817e4Smiod /*
663d8817e4Smiod * subseg_change()
673d8817e4Smiod *
683d8817e4Smiod * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the
693d8817e4Smiod * subsegment. If we are already in the correct subsegment, change nothing.
703d8817e4Smiod * This is used eg as a worker for subseg_set [which does make a new frag_now]
713d8817e4Smiod * and for changing segments after we have read the source. We construct eg
723d8817e4Smiod * fixSs even after the source file is read, so we do have to keep the
733d8817e4Smiod * segment context correct.
743d8817e4Smiod */
753d8817e4Smiod void
subseg_change(register segT seg,register int subseg)763d8817e4Smiod subseg_change (register segT seg, register int subseg)
773d8817e4Smiod {
783d8817e4Smiod segment_info_type *seginfo;
793d8817e4Smiod now_seg = seg;
803d8817e4Smiod now_subseg = subseg;
813d8817e4Smiod
823d8817e4Smiod if (now_seg == absolute_section)
833d8817e4Smiod return;
843d8817e4Smiod
853d8817e4Smiod seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg);
863d8817e4Smiod if (! seginfo)
873d8817e4Smiod {
883d8817e4Smiod seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
893d8817e4Smiod memset ((PTR) seginfo, 0, sizeof (*seginfo));
903d8817e4Smiod seginfo->fix_root = NULL;
913d8817e4Smiod seginfo->fix_tail = NULL;
923d8817e4Smiod seginfo->bfd_section = seg;
933d8817e4Smiod seginfo->sym = 0;
943d8817e4Smiod if (seg == bfd_abs_section_ptr)
953d8817e4Smiod abs_seg_info = seginfo;
963d8817e4Smiod else if (seg == bfd_und_section_ptr)
973d8817e4Smiod und_seg_info = seginfo;
983d8817e4Smiod else
993d8817e4Smiod bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
1003d8817e4Smiod }
1013d8817e4Smiod }
1023d8817e4Smiod
1033d8817e4Smiod static void
subseg_set_rest(segT seg,subsegT subseg)1043d8817e4Smiod subseg_set_rest (segT seg, subsegT subseg)
1053d8817e4Smiod {
1063d8817e4Smiod register frchainS *frcP; /* crawl frchain chain */
1073d8817e4Smiod register frchainS **lastPP; /* address of last pointer */
1083d8817e4Smiod frchainS *newP; /* address of new frchain */
1093d8817e4Smiod
1103d8817e4Smiod mri_common_symbol = NULL;
1113d8817e4Smiod
1123d8817e4Smiod if (frag_now && frchain_now)
1133d8817e4Smiod frchain_now->frch_frag_now = frag_now;
1143d8817e4Smiod
1153d8817e4Smiod assert (frchain_now == 0
1163d8817e4Smiod || now_seg == undefined_section
1173d8817e4Smiod || now_seg == absolute_section
1183d8817e4Smiod || frchain_now->frch_last == frag_now);
1193d8817e4Smiod
1203d8817e4Smiod subseg_change (seg, (int) subseg);
1213d8817e4Smiod
1223d8817e4Smiod if (seg == absolute_section)
1233d8817e4Smiod {
1243d8817e4Smiod frchain_now = &absolute_frchain;
1253d8817e4Smiod frag_now = &zero_address_frag;
1263d8817e4Smiod return;
1273d8817e4Smiod }
1283d8817e4Smiod
1293d8817e4Smiod assert (frchain_now == 0
1303d8817e4Smiod || now_seg == undefined_section
1313d8817e4Smiod || frchain_now->frch_last == frag_now);
1323d8817e4Smiod
1333d8817e4Smiod /*
1343d8817e4Smiod * Attempt to find or make a frchain for that sub seg.
1353d8817e4Smiod * Crawl along chain of frchainSs, begins @ frchain_root.
1363d8817e4Smiod * If we need to make a frchainS, link it into correct
1373d8817e4Smiod * position of chain rooted in frchain_root.
1383d8817e4Smiod */
1393d8817e4Smiod for (frcP = *(lastPP = &frchain_root);
1403d8817e4Smiod frcP && frcP->frch_seg <= seg;
1413d8817e4Smiod frcP = *(lastPP = &frcP->frch_next))
1423d8817e4Smiod {
1433d8817e4Smiod if (frcP->frch_seg == seg
1443d8817e4Smiod && frcP->frch_subseg >= subseg)
1453d8817e4Smiod {
1463d8817e4Smiod break;
1473d8817e4Smiod }
1483d8817e4Smiod }
1493d8817e4Smiod /*
1503d8817e4Smiod * frcP: Address of the 1st frchainS in correct segment with
1513d8817e4Smiod * frch_subseg >= subseg.
1523d8817e4Smiod * We want to either use this frchainS, or we want
1533d8817e4Smiod * to insert a new frchainS just before it.
1543d8817e4Smiod *
1553d8817e4Smiod * If frcP==NULL, then we are at the end of the chain
1563d8817e4Smiod * of frchainS-s. A NULL frcP means we fell off the end
1573d8817e4Smiod * of the chain looking for a
1583d8817e4Smiod * frch_subseg >= subseg, so we
1593d8817e4Smiod * must make a new frchainS.
1603d8817e4Smiod *
1613d8817e4Smiod * If we ever maintain a pointer to
1623d8817e4Smiod * the last frchainS in the chain, we change that pointer
1633d8817e4Smiod * ONLY when frcP==NULL.
1643d8817e4Smiod *
1653d8817e4Smiod * lastPP: Address of the pointer with value frcP;
1663d8817e4Smiod * Never NULL.
1673d8817e4Smiod * May point to frchain_root.
1683d8817e4Smiod *
1693d8817e4Smiod */
1703d8817e4Smiod if (!frcP
1713d8817e4Smiod || (frcP->frch_seg > seg
1723d8817e4Smiod || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
1733d8817e4Smiod {
1743d8817e4Smiod /*
1753d8817e4Smiod * This should be the only code that creates a frchainS.
1763d8817e4Smiod */
1773d8817e4Smiod segment_info_type *seginfo;
1783d8817e4Smiod
1793d8817e4Smiod newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
1803d8817e4Smiod newP->frch_subseg = subseg;
1813d8817e4Smiod newP->frch_seg = seg;
1823d8817e4Smiod newP->fix_root = NULL;
1833d8817e4Smiod newP->fix_tail = NULL;
1843d8817e4Smiod obstack_begin (&newP->frch_obstack, chunksize);
1853d8817e4Smiod #if __GNUC__ >= 2
1863d8817e4Smiod obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
1873d8817e4Smiod #endif
1883d8817e4Smiod newP->frch_frag_now = frag_alloc (&newP->frch_obstack);
1893d8817e4Smiod newP->frch_frag_now->fr_type = rs_fill;
190*a51f8248Skettenis newP->frch_cfi_data = NULL;
1913d8817e4Smiod
1923d8817e4Smiod newP->frch_root = newP->frch_last = newP->frch_frag_now;
1933d8817e4Smiod
1943d8817e4Smiod *lastPP = newP;
1953d8817e4Smiod newP->frch_next = frcP; /* perhaps NULL */
1963d8817e4Smiod
1973d8817e4Smiod seginfo = seg_info (seg);
1983d8817e4Smiod if (seginfo && (!seginfo->frchainP || seginfo->frchainP == frcP))
1993d8817e4Smiod seginfo->frchainP = newP;
2003d8817e4Smiod
2013d8817e4Smiod frcP = newP;
2023d8817e4Smiod }
2033d8817e4Smiod /*
2043d8817e4Smiod * Here with frcP pointing to the frchainS for subseg.
2053d8817e4Smiod */
2063d8817e4Smiod frchain_now = frcP;
2073d8817e4Smiod frag_now = frcP->frch_frag_now;
2083d8817e4Smiod
2093d8817e4Smiod assert (frchain_now->frch_last == frag_now);
2103d8817e4Smiod }
2113d8817e4Smiod
2123d8817e4Smiod /*
2133d8817e4Smiod * subseg_set(segT, subsegT)
2143d8817e4Smiod *
2153d8817e4Smiod * If you attempt to change to the current subsegment, nothing happens.
2163d8817e4Smiod *
2173d8817e4Smiod * In: segT, subsegT code for new subsegment.
2183d8817e4Smiod * frag_now -> incomplete frag for current subsegment.
2193d8817e4Smiod * If frag_now==NULL, then there is no old, incomplete frag, so
2203d8817e4Smiod * the old frag is not closed off.
2213d8817e4Smiod *
2223d8817e4Smiod * Out: now_subseg, now_seg updated.
2233d8817e4Smiod * Frchain_now points to the (possibly new) struct frchain for this
2243d8817e4Smiod * sub-segment.
2253d8817e4Smiod * Frchain_root updated if needed.
2263d8817e4Smiod */
2273d8817e4Smiod
2283d8817e4Smiod segT
subseg_get(const char * segname,int force_new)2293d8817e4Smiod subseg_get (const char *segname, int force_new)
2303d8817e4Smiod {
2313d8817e4Smiod segT secptr;
2323d8817e4Smiod segment_info_type *seginfo;
2333d8817e4Smiod const char *now_seg_name = (now_seg
2343d8817e4Smiod ? bfd_get_section_name (stdoutput, now_seg)
2353d8817e4Smiod : 0);
2363d8817e4Smiod
2373d8817e4Smiod if (!force_new
2383d8817e4Smiod && now_seg_name
2393d8817e4Smiod && (now_seg_name == segname
2403d8817e4Smiod || !strcmp (now_seg_name, segname)))
2413d8817e4Smiod return now_seg;
2423d8817e4Smiod
2433d8817e4Smiod if (!force_new)
2443d8817e4Smiod secptr = bfd_make_section_old_way (stdoutput, segname);
2453d8817e4Smiod else
2463d8817e4Smiod secptr = bfd_make_section_anyway (stdoutput, segname);
2473d8817e4Smiod
2483d8817e4Smiod #ifdef obj_sec_set_private_data
2493d8817e4Smiod obj_sec_set_private_data (stdoutput, secptr);
2503d8817e4Smiod #endif
2513d8817e4Smiod
2523d8817e4Smiod seginfo = seg_info (secptr);
2533d8817e4Smiod if (! seginfo)
2543d8817e4Smiod {
2553d8817e4Smiod /* Check whether output_section is set first because secptr may
2563d8817e4Smiod be bfd_abs_section_ptr. */
2573d8817e4Smiod if (secptr->output_section != secptr)
2583d8817e4Smiod secptr->output_section = secptr;
2593d8817e4Smiod seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
2603d8817e4Smiod memset ((PTR) seginfo, 0, sizeof (*seginfo));
2613d8817e4Smiod seginfo->fix_root = NULL;
2623d8817e4Smiod seginfo->fix_tail = NULL;
2633d8817e4Smiod seginfo->bfd_section = secptr;
2643d8817e4Smiod if (secptr == bfd_abs_section_ptr)
2653d8817e4Smiod abs_seg_info = seginfo;
2663d8817e4Smiod else if (secptr == bfd_und_section_ptr)
2673d8817e4Smiod und_seg_info = seginfo;
2683d8817e4Smiod else
2693d8817e4Smiod bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
2703d8817e4Smiod seginfo->frchainP = NULL;
2713d8817e4Smiod seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
2723d8817e4Smiod seginfo->sym = NULL;
2733d8817e4Smiod seginfo->dot = NULL;
2743d8817e4Smiod }
2753d8817e4Smiod return secptr;
2763d8817e4Smiod }
2773d8817e4Smiod
2783d8817e4Smiod segT
subseg_new(const char * segname,subsegT subseg)2793d8817e4Smiod subseg_new (const char *segname, subsegT subseg)
2803d8817e4Smiod {
2813d8817e4Smiod segT secptr;
2823d8817e4Smiod segment_info_type *seginfo;
2833d8817e4Smiod
2843d8817e4Smiod secptr = subseg_get (segname, 0);
2853d8817e4Smiod subseg_set_rest (secptr, subseg);
2863d8817e4Smiod seginfo = seg_info (secptr);
2873d8817e4Smiod if (! seginfo->frchainP)
2883d8817e4Smiod seginfo->frchainP = frchain_now;
2893d8817e4Smiod return secptr;
2903d8817e4Smiod }
2913d8817e4Smiod
2923d8817e4Smiod /* Like subseg_new, except a new section is always created, even if
2933d8817e4Smiod a section with that name already exists. */
2943d8817e4Smiod segT
subseg_force_new(const char * segname,subsegT subseg)2953d8817e4Smiod subseg_force_new (const char *segname, subsegT subseg)
2963d8817e4Smiod {
2973d8817e4Smiod segT secptr;
2983d8817e4Smiod segment_info_type *seginfo;
2993d8817e4Smiod
3003d8817e4Smiod secptr = subseg_get (segname, 1);
3013d8817e4Smiod subseg_set_rest (secptr, subseg);
3023d8817e4Smiod seginfo = seg_info (secptr);
3033d8817e4Smiod if (! seginfo->frchainP)
3043d8817e4Smiod seginfo->frchainP = frchain_now;
3053d8817e4Smiod return secptr;
3063d8817e4Smiod }
3073d8817e4Smiod
3083d8817e4Smiod void
subseg_set(segT secptr,subsegT subseg)3093d8817e4Smiod subseg_set (segT secptr, subsegT subseg)
3103d8817e4Smiod {
3113d8817e4Smiod if (! (secptr == now_seg && subseg == now_subseg))
3123d8817e4Smiod subseg_set_rest (secptr, subseg);
3133d8817e4Smiod mri_common_symbol = NULL;
3143d8817e4Smiod }
3153d8817e4Smiod
3163d8817e4Smiod #ifndef obj_sec_sym_ok_for_reloc
3173d8817e4Smiod #define obj_sec_sym_ok_for_reloc(SEC) 0
3183d8817e4Smiod #endif
3193d8817e4Smiod
3203d8817e4Smiod /* Get the gas information we are storing for a section. */
3213d8817e4Smiod
3223d8817e4Smiod segment_info_type *
seg_info(segT sec)3233d8817e4Smiod seg_info (segT sec)
3243d8817e4Smiod {
3253d8817e4Smiod if (sec == bfd_abs_section_ptr)
3263d8817e4Smiod return abs_seg_info;
3273d8817e4Smiod else if (sec == bfd_und_section_ptr)
3283d8817e4Smiod return und_seg_info;
3293d8817e4Smiod else
3303d8817e4Smiod return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
3313d8817e4Smiod }
3323d8817e4Smiod
3333d8817e4Smiod symbolS *
section_symbol(segT sec)3343d8817e4Smiod section_symbol (segT sec)
3353d8817e4Smiod {
3363d8817e4Smiod segment_info_type *seginfo = seg_info (sec);
3373d8817e4Smiod symbolS *s;
3383d8817e4Smiod
3393d8817e4Smiod if (seginfo == 0)
3403d8817e4Smiod abort ();
3413d8817e4Smiod if (seginfo->sym)
3423d8817e4Smiod return seginfo->sym;
3433d8817e4Smiod
3443d8817e4Smiod #ifndef EMIT_SECTION_SYMBOLS
3453d8817e4Smiod #define EMIT_SECTION_SYMBOLS 1
3463d8817e4Smiod #endif
3473d8817e4Smiod
3483d8817e4Smiod if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen)
3493d8817e4Smiod {
3503d8817e4Smiod /* Here we know it won't be going into the symbol table. */
3513d8817e4Smiod s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag);
3523d8817e4Smiod }
3533d8817e4Smiod else
3543d8817e4Smiod {
3553d8817e4Smiod segT seg;
3563d8817e4Smiod s = symbol_find (sec->symbol->name);
3573d8817e4Smiod /* We have to make sure it is the right symbol when we
3583d8817e4Smiod have multiple sections with the same section name. */
3593d8817e4Smiod if (s == NULL
3603d8817e4Smiod || ((seg = S_GET_SEGMENT (s)) != sec
3613d8817e4Smiod && seg != undefined_section))
3623d8817e4Smiod s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag);
3633d8817e4Smiod else if (seg == undefined_section)
3643d8817e4Smiod {
3653d8817e4Smiod S_SET_SEGMENT (s, sec);
3663d8817e4Smiod symbol_set_frag (s, &zero_address_frag);
3673d8817e4Smiod }
3683d8817e4Smiod }
3693d8817e4Smiod
3703d8817e4Smiod S_CLEAR_EXTERNAL (s);
3713d8817e4Smiod
3723d8817e4Smiod /* Use the BFD section symbol, if possible. */
3733d8817e4Smiod if (obj_sec_sym_ok_for_reloc (sec))
3743d8817e4Smiod symbol_set_bfdsym (s, sec->symbol);
3753d8817e4Smiod else
3763d8817e4Smiod symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM;
3773d8817e4Smiod
3783d8817e4Smiod seginfo->sym = s;
3793d8817e4Smiod return s;
3803d8817e4Smiod }
3813d8817e4Smiod
3823d8817e4Smiod /* Return whether the specified segment is thought to hold text. */
3833d8817e4Smiod
3843d8817e4Smiod int
subseg_text_p(segT sec)3853d8817e4Smiod subseg_text_p (segT sec)
3863d8817e4Smiod {
3873d8817e4Smiod return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0;
3883d8817e4Smiod }
3893d8817e4Smiod
3903d8817e4Smiod /* Return non zero if SEC has at least one byte of data. It is
3913d8817e4Smiod possible that we'll return zero even on a non-empty section because
3923d8817e4Smiod we don't know all the fragment types, and it is possible that an
3933d8817e4Smiod fr_fix == 0 one still contributes data. Think of this as
3943d8817e4Smiod seg_definitely_not_empty_p. */
3953d8817e4Smiod
3963d8817e4Smiod int
seg_not_empty_p(segT sec ATTRIBUTE_UNUSED)3973d8817e4Smiod seg_not_empty_p (segT sec ATTRIBUTE_UNUSED)
3983d8817e4Smiod {
3993d8817e4Smiod segment_info_type *seginfo = seg_info (sec);
4003d8817e4Smiod frchainS *chain;
4013d8817e4Smiod fragS *frag;
4023d8817e4Smiod
4033d8817e4Smiod if (!seginfo)
4043d8817e4Smiod return 0;
4053d8817e4Smiod
4063d8817e4Smiod for (chain = seginfo->frchainP; chain; chain = chain->frch_next)
4073d8817e4Smiod {
4083d8817e4Smiod for (frag = chain->frch_root; frag; frag = frag->fr_next)
4093d8817e4Smiod if (frag->fr_fix)
4103d8817e4Smiod return 1;
4113d8817e4Smiod if (obstack_next_free (&chain->frch_obstack)
4123d8817e4Smiod != chain->frch_last->fr_literal)
4133d8817e4Smiod return 1;
4143d8817e4Smiod }
4153d8817e4Smiod return 0;
4163d8817e4Smiod }
4173d8817e4Smiod
4183d8817e4Smiod void
subsegs_print_statistics(FILE * file)4193d8817e4Smiod subsegs_print_statistics (FILE *file)
4203d8817e4Smiod {
4213d8817e4Smiod frchainS *frchp;
4223d8817e4Smiod fprintf (file, "frag chains:\n");
4233d8817e4Smiod for (frchp = frchain_root; frchp; frchp = frchp->frch_next)
4243d8817e4Smiod {
4253d8817e4Smiod int count = 0;
4263d8817e4Smiod fragS *fragp;
4273d8817e4Smiod
4283d8817e4Smiod /* If frch_subseg is non-zero, it's probably been chained onto
4293d8817e4Smiod the end of a previous subsection. Don't count it again. */
4303d8817e4Smiod if (frchp->frch_subseg != 0)
4313d8817e4Smiod continue;
4323d8817e4Smiod
4333d8817e4Smiod /* Skip gas-internal sections. */
4343d8817e4Smiod if (segment_name (frchp->frch_seg)[0] == '*')
4353d8817e4Smiod continue;
4363d8817e4Smiod
4373d8817e4Smiod for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
4383d8817e4Smiod {
4393d8817e4Smiod count++;
4403d8817e4Smiod }
4413d8817e4Smiod fprintf (file, "\n");
4423d8817e4Smiod fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
4433d8817e4Smiod segment_name (frchp->frch_seg), count);
4443d8817e4Smiod }
4453d8817e4Smiod }
4463d8817e4Smiod
4473d8817e4Smiod /* end of subsegs.c */
448