bfd/
[external/binutils.git] / gas / subsegs.c
1 /* subsegs.c - subsegments -
2    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2002
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 2, 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, 59 Temple Place - Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 /* Segments & sub-segments.  */
24
25 #include "as.h"
26
27 #include "subsegs.h"
28 #include "obstack.h"
29
30 frchainS *frchain_root, *frchain_now;
31
32 static struct obstack frchains;
33
34 #ifndef BFD_ASSEMBLER
35 #ifdef MANY_SEGMENTS
36 segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
37
38 #else
39 /* Commented in "subsegs.h".  */
40 frchainS *data0_frchainP, *bss0_frchainP;
41
42 #endif /* MANY_SEGMENTS */
43 char const *const seg_name[] = {
44   "absolute",
45 #ifdef MANY_SEGMENTS
46   "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9",
47   "e10", "e11", "e12", "e13", "e14", "e15", "e16", "e17", "e18", "e19",
48   "e20", "e21", "e22", "e23", "e24", "e25", "e26", "e27", "e28", "e29",
49   "e30", "e31", "e32", "e33", "e34", "e35", "e36", "e37", "e38", "e39",
50 #else
51   "text",
52   "data",
53   "bss",
54 #endif /* MANY_SEGMENTS */
55   "unknown",
56   "ASSEMBLER-INTERNAL-LOGIC-ERROR!",
57   "expr",
58   "debug",
59   "transfert vector preload",
60   "transfert vector postload",
61   "register",
62   "",
63 };                              /* Used by error reporters, dumpers etc.  */
64 #else /* BFD_ASSEMBLER */
65
66 /* Gas segment information for bfd_abs_section_ptr and
67    bfd_und_section_ptr.  */
68 static segment_info_type *abs_seg_info;
69 static segment_info_type *und_seg_info;
70
71 #endif /* BFD_ASSEMBLER */
72
73 static void subseg_set_rest PARAMS ((segT, subsegT));
74
75 static fragS dummy_frag;
76
77 static frchainS absolute_frchain;
78 \f
79 void
80 subsegs_begin ()
81 {
82   /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */
83 #if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
84   know (SEG_ABSOLUTE == 0);
85   know (SEG_TEXT == 1);
86   know (SEG_DATA == 2);
87   know (SEG_BSS == 3);
88   know (SEG_UNKNOWN == 4);
89   know (SEG_GOOF == 5);
90   know (SEG_EXPR == 6);
91   know (SEG_DEBUG == 7);
92   know (SEG_NTV == 8);
93   know (SEG_PTV == 9);
94   know (SEG_REGISTER == 10);
95   know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
96 #endif
97
98   obstack_begin (&frchains, chunksize);
99 #if __GNUC__ >= 2
100   obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
101 #endif
102
103   frchain_root = NULL;
104   frchain_now = NULL;           /* Warn new_subseg() that we are booting.  */
105
106   frag_now = &dummy_frag;
107
108 #ifndef BFD_ASSEMBLER
109   now_subseg = 42;              /* Lie for 1st call to subseg_new.  */
110 #ifdef MANY_SEGMENTS
111   {
112     int i;
113     for (i = SEG_E0; i < SEG_UNKNOWN; i++)
114       {
115         subseg_set (i, 0);
116         segment_info[i].frchainP = frchain_now;
117       }
118   }
119 #else
120   subseg_set (SEG_DATA, 0);     /* .data 0 */
121   data0_frchainP = frchain_now;
122
123   subseg_set (SEG_BSS, 0);
124   bss0_frchainP = frchain_now;
125
126 #endif /* ! MANY_SEGMENTS */
127 #endif /* ! BFD_ASSEMBLER */
128
129   absolute_frchain.frch_seg = absolute_section;
130   absolute_frchain.frch_subseg = 0;
131 #ifdef BFD_ASSEMBLER
132   absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
133 #endif
134   absolute_frchain.frch_frag_now = &zero_address_frag;
135   absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
136 }
137 \f
138 /*
139  *                      subseg_change()
140  *
141  * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the
142  * subsegment. If we are already in the correct subsegment, change nothing.
143  * This is used eg as a worker for subseg_set [which does make a new frag_now]
144  * and for changing segments after we have read the source. We construct eg
145  * fixSs even after the source file is read, so we do have to keep the
146  * segment context correct.
147  */
148 void
149 subseg_change (seg, subseg)
150      register segT seg;
151      register int subseg;
152 {
153   now_seg = seg;
154   now_subseg = subseg;
155
156   if (now_seg == absolute_section)
157     return;
158
159 #ifdef BFD_ASSEMBLER
160   {
161     segment_info_type *seginfo;
162     seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg);
163     if (! seginfo)
164       {
165         seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
166         memset ((PTR) seginfo, 0, sizeof (*seginfo));
167         seginfo->fix_root = NULL;
168         seginfo->fix_tail = NULL;
169         seginfo->bfd_section = seg;
170         seginfo->sym = 0;
171         if (seg == bfd_abs_section_ptr)
172           abs_seg_info = seginfo;
173         else if (seg == bfd_und_section_ptr)
174           und_seg_info = seginfo;
175         else
176           bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
177       }
178   }
179 #else
180 #ifdef MANY_SEGMENTS
181   seg_fix_rootP = &segment_info[seg].fix_root;
182   seg_fix_tailP = &segment_info[seg].fix_tail;
183 #else
184   if (seg == SEG_DATA)
185     {
186       seg_fix_rootP = &data_fix_root;
187       seg_fix_tailP = &data_fix_tail;
188     }
189   else if (seg == SEG_TEXT)
190     {
191       seg_fix_rootP = &text_fix_root;
192       seg_fix_tailP = &text_fix_tail;
193     }
194   else
195     {
196       know (seg == SEG_BSS);
197       seg_fix_rootP = &bss_fix_root;
198       seg_fix_tailP = &bss_fix_tail;
199     }
200
201 #endif
202 #endif
203 }
204 \f
205 static void
206 subseg_set_rest (seg, subseg)
207      segT seg;
208      subsegT subseg;
209 {
210   register frchainS *frcP;      /* crawl frchain chain */
211   register frchainS **lastPP;   /* address of last pointer */
212   frchainS *newP;               /* address of new frchain */
213
214   mri_common_symbol = NULL;
215
216   if (frag_now && frchain_now)
217     frchain_now->frch_frag_now = frag_now;
218
219   assert (frchain_now == 0
220           || now_seg == undefined_section
221           || now_seg == absolute_section
222           || frchain_now->frch_last == frag_now);
223
224   subseg_change (seg, (int) subseg);
225
226   if (seg == absolute_section)
227     {
228       frchain_now = &absolute_frchain;
229       frag_now = &zero_address_frag;
230       return;
231     }
232
233   assert (frchain_now == 0
234           || now_seg == undefined_section
235           || frchain_now->frch_last == frag_now);
236
237   /*
238    * Attempt to find or make a frchain for that sub seg.
239    * Crawl along chain of frchainSs, begins @ frchain_root.
240    * If we need to make a frchainS, link it into correct
241    * position of chain rooted in frchain_root.
242    */
243   for (frcP = *(lastPP = &frchain_root);
244        frcP && frcP->frch_seg <= seg;
245        frcP = *(lastPP = &frcP->frch_next))
246     {
247       if (frcP->frch_seg == seg
248           && frcP->frch_subseg >= subseg)
249         {
250           break;
251         }
252     }
253   /*
254    * frcP:              Address of the 1st frchainS in correct segment with
255    *            frch_subseg >= subseg.
256    *            We want to either use this frchainS, or we want
257    *            to insert a new frchainS just before it.
258    *
259    *            If frcP==NULL, then we are at the end of the chain
260    *            of frchainS-s. A NULL frcP means we fell off the end
261    *            of the chain looking for a
262    *            frch_subseg >= subseg, so we
263    *            must make a new frchainS.
264    *
265    *            If we ever maintain a pointer to
266    *            the last frchainS in the chain, we change that pointer
267    *            ONLY when frcP==NULL.
268    *
269    * lastPP:    Address of the pointer with value frcP;
270    *            Never NULL.
271    *            May point to frchain_root.
272    *
273    */
274   if (!frcP
275       || (frcP->frch_seg > seg
276           || frcP->frch_subseg > subseg))       /* Kinky logic only works with 2 segments.  */
277     {
278       /*
279        * This should be the only code that creates a frchainS.
280        */
281       newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
282       newP->frch_subseg = subseg;
283       newP->frch_seg = seg;
284 #ifdef BFD_ASSEMBLER
285       newP->fix_root = NULL;
286       newP->fix_tail = NULL;
287 #endif
288       obstack_begin (&newP->frch_obstack, chunksize);
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;
296
297       *lastPP = newP;
298       newP->frch_next = frcP;   /* perhaps NULL */
299
300 #ifdef BFD_ASSEMBLER
301       {
302         segment_info_type *seginfo;
303         seginfo = seg_info (seg);
304         if (seginfo && seginfo->frchainP == frcP)
305           seginfo->frchainP = newP;
306       }
307 #endif
308
309       frcP = newP;
310     }
311   /*
312    * Here with frcP pointing to the frchainS for subseg.
313    */
314   frchain_now = frcP;
315   frag_now = frcP->frch_frag_now;
316
317   assert (frchain_now->frch_last == frag_now);
318 }
319
320 /*
321  *                      subseg_set(segT, subsegT)
322  *
323  * If you attempt to change to the current subsegment, nothing happens.
324  *
325  * In:  segT, subsegT code for new subsegment.
326  *      frag_now -> incomplete frag for current subsegment.
327  *      If frag_now==NULL, then there is no old, incomplete frag, so
328  *      the old frag is not closed off.
329  *
330  * Out: now_subseg, now_seg updated.
331  *      Frchain_now points to the (possibly new) struct frchain for this
332  *      sub-segment.
333  *      Frchain_root updated if needed.
334  */
335
336 #ifndef BFD_ASSEMBLER
337
338 segT
339 subseg_new (segname, subseg)
340      const char *segname;
341      subsegT subseg;
342 {
343   int i;
344
345   for (i = 0; i < (int) SEG_MAXIMUM_ORDINAL; i++)
346     {
347       const char *s;
348
349       s = segment_name ((segT) i);
350       if (strcmp (segname, s) == 0
351           || (segname[0] == '.'
352               && strcmp (segname + 1, s) == 0))
353         {
354           subseg_set ((segT) i, subseg);
355           return (segT) i;
356         }
357 #ifdef obj_segment_name
358       s = obj_segment_name ((segT) i);
359       if (strcmp (segname, s) == 0
360           || (segname[0] == '.'
361               && strcmp (segname + 1, s) == 0))
362         {
363           subseg_set ((segT) i, subseg);
364           return (segT) i;
365         }
366 #endif
367     }
368
369 #ifdef obj_add_segment
370   {
371     segT new_seg;
372     new_seg = obj_add_segment (segname);
373     subseg_set (new_seg, subseg);
374     return new_seg;
375   }
376 #else
377   as_bad (_("attempt to switch to nonexistent segment \"%s\""), segname);
378   return now_seg;
379 #endif
380 }
381
382 void
383 subseg_set (seg, subseg)        /* begin assembly for a new sub-segment */
384      register segT seg;         /* SEG_DATA or SEG_TEXT */
385      register subsegT subseg;
386 {
387 #ifndef MANY_SEGMENTS
388   know (seg == SEG_DATA
389         || seg == SEG_TEXT
390         || seg == SEG_BSS
391         || seg == SEG_ABSOLUTE);
392 #endif
393
394   if (seg != now_seg || subseg != now_subseg)
395     {                           /* we just changed sub-segments */
396       subseg_set_rest (seg, subseg);
397     }
398   mri_common_symbol = NULL;
399 }
400
401 #else /* BFD_ASSEMBLER */
402
403 segT
404 subseg_get (segname, force_new)
405      const char *segname;
406      int force_new;
407 {
408   segT secptr;
409   segment_info_type *seginfo;
410   const char *now_seg_name = (now_seg
411                               ? bfd_get_section_name (stdoutput, now_seg)
412                               : 0);
413
414   if (!force_new
415       && now_seg_name
416       && (now_seg_name == segname
417           || !strcmp (now_seg_name, segname)))
418     return now_seg;
419
420   if (!force_new)
421     secptr = bfd_make_section_old_way (stdoutput, segname);
422   else
423     secptr = bfd_make_section_anyway (stdoutput, segname);
424
425 #ifdef obj_sec_set_private_data
426   obj_sec_set_private_data (stdoutput, secptr);
427 #endif
428
429   seginfo = seg_info (secptr);
430   if (! seginfo)
431     {
432       /* Check whether output_section is set first because secptr may
433          be bfd_abs_section_ptr.  */
434       if (secptr->output_section != secptr)
435         secptr->output_section = secptr;
436       seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
437       memset ((PTR) seginfo, 0, sizeof (*seginfo));
438       seginfo->fix_root = NULL;
439       seginfo->fix_tail = NULL;
440       seginfo->bfd_section = secptr;
441       if (secptr == bfd_abs_section_ptr)
442         abs_seg_info = seginfo;
443       else if (secptr == bfd_und_section_ptr)
444         und_seg_info = seginfo;
445       else
446         bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
447       seginfo->frchainP = NULL;
448       seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
449       seginfo->sym = NULL;
450       seginfo->dot = NULL;
451     }
452   return secptr;
453 }
454
455 segT
456 subseg_new (segname, subseg)
457      const char *segname;
458      subsegT subseg;
459 {
460   segT secptr;
461   segment_info_type *seginfo;
462
463   secptr = subseg_get (segname, 0);
464   subseg_set_rest (secptr, subseg);
465   seginfo = seg_info (secptr);
466   if (! seginfo->frchainP)
467     seginfo->frchainP = frchain_now;
468   return secptr;
469 }
470
471 /* Like subseg_new, except a new section is always created, even if
472    a section with that name already exists.  */
473 segT
474 subseg_force_new (segname, subseg)
475      const char *segname;
476      subsegT subseg;
477 {
478   segT secptr;
479   segment_info_type *seginfo;
480
481   secptr = subseg_get (segname, 1);
482   subseg_set_rest (secptr, subseg);
483   seginfo = seg_info (secptr);
484   if (! seginfo->frchainP)
485     seginfo->frchainP = frchain_now;
486   return secptr;
487 }
488
489 void
490 subseg_set (secptr, subseg)
491      segT secptr;
492      subsegT subseg;
493 {
494   if (! (secptr == now_seg && subseg == now_subseg))
495     subseg_set_rest (secptr, subseg);
496   mri_common_symbol = NULL;
497 }
498
499 #ifndef obj_sec_sym_ok_for_reloc
500 #define obj_sec_sym_ok_for_reloc(SEC)   0
501 #endif
502
503 /* Get the gas information we are storing for a section.  */
504
505 segment_info_type *
506 seg_info (sec)
507      segT sec;
508 {
509   if (sec == bfd_abs_section_ptr)
510     return abs_seg_info;
511   else if (sec == bfd_und_section_ptr)
512     return und_seg_info;
513   else
514     return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
515 }
516
517 symbolS *
518 section_symbol (sec)
519      segT sec;
520 {
521   segment_info_type *seginfo = seg_info (sec);
522   symbolS *s;
523
524   if (seginfo == 0)
525     abort ();
526   if (seginfo->sym)
527     return seginfo->sym;
528
529 #ifndef EMIT_SECTION_SYMBOLS
530 #define EMIT_SECTION_SYMBOLS 1
531 #endif
532
533   if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen)
534     {
535       /* Here we know it won't be going into the symbol table.  */
536       s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag);
537     }
538   else
539     {
540       s = symbol_find_base (sec->symbol->name, 0);
541       if (s == NULL)
542         s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag);
543       else
544         {
545           if (S_GET_SEGMENT (s) == undefined_section)
546             {
547               S_SET_SEGMENT (s, sec);
548               symbol_set_frag (s, &zero_address_frag);
549             }
550         }
551     }
552
553   S_CLEAR_EXTERNAL (s);
554
555   /* Use the BFD section symbol, if possible.  */
556   if (obj_sec_sym_ok_for_reloc (sec))
557     symbol_set_bfdsym (s, sec->symbol);
558   else
559     symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM;
560
561   seginfo->sym = s;
562   return s;
563 }
564
565 #endif /* BFD_ASSEMBLER */
566
567 /* Return whether the specified segment is thought to hold text.  */
568
569 #ifndef BFD_ASSEMBLER
570 const char * const nontext_section_names[] = {
571   ".eh_frame",
572   ".gcc_except_table",
573 #ifdef OBJ_COFF
574 #ifndef COFF_LONG_SECTION_NAMES
575   ".eh_fram",
576   ".gcc_exc",
577 #endif
578 #endif
579   NULL
580 };
581 #endif /* ! BFD_ASSEMBLER */
582
583 int
584 subseg_text_p (sec)
585      segT sec;
586 {
587 #ifdef BFD_ASSEMBLER
588   return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0;
589 #else /* ! BFD_ASSEMBLER */
590   const char * const *p;
591
592   if (sec == data_section || sec == bss_section || sec == absolute_section)
593     return 0;
594
595   for (p = nontext_section_names; *p != NULL; ++p)
596     {
597       if (strcmp (segment_name (sec), *p) == 0)
598         return 0;
599
600 #ifdef obj_segment_name
601       if (strcmp (obj_segment_name (sec), *p) == 0)
602         return 0;
603 #endif
604     }
605
606   return 1;
607
608 #endif /* ! BFD_ASSEMBLER */
609 }
610
611 void
612 subsegs_print_statistics (file)
613      FILE *file;
614 {
615   frchainS *frchp;
616   fprintf (file, "frag chains:\n");
617   for (frchp = frchain_root; frchp; frchp = frchp->frch_next)
618     {
619       int count = 0;
620       fragS *fragp;
621
622       /* If frch_subseg is non-zero, it's probably been chained onto
623          the end of a previous subsection.  Don't count it again.  */
624       if (frchp->frch_subseg != 0)
625         continue;
626
627       /* Skip gas-internal sections.  */
628       if (segment_name (frchp->frch_seg)[0] == '*')
629         continue;
630
631       for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
632         {
633 #if 0
634           switch (fragp->fr_type)
635             {
636             case rs_fill:
637               fprintf (file, "f"); break;
638             case rs_align:
639               fprintf (file, "a"); break;
640             case rs_align_code:
641               fprintf (file, "c"); break;
642             case rs_org:
643               fprintf (file, "o"); break;
644             case rs_machine_dependent:
645               fprintf (file, "m"); break;
646             case rs_space:
647               fprintf (file, "s"); break;
648             case 0:
649               fprintf (file, "0"); break;
650             default:
651               fprintf (file, "?"); break;
652             }
653 #endif
654           count++;
655         }
656       fprintf (file, "\n");
657       fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
658                segment_name (frchp->frch_seg), count);
659     }
660 }
661
662 /* end of subsegs.c */