OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [subsegs.c] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* subsegs.c - subsegments -
2
   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/* Segments & sub-segments.  */
24
 
25
#include "as.h"
26
 
27
#include "subsegs.h"
28
#include "obstack.h"
29
 
30
frchainS *frchain_now;
31
 
32
static struct obstack frchains;
33
 
34
static fragS dummy_frag;
35
 
36
 
37
void
38
subsegs_begin (void)
39
{
40
  obstack_begin (&frchains, chunksize);
41
#if __GNUC__ >= 2
42
  obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
43
#endif
44
 
45
  frchain_now = NULL;           /* Warn new_subseg() that we are booting.  */
46
  frag_now = &dummy_frag;
47
}
48
 
49
/*
50
 *                      subseg_change()
51
 *
52
 * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the
53
 * subsegment. If we are already in the correct subsegment, change nothing.
54
 * This is used eg as a worker for subseg_set [which does make a new frag_now]
55
 * and for changing segments after we have read the source. We construct eg
56
 * fixSs even after the source file is read, so we do have to keep the
57
 * segment context correct.
58
 */
59
void
60
subseg_change (register segT seg, register int subseg)
61
{
62
  segment_info_type *seginfo = seg_info (seg);
63
  now_seg = seg;
64
  now_subseg = subseg;
65
 
66
  if (! seginfo)
67
    {
68
      seginfo = (segment_info_type *) xcalloc (1, sizeof (*seginfo));
69
      seginfo->bfd_section = seg;
70
      bfd_set_section_userdata (stdoutput, seg, seginfo);
71
    }
72
}
73
 
74
static void
75
subseg_set_rest (segT seg, subsegT subseg)
76
{
77
  frchainS *frcP;               /* crawl frchain chain */
78
  frchainS **lastPP;            /* address of last pointer */
79
  frchainS *newP;               /* address of new frchain */
80
  segment_info_type *seginfo;
81
 
82
  mri_common_symbol = NULL;
83
 
84
  if (frag_now && frchain_now)
85
    frchain_now->frch_frag_now = frag_now;
86
 
87
  gas_assert (frchain_now == 0
88
          || frchain_now->frch_last == frag_now);
89
 
90
  subseg_change (seg, (int) subseg);
91
 
92
  seginfo = seg_info (seg);
93
 
94
  /* Attempt to find or make a frchain for that subsection.
95
     We keep the list sorted by subsection number.  */
96
  for (frcP = *(lastPP = &seginfo->frchainP);
97
       frcP != NULL;
98
       frcP = *(lastPP = &frcP->frch_next))
99
    if (frcP->frch_subseg >= subseg)
100
      break;
101
 
102
  if (frcP == NULL || frcP->frch_subseg != subseg)
103
    {
104
      /* This should be the only code that creates a frchainS.  */
105
 
106
      newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
107
      newP->frch_subseg = subseg;
108
      newP->fix_root = NULL;
109
      newP->fix_tail = NULL;
110
      obstack_begin (&newP->frch_obstack, chunksize);
111
#if __GNUC__ >= 2
112
      obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
113
#endif
114
      newP->frch_frag_now = frag_alloc (&newP->frch_obstack);
115
      newP->frch_frag_now->fr_type = rs_fill;
116
      newP->frch_cfi_data = NULL;
117
 
118
      newP->frch_root = newP->frch_last = newP->frch_frag_now;
119
 
120
      *lastPP = newP;
121
      newP->frch_next = frcP;
122
      frcP = newP;
123
    }
124
 
125
  frchain_now = frcP;
126
  frag_now = frcP->frch_frag_now;
127
 
128
  gas_assert (frchain_now->frch_last == frag_now);
129
}
130
 
131
/*
132
 *                      subseg_set(segT, subsegT)
133
 *
134
 * If you attempt to change to the current subsegment, nothing happens.
135
 *
136
 * In:  segT, subsegT code for new subsegment.
137
 *      frag_now -> incomplete frag for current subsegment.
138
 *      If frag_now==NULL, then there is no old, incomplete frag, so
139
 *      the old frag is not closed off.
140
 *
141
 * Out: now_subseg, now_seg updated.
142
 *      Frchain_now points to the (possibly new) struct frchain for this
143
 *      sub-segment.
144
 */
145
 
146
segT
147
subseg_get (const char *segname, int force_new)
148
{
149
  segT secptr;
150
  segment_info_type *seginfo;
151
  const char *now_seg_name = (now_seg
152
                              ? bfd_get_section_name (stdoutput, now_seg)
153
                              : 0);
154
 
155
  if (!force_new
156
      && now_seg_name
157
      && (now_seg_name == segname
158
          || !strcmp (now_seg_name, segname)))
159
    return now_seg;
160
 
161
  if (!force_new)
162
    secptr = bfd_make_section_old_way (stdoutput, segname);
163
  else
164
    secptr = bfd_make_section_anyway (stdoutput, segname);
165
 
166
  seginfo = seg_info (secptr);
167
  if (! seginfo)
168
    {
169
      secptr->output_section = secptr;
170
      seginfo = (segment_info_type *) xcalloc (1, sizeof (*seginfo));
171
      seginfo->bfd_section = secptr;
172
      bfd_set_section_userdata (stdoutput, secptr, seginfo);
173
    }
174
  return secptr;
175
}
176
 
177
segT
178
subseg_new (const char *segname, subsegT subseg)
179
{
180
  segT secptr;
181
 
182
  secptr = subseg_get (segname, 0);
183
  subseg_set_rest (secptr, subseg);
184
  return secptr;
185
}
186
 
187
/* Like subseg_new, except a new section is always created, even if
188
   a section with that name already exists.  */
189
segT
190
subseg_force_new (const char *segname, subsegT subseg)
191
{
192
  segT secptr;
193
 
194
  secptr = subseg_get (segname, 1);
195
  subseg_set_rest (secptr, subseg);
196
  return secptr;
197
}
198
 
199
void
200
subseg_set (segT secptr, subsegT subseg)
201
{
202
  if (! (secptr == now_seg && subseg == now_subseg))
203
    subseg_set_rest (secptr, subseg);
204
  mri_common_symbol = NULL;
205
}
206
 
207
#ifndef obj_sec_sym_ok_for_reloc
208
#define obj_sec_sym_ok_for_reloc(SEC)   0
209
#endif
210
 
211
symbolS *
212
section_symbol (segT sec)
213
{
214
  segment_info_type *seginfo = seg_info (sec);
215
  symbolS *s;
216
 
217
  if (seginfo == 0)
218
    abort ();
219
  if (seginfo->sym)
220
    return seginfo->sym;
221
 
222
#ifndef EMIT_SECTION_SYMBOLS
223
#define EMIT_SECTION_SYMBOLS 1
224
#endif
225
 
226
  if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen)
227
    {
228
      /* Here we know it won't be going into the symbol table.  */
229
      s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag);
230
    }
231
  else
232
    {
233
      segT seg;
234
      s = symbol_find (sec->symbol->name);
235
      /* We have to make sure it is the right symbol when we
236
         have multiple sections with the same section name.  */
237
      if (s == NULL
238
          || ((seg = S_GET_SEGMENT (s)) != sec
239
              && seg != undefined_section))
240
        s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag);
241
      else if (seg == undefined_section)
242
        {
243
          S_SET_SEGMENT (s, sec);
244
          symbol_set_frag (s, &zero_address_frag);
245
        }
246
    }
247
 
248
  S_CLEAR_EXTERNAL (s);
249
 
250
  /* Use the BFD section symbol, if possible.  */
251
  if (obj_sec_sym_ok_for_reloc (sec))
252
    symbol_set_bfdsym (s, sec->symbol);
253
  else
254
    symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM;
255
 
256
  seginfo->sym = s;
257
  return s;
258
}
259
 
260
/* Return whether the specified segment is thought to hold text.  */
261
 
262
int
263
subseg_text_p (segT sec)
264
{
265
  return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0;
266
}
267
 
268
/* Return non zero if SEC has at least one byte of data.  It is
269
   possible that we'll return zero even on a non-empty section because
270
   we don't know all the fragment types, and it is possible that an
271
   fr_fix == 0 one still contributes data.  Think of this as
272
   seg_definitely_not_empty_p.  */
273
 
274
int
275
seg_not_empty_p (segT sec ATTRIBUTE_UNUSED)
276
{
277
  segment_info_type *seginfo = seg_info (sec);
278
  frchainS *chain;
279
  fragS *frag;
280
 
281
  if (!seginfo)
282
    return 0;
283
 
284
  for (chain = seginfo->frchainP; chain; chain = chain->frch_next)
285
    {
286
      for (frag = chain->frch_root; frag; frag = frag->fr_next)
287
        if (frag->fr_fix)
288
          return 1;
289
      if (obstack_next_free (&chain->frch_obstack)
290
          != chain->frch_last->fr_literal)
291
        return 1;
292
    }
293
  return 0;
294
}
295
 
296
void
297
subsegs_print_statistics (FILE *file)
298
{
299
  frchainS *frchp;
300
  asection *s;
301
 
302
  fprintf (file, "frag chains:\n");
303
  for (s = stdoutput->sections; s; s = s->next)
304
    {
305
      segment_info_type *seginfo;
306
 
307
      /* Skip gas-internal sections.  */
308
      if (segment_name (s)[0] == '*')
309
        continue;
310
 
311
      seginfo = seg_info (s);
312
      if (!seginfo)
313
        continue;
314
 
315
      for (frchp = seginfo->frchainP; frchp; frchp = frchp->frch_next)
316
        {
317
          int count = 0;
318
          fragS *fragp;
319
 
320
          for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
321
            count++;
322
 
323
          fprintf (file, "\n");
324
          fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
325
                   segment_name (s), count);
326
        }
327
    }
328
}
329
 
330
/* end of subsegs.c */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.