subsegs.c 8.2 KB

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