removed unitialized used vartiable
[libfirm] / ir / be / begnuas.c
1 /**
2  * Dumps global variables and constants as gas assembler.
3  * @author Christian Wuerdig, Matthias Braun
4  * @date 04.11.2005
5  * @version $Id$
6  */
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "begnuas.h"
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <assert.h>
17
18 #include "obst.h"
19 #include "tv.h"
20 #include "irnode.h"
21 #include "entity.h"
22 #include "irprog.h"
23 #include "pdeq.h"
24 #include "error.h"
25
26 #include "be_t.h"
27 #include "beemitter.h"
28 #include "be_dbgout.h"
29
30 typedef struct obstack obstack_t;
31
32 /** by default, we generate assembler code for the Linux gas */
33 be_gas_flavour_t be_gas_flavour = GAS_FLAVOUR_NORMAL;
34
35 static const char* get_section_name(be_gas_section_t section) {
36         static const char *text[GAS_FLAVOUR_MAX][GAS_SECTION_MAX] = {
37                 {
38                         ".section\t.text",
39                         ".section\t.data",
40                         ".section\t.rodata",
41                         ".section\t.bss",
42                         ".section\t.tbss,\"awT\",@nobits",
43                         ".section\t.ctors,\"aw\",@progbits"
44                 },
45                 {
46                         ".section\t.text",
47                         ".section\t.data",
48                         ".section .rdata,\"dr\"",
49                         ".section\t.bss",
50                         ".section\t.tbss,\"awT\",@nobits",
51                         ".section\t.ctors,\"aw\",@progbits"
52                 }
53         };
54
55         assert(be_gas_flavour >= 0 && be_gas_flavour < GAS_FLAVOUR_MAX);
56         assert(section >= 0 && section < GAS_SECTION_MAX);
57         return text[be_gas_flavour][section];
58 }
59
60 void be_gas_emit_switch_section(be_emit_env_t *env, be_gas_section_t section) {
61         be_emit_char(env, '\t');
62         be_emit_string(env, get_section_name(section));
63         be_emit_char(env, '\n');
64         be_emit_write_line(env);
65 }
66
67 typedef struct _ia32_decl_env {
68         obstack_t *rodata_obst;
69         obstack_t *data_obst;
70         obstack_t *bss_obst;
71         obstack_t *ctor_obst;
72         const be_main_env_t *main_env;
73         waitq     *worklist;
74 } ia32_decl_env_t;
75
76 /************************************************************************/
77
78 /**
79  * output a tarval
80  */
81 static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
82 {
83         switch (bytes) {
84
85         case 1:
86                 obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
87                 break;
88
89         case 2:
90                 obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
91                 break;
92
93         case 4:
94                 obstack_printf(obst, "0x%02x%02x%02x%02x",
95                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
96                 break;
97
98         case 8:
99                 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
100                         get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
101                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
102                 break;
103
104         case 10:
105         case 12:
106                 break;
107
108         case 16:
109                 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
110                                                "%02x%02x%02x%02x%02x%02x%02x%02x",
111                         get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
112                         get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
113                         get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
114                         get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
115                         get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
116                         get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
117                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
118                         get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
119                 break;
120
121
122         default:
123                 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
124                 assert(0);
125         }
126 }
127
128 /**
129  * Return the tarval of an atomic initializer.
130  */
131 static tarval *get_atomic_init_tv(ir_node *init)
132 {
133         for (;;) {
134                 ir_mode *mode = get_irn_mode(init);
135
136                 switch (get_irn_opcode(init)) {
137
138                 case iro_Cast:
139                         init = get_Cast_op(init);
140                         continue;
141
142                 case iro_Conv:
143                         init = get_Conv_op(init);
144                         continue;
145
146                 case iro_Const:
147                         return get_Const_tarval(init);
148
149                 case iro_SymConst:
150                         switch (get_SymConst_kind(init)) {
151                         case symconst_ofs_ent:
152                                 return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
153
154                         case symconst_type_size:
155                                 return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
156
157                         case symconst_type_align:
158                                 return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
159
160                         case symconst_enum_const:
161                                 return get_enumeration_value(get_SymConst_enum(init));
162
163                         default:
164                                 return NULL;
165                         }
166
167                 default:
168                         return NULL;
169                 }
170         }
171 }
172
173 /**
174  * dump an atomic value
175  */
176 static void do_dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
177                                 ir_node *init)
178 {
179         ir_mode *mode = get_irn_mode(init);
180         int bytes     = get_mode_size_bytes(mode);
181         tarval *tv;
182         ir_entity *ent;
183
184         switch (get_irn_opcode(init)) {
185
186         case iro_Cast:
187                 do_dump_atomic_init(env, obst, get_Cast_op(init));
188                 return;
189
190         case iro_Conv:
191                 do_dump_atomic_init(env, obst, get_Conv_op(init));
192                 return;
193
194         case iro_Const:
195                 tv = get_Const_tarval(init);
196
197                 /* it's a arithmetic value */
198                 dump_arith_tarval(obst, tv, bytes);
199                 return;
200
201         case iro_SymConst:
202                 switch (get_SymConst_kind(init)) {
203                 case symconst_addr_name:
204                         obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
205                         break;
206
207                 case symconst_addr_ent:
208                         ent = get_SymConst_entity(init);
209                         if(!entity_visited(ent)) {
210                                 waitq_put(env->worklist, ent);
211                                 mark_entity_visited(ent);
212                         }
213                         obstack_printf(obst, "%s", get_entity_ld_name(ent));
214                         break;
215
216                 case symconst_ofs_ent:
217                         ent = get_SymConst_entity(init);
218 #if 0       /* not needed, is it? */
219                         if(!entity_visited(ent)) {
220                                 waitq_put(env->worklist, ent);
221                                 mark_entity_visited(ent);
222                         }
223 #endif
224                         obstack_printf(obst, "%d", get_entity_offset(ent));
225                         break;
226
227                 case symconst_type_size:
228                         obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
229                         break;
230
231                 case symconst_type_align:
232                         obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
233                         break;
234
235                 case symconst_enum_const:
236                         tv = get_enumeration_value(get_SymConst_enum(init));
237                         dump_arith_tarval(obst, tv, bytes);
238                         break;
239
240                 default:
241                         assert(!"dump_atomic_init(): don't know how to init from this SymConst");
242                 }
243                 return;
244
245                 case iro_Add:
246                         do_dump_atomic_init(env, obst, get_Add_left(init));
247                         obstack_printf(obst, " + ");
248                         do_dump_atomic_init(env, obst, get_Add_right(init));
249                         return;
250
251                 case iro_Sub:
252                         do_dump_atomic_init(env, obst, get_Sub_left(init));
253                         obstack_printf(obst, " - ");
254                         do_dump_atomic_init(env, obst, get_Sub_right(init));
255                         return;
256
257                 case iro_Mul:
258                         do_dump_atomic_init(env, obst, get_Mul_left(init));
259                         obstack_printf(obst, " * ");
260                         do_dump_atomic_init(env, obst, get_Mul_right(init));
261                         return;
262
263                 default:
264                         assert(0 && "dump_atomic_init(): unknown IR-node");
265         }
266 }
267
268 /**
269  * dumps the type for given size (.byte, .long, ...)
270  */
271 static void dump_size_type(obstack_t *obst, int size) {
272         switch (size) {
273
274         case 1:
275                 obstack_printf(obst, "\t.byte\t");
276                 break;
277
278         case 2:
279                 obstack_printf(obst, "\t.value\t");
280                 break;
281
282         case 4:
283                 obstack_printf(obst, "\t.long\t");
284                 break;
285
286         case 8:
287                 obstack_printf(obst, "\t.quad\t");
288                 break;
289
290         case 10:
291         case 12:
292                 /* handled in arith */
293                 break;
294
295         case 16:
296                 obstack_printf(obst, "\t.octa\t");
297                 break;
298
299         default:
300                 fprintf(stderr, "Try to dump a type with %d bytes\n", size);
301                 assert(0);
302         }
303 }
304
305 /**
306  * dump an atomic value to an obstack
307  */
308 static void dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
309                              ir_node *init)
310 {
311         ir_mode *mode = get_irn_mode(init);
312         int bytes     = get_mode_size_bytes(mode);
313
314         dump_size_type(obst, bytes);
315         do_dump_atomic_init(env, obst, init);
316         obstack_printf(obst, "\n");
317 }
318
319 /************************************************************************/
320 /* Routines to dump global variables                                    */
321 /************************************************************************/
322
323 /**
324  * Determine if an entity is a string constant
325  * @param ent The entity
326  * @return 1 if it is a string constant, 0 otherwise
327  */
328 static int ent_is_string_const(ir_entity *ent)
329 {
330         ir_type *type, *element_type;
331         ir_mode *mode;
332         int i, c, n;
333
334         type = get_entity_type(ent);
335
336         /* if it's an array */
337         if (!is_Array_type(type))
338                 return 0;
339
340         element_type = get_array_element_type(type);
341
342         /* and the array's element type is primitive */
343         if (!is_Primitive_type(element_type))
344                 return 0;
345
346         /* and the mode of the element type is an int of
347          * the same size as the byte mode */
348         mode = get_type_mode(element_type);
349         if (!mode_is_int(mode)
350                 || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
351                 return 0;
352
353         /* if it contains only printable chars and a 0 at the end */
354         n = get_compound_ent_n_values(ent);
355         for (i = 0; i < n; ++i) {
356                 ir_node *irn = get_compound_ent_value(ent, i);
357                 if(get_irn_opcode(irn) != iro_Const)
358                         return 0;
359
360                 c = (int) get_tarval_long(get_Const_tarval(irn));
361
362                 if((i < n - 1 && !(isgraph(c) || isspace(c)))
363                                 || (i == n - 1 && c != '\0'))
364                         return 0;
365         }
366
367         /* then we can emit it as a string constant */
368         return 1;
369 }
370
371 /**
372  * Dump a string constant.
373  * No checks are made!!
374  * @param obst The obst to dump on.
375  * @param ent The entity to dump.
376  */
377 static void dump_string_cst(obstack_t *obst, ir_entity *ent)
378 {
379         int i, n;
380
381         obstack_printf(obst, "\t.string \"");
382         n = get_compound_ent_n_values(ent);
383
384         for (i = 0; i < n-1; ++i) {
385                 ir_node *irn;
386                 int c;
387
388                 irn = get_compound_ent_value(ent, i);
389                 c = (int) get_tarval_long(get_Const_tarval(irn));
390
391                 switch (c) {
392                 case '"' : obstack_printf(obst, "\\\""); break;
393                 case '\n': obstack_printf(obst, "\\n"); break;
394                 case '\r': obstack_printf(obst, "\\r"); break;
395                 case '\t': obstack_printf(obst, "\\t"); break;
396                 case '\\': obstack_printf(obst, "\\\\"); break;
397                 default  :
398                         if (isprint(c))
399                                 obstack_printf(obst, "%c", c);
400                         else
401                                 obstack_printf(obst, "\\%o", c);
402                         break;
403                 }
404         }
405         obstack_printf(obst, "\"\n");
406 }
407
408 static void dump_array_init(ia32_decl_env_t *env, obstack_t *obst,
409                             ir_entity *ent)
410 {
411         const ir_type *ty = get_entity_type(ent);
412         int i;
413         int filler;
414         int size = 0;
415
416         /* potential spare values should be already included! */
417         for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
418                 ir_entity *step = get_compound_ent_value_member(ent, i);
419                 ir_type *stype = get_entity_type(step);
420
421                 if (get_type_mode(stype)) {
422                         int align = (get_type_alignment_bits(stype) + 7) >> 3;
423                         int n     = size % align;
424
425                         if (n > 0) {
426                                 obstack_printf(obst, "\t.zero\t%d\n", align - n);
427                                 size += align - n;
428                         }
429                 }
430                 dump_atomic_init(env, obst, get_compound_ent_value(ent, i));
431                 size += get_type_size_bytes(stype);
432         }
433         filler = get_type_size_bytes(ty) - size;
434
435         if (filler > 0)
436                 obstack_printf(obst, "\t.skip\t%d\n", filler);
437 }
438
439 enum normal_or_bitfield_kind {
440         NORMAL = 0,
441         BITFIELD
442 };
443
444 typedef struct {
445         enum normal_or_bitfield_kind kind;
446         union {
447                 ir_node *value;
448                 unsigned char bf_val;
449         } v;
450 } normal_or_bitfield;
451
452 /**
453  * Dump an initializer for a compound entity.
454  */
455 static void dump_compound_init(ia32_decl_env_t *env, obstack_t *obst,
456                                ir_entity *ent)
457 {
458         normal_or_bitfield *vals;
459         int i, j, n = get_compound_ent_n_values(ent);
460         int last_ofs;
461
462         /* Find the initializer size. Sorrily gcc support a nasty feature:
463            The last field of a compound may be a flexible array. This allows
464            initializers bigger than the type size. */
465         last_ofs = get_type_size_bytes(get_entity_type(ent));
466         for (i = 0; i < n; ++i) {
467                 int offset = get_compound_ent_value_offset_bytes(ent, i);
468                 int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
469                 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
470                 int path_len = get_compound_graph_path_length(path);
471                 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
472                 int value_len = get_type_size_bits(get_entity_type(last_ent));
473
474                 offset += (value_len + bits_remainder + 7) >> 3;
475
476                 if (offset > last_ofs) {
477                         last_ofs = offset;
478                 }
479         }
480
481         /*
482          * In the worst case, every initializer allocates one byte.
483          * Moreover, initializer might be big, do not allocate on stack.
484          */
485         vals = xcalloc(last_ofs, sizeof(vals[0]));
486
487         /* collect the values and store them at the offsets */
488         for (i = 0; i < n; ++i) {
489                 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
490                 int path_len = get_compound_graph_path_length(path);
491                 int offset = get_compound_ent_value_offset_bytes(ent, i);
492                 int offset_bits = get_compound_ent_value_offset_bit_remainder(ent, i);
493                 ir_node *value = get_compound_ent_value(ent, i);
494                 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
495                 int value_len = get_type_size_bits(get_entity_type(last_ent));
496                 assert(offset >= 0);
497                 assert(offset_bits >= 0);
498
499                 if (offset_bits != 0 ||
500                         (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
501                         tarval *shift, *shifted;
502                         tarval *tv = get_atomic_init_tv(value);
503                         if (tv == NULL) {
504                                 panic("Couldn't get numeric value for bitfield initializer '%s'\n",
505                                       get_entity_ld_name(ent));
506                         }
507                         tv = tarval_convert_to(tv, mode_Lu);
508                         shift = new_tarval_from_long(offset_bits, mode_Is);
509                         shifted = tarval_shl(tv, shift);
510                         if (shifted == tarval_bad || shifted == tarval_undefined) {
511                                 panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
512                                       get_entity_ld_name(ent));
513                         }
514
515                         for (j = 0; value_len > 0; ++j) {
516                                 assert(offset + j < last_ofs);
517                                 assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
518                                 vals[offset + j].kind = BITFIELD;
519                                 vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
520                                 value_len -= 8 - offset_bits;
521                                 offset_bits = 0;
522                         }
523                 } else {
524                         assert(offset < last_ofs);
525                         assert(vals[offset].kind == NORMAL);
526                         assert(vals[offset].v.value == NULL);
527                         vals[offset].v.value = value;
528                 }
529         }
530
531         /* now write them sorted */
532         for (i = 0; i < last_ofs; ) {
533                 int space = 0, skip = 0;
534                 if (vals[i].kind == NORMAL) {
535                         if(vals[i].v.value != NULL) {
536                                 dump_atomic_init(env, obst, vals[i].v.value);
537                                 skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
538                         } else {
539                                 space = 1;
540                         }
541                 } else {
542                         assert(vals[i].kind == BITFIELD);
543                         obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
544                 }
545
546                 ++i;
547                 space = 0;
548                 while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
549                         ++space;
550                         ++i;
551                 }
552                 space -= skip;
553                 assert(space >= 0);
554
555                 /* a gap */
556                 if (space > 0)
557                         obstack_printf(obst, "\t.skip\t%d\n", space);
558         }
559         xfree(vals);
560 }
561
562 /**
563  * Dump a global entity.
564  */
565 static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
566 {
567         obstack_t *obst;
568         ir_type *type = get_entity_type(ent);
569         const char *ld_name = get_entity_ld_name(ent);
570         ir_variability variability = get_entity_variability(ent);
571         ir_visibility visibility = get_entity_visibility(ent);
572         int align = get_type_alignment_bytes(type);
573         int emit_as_common = 0;
574
575         obst = env->data_obst;
576         if (is_Method_type(type)) {
577                 if (get_method_img_section(ent) == section_constructors) {
578                         obst = env->ctor_obst;
579                         obstack_printf(obst, ".balign\t%d\n", align);
580                         dump_size_type(obst, align);
581                         obstack_printf(obst, "%s\n", ld_name);
582                 }
583                 return;
584         } else if (variability == variability_constant) {
585                 /* a constant entity, put it on the rdata */
586                 obst = env->rodata_obst;
587         } else if (variability == variability_uninitialized) {
588                 /* uninitialized entity put it in bss segment */
589                 obst = env->bss_obst;
590                 if(emit_commons && visibility != visibility_local)
591                         emit_as_common = 1;
592         }
593
594         be_dbg_variable(env->main_env->db_handle, obst, ent);
595
596         /* global or not global */
597         if (visibility == visibility_external_visible && !emit_as_common) {
598                 obstack_printf(obst, ".global\t%s\n", ld_name);
599         } else if(visibility == visibility_external_allocated) {
600                 obstack_printf(obst, ".global\t%s\n", ld_name);
601                 /* we can return now... */
602                 return;
603         }
604         /* alignment */
605         if (align > 1 && !emit_as_common) {
606                 obstack_printf(obst, ".balign\t%d\n", align);
607         }
608
609         if (!emit_as_common) {
610                 obstack_printf(obst, "%s:\n", ld_name);
611         }
612
613         if (variability == variability_uninitialized) {
614                 if(emit_as_common) {
615                         obstack_printf(obst, "\t.comm %s,%d,%d\n",
616                                         ld_name, get_type_size_bytes(type), align);
617                 } else {
618                         obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
619                 }
620         } else if (is_atomic_type(type)) {
621                 dump_atomic_init(env, obst, get_atomic_ent_value(ent));
622         } else if (ent_is_string_const(ent)) {
623                 dump_string_cst(obst, ent);
624         } else if (is_Array_type(type)) {
625                 dump_array_init(env, obst, ent);
626         } else if (is_compound_type(type)) {
627                 dump_compound_init(env, obst, ent);
628         } else {
629                 assert(0 && "unsupported type");
630         }
631 }
632
633 /**
634  * Dumps declarations of global variables and the initialization code.
635  */
636 static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env,
637                               int emit_commons, int only_emit_marked)
638 {
639         int i, n = get_compound_n_members(gt);
640         waitq *worklist = new_waitq();
641
642         if(only_emit_marked) {
643                 for (i = 0; i < n; i++) {
644                         ir_entity *ent = get_compound_member(gt, i);
645                         if(entity_visited(ent) ||
646                                         get_entity_visibility(ent) != visibility_external_allocated) {
647                                 waitq_put(worklist, ent);
648                                 mark_entity_visited(ent);
649                         }
650                 }
651         } else {
652                 inc_master_type_visited();
653                 for (i = 0; i < n; i++) {
654                         ir_entity *ent = get_compound_member(gt, i);
655                         mark_entity_visited(ent);
656                         waitq_put(worklist, ent);
657                 }
658         }
659
660         env->worklist = worklist;
661
662         while(!waitq_empty(worklist)) {
663                 ir_entity *ent = waitq_get(worklist);
664
665                 dump_global(env, ent, emit_commons);
666         }
667
668         del_waitq(worklist);
669         env->worklist = NULL;
670 }
671
672 /************************************************************************/
673
674 void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env,
675                        int only_emit_marked_entities)
676 {
677         ia32_decl_env_t env;
678         obstack_t rodata, data, bss, ctor;
679         int    size;
680         char   *cp;
681
682         /* dump the global type */
683         obstack_init(&rodata);
684         obstack_init(&data);
685         obstack_init(&bss);
686         obstack_init(&ctor);
687
688         env.rodata_obst = &rodata;
689         env.data_obst   = &data;
690         env.bss_obst    = &bss;
691         env.ctor_obst   = &ctor;
692         env.main_env    = main_env;
693
694         ia32_dump_globals(get_glob_type(), &env, 1, only_emit_marked_entities);
695
696         size = obstack_object_size(&data);
697         cp   = obstack_finish(&data);
698         if (size > 0) {
699                 be_gas_emit_switch_section(emit, GAS_SECTION_DATA);
700                 be_emit_string_len(emit, cp, size);
701                 be_emit_write_line(emit);
702         }
703
704         size = obstack_object_size(&rodata);
705         cp   = obstack_finish(&rodata);
706         if (size > 0) {
707                 be_gas_emit_switch_section(emit, GAS_SECTION_RODATA);
708                 be_emit_string_len(emit, cp, size);
709                 be_emit_write_line(emit);
710         }
711
712         size = obstack_object_size(&bss);
713         cp   = obstack_finish(&bss);
714         if (size > 0) {
715                 be_gas_emit_switch_section(emit, GAS_SECTION_COMMON);
716                 be_emit_string_len(emit, cp, size);
717                 be_emit_write_line(emit);
718         }
719
720         size = obstack_object_size(&ctor);
721         cp   = obstack_finish(&ctor);
722         if (size > 0) {
723                 be_gas_emit_switch_section(emit, GAS_SECTION_CTOR);
724                 be_emit_string_len(emit, cp, size);
725                 be_emit_write_line(emit);
726         }
727
728         obstack_free(&rodata, NULL);
729         obstack_free(&data, NULL);
730         obstack_free(&bss, NULL);
731         obstack_free(&ctor, NULL);
732
733         /* dump the Thread Local Storage */
734         obstack_init(&data);
735
736         env.rodata_obst = &data;
737         env.data_obst   = &data;
738         env.bss_obst    = &data;
739         env.ctor_obst   = NULL;
740
741         ia32_dump_globals(get_tls_type(), &env, 0, only_emit_marked_entities);
742
743         size = obstack_object_size(&data);
744         cp   = obstack_finish(&data);
745         if (size > 0) {
746                 be_gas_emit_switch_section(emit, GAS_SECTION_TLS);
747                 be_emit_cstring(emit, ".balign\t32\n");
748                 be_emit_write_line(emit);
749                 be_emit_string_len(emit, cp, size);
750                 be_emit_write_line(emit);
751         }
752
753         obstack_free(&data, NULL);
754 }