Studying note of GCC-3.4.6 source (172)
来源:互联网 发布:宁波每日新房成交数据 编辑:程序博客网 时间:2024/06/01 07:12
5.13.5.2.2.2. The variable
Afteroutputting the initializer(s), back assemble_variable, next output the variable.
assemble_variable (continue)
1468 resolve_unique_section(decl, reloc, flag_data_sections);
Above, flag_data_sectionsgets value of switch –fdata-sections, tegother with switch –ffunction-sections(in flag_function_sections)are used for following purpose[6]:
Place each function or data item into its own section in the output file if the target supports arbitrary sections. The name of the function or the name of the data item determines the section’s name in the output file.
Use these options on systems where the linker can perform optimizations to improve locality of reference in the instruction space. Most systems using the ELF object format and SPARC processors running Solaris 2 have linkers with such optimizations. AIX may have these optimizations in the future.
Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker will create larger object and executable files and will also be slower. You will not be able to use gprof on all systems if you specify this option and you may have problems with debugging if you specify both this option and ‘-g’.
442 void
443 resolve_unique_section (tree decl, intreloc ATTRIBUTE_UNUSED, in varasm.c
444 intflag_function_or_data_sections)
445 {
446 if (DECL_SECTION_NAME (decl) == NULL_TREE
447 && targetm.have_named_sections
448 && (flag_function_or_data_sections
449 || DECL_ONE_ONLY (decl)))
450 (*targetm.asm_out.unique_section)(decl, reloc);
451 }
Here assuming –fdata-sections is not present, by default, flag_data_sectionsis 0. And at line 449 above DECL_ONE_ONLY is nonzero if copies of decl inmultiple translation units should be merged. For x86 chip and Linux OS, at thispoint, this predicate returns false.
assemble_variable (continue)
1470 /* Handleuninitialized definitions. */
1471
1472 /* If the decl has been given an explicitsection name, then it
1473 isn't common, and shouldn't be handled assuch. */
1474 if (DECL_SECTION_NAME (decl) ||dont_output_data)
1475 ;
1476 /* We don'timplement common thread-local data at present. */
1477 else if (DECL_THREAD_LOCAL (decl))
1478 {
1479 if (DECL_COMMON (decl))
1480 sorry ("thread-local COMMON data notimplemented");
1481 }
1482 else if (DECL_INITIAL (decl) == 0
1483 || DECL_INITIAL (decl) ==error_mark_node
1484 || (flag_zero_initialized_in_bss
1485 /* Leaveconstant zeroes in .rodata so they can be shared. */
1486 && !TREE_READONLY (decl)
1487 && initializer_zerop(DECL_INITIAL (decl))))
1488 {
1489 unsigned HOST_WIDE_INT size = tree_low_cst(DECL_SIZE_UNIT (decl), 1);
1490 unsigned HOST_WIDE_INT rounded = size;
1491
1492 /* Don't allocatezero bytes of common,
1493 since that means "undefinedexternal" in the linker. */
1494 if (size == 0)
1495 rounded = 1;
1496
1497 /* Round size upto multiple of BIGGEST_ALIGNMENT bits
1498 so that each uninitialized object startson such a boundary. */
1499 rounded += (BIGGEST_ALIGNMENT /BITS_PER_UNIT) - 1;
1500 rounded = (rounded / (BIGGEST_ALIGNMENT /BITS_PER_UNIT)
1501 * (BIGGEST_ALIGNMENT /BITS_PER_UNIT));
1502
1503 #if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
1504 if ((unsigned HOST_WIDE_INT) DECL_ALIGN(decl) / BITS_PER_UNIT > rounded)
1505 warning ("%Jrequested alignment for'%D' is greater than "
1506 "implemented alignment of%d", decl, decl, rounded);
1507 #endif
1508
1509 /* If the targetcannot output uninitialized but not common global data
1510 in .bss, then we have to use .data, so fall through. */
1511 if (asm_emit_uninitialised(decl, name, size, rounded))
1512 return;
1513 }
Because here resolve_unique_section doesn’t any processing(if required, it will select an unique section for decl), DECL_SECTION_NAME at line1474 returns NULL.
5.13.5.2.2.2.1. Output assemble – variablewithout initializer
Note that don’t_output_data is 0. At line 1484, flag_zero_initialized_in_bssby default is 1, it indicates to put zero initialized data in the bss section (GCCby default puts variable initialized to 0 into BSS section, unless the targetcan’t support it).
At line 1267, if DECL_COMMON holds, means putting the declarationinto “.comm” section as possible, thus multiple copies of this uninitializedvariable cam be merged. But if its DECL_INITIAL isn’t error_mark_node, thedeclaration can’t be put into “.comm” section.
1250 static bool
1251 asm_emit_uninitialised (tree decl, const char *name, in varasm.c
1252 unsigned HOST_WIDE_INT sizeATTRIBUTE_UNUSED,
1253 unsigned HOST_WIDE_INTrounded ATTRIBUTE_UNUSED)
1254 {
1255 enum
1256 {
1257 asm_dest_common,
1258 asm_dest_bss,
1259 asm_dest_local
1260 }
1261 destination = asm_dest_local;
1262
1263 /* ??? We shouldhandle .bss via select_section mechanisms rather than
1264 via special target hooks. That wouldeliminate this special case. */
1265 if (TREE_PUBLIC (decl))
1266 {
1267 if (!DECL_COMMON (decl))
1268 #ifdef ASM_EMIT_BSS
1269 destination = asm_dest_bss;
1270 #else
1271 return false;
1272 #endif
1273 else
1274 destination = asm_dest_common;
1275 }
1276
1277 if (destination == asm_dest_bss)
1278 globalize_decl(decl);
1279 resolve_unique_section(decl, 0, flag_data_sections);
Usually,uninitialized global variable (includes static member) has DECL_COMMON set(note that TREE_PUBLIC of static variable is not TRUE, it will be output into “.local”section), but not for declarations having initializer. For object havinginitialzier, above at line 1278, outputs its property by below function.
4355 static void
4356 globalize_decl (tree decl) in varasm.c
4357 {
4358 const char*name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
4359
4360 #ifdefined (ASM_WEAKEN_LABEL)|| defined (ASM_WEAKEN_DECL)
4361 if (DECL_WEAK (decl))
4362 {
4363 tree *p, t;
4364
4365 #ifdefASM_WEAKEN_DECL
4366 ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
4367 #else
4368 ASM_WEAKEN_LABEL(asm_out_file,name);
4369 #endif
4370
4371 /* Remove thisfunction from the pending weak list so that
4372 we do not emit multiple .weak directives for it. */
4373 for (p =&weak_decls;(t = *p) ; )
4374 {
4375 if(DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
4376 *p= TREE_CHAIN (t);
4377 else
4378 p= &TREE_CHAIN (t);
4379 }
4380 return;
4381 }
4382 #endif
4383
4384 (*targetm.asm_out.globalize_label)(asm_out_file,name);
4385 }
Above for our target machine, macro ASM_WEAKEN_DECL isn’t defined,and macro ASM_WEAKEN_LABEL has below definition, it outputs the property ofweak declaration.
240 #define ASM_WEAKEN_LABEL(FILE, NAME) / in elfos.h
241 do /
242 { /
243 fputs ("/t.weak/t", (FILE)); /
244 assemble_name ((FILE), (NAME)); /
245 fputc ('/n', (FILE)); /
246 } /
247 while (0)
For non-weak global variable, it is output by hook globalize_labelat line 4384. On our target machine, the function is default_globalize_label.
5252 #ifdef GLOBAL_ASM_OP
5253 void
5254 default_globalize_label (FILE * stream, const char *name) in varasm.c
5255 {
5256 fputs (GLOBAL_ASM_OP, stream);
5257 assemble_name(stream, name);
5258 putc ('/n', stream);
5259 }
5260 #endif /* GLOBAL_ASM_OP */
GLOBAL_ASM_OP is defined as “.globl” here (another compatible one is“.global”), it makes the symbol visible to ld (GNU linker). So the output of default_globalize_labelhas form “.globl b”, in which “b” is thevariable name.
After outputting the property and the name, below code determinesthe section to output the variable and output the section information (if needsto swap current section).
asm_emit_unintialised (continue)
1281 if (flag_shared_data)
1282 {
1283 switch(destination)
1284 {
1285 #ifdefASM_OUTPUT_SHARED_BSS
1286 case asm_dest_bss:
1287 ASM_OUTPUT_SHARED_BSS (asm_out_file,decl, name, size, rounded);
1288 return;
1289 #endif
1290 #ifdef ASM_OUTPUT_SHARED_COMMON
1291 case asm_dest_common:
1292 ASM_OUTPUT_SHARED_COMMON (asm_out_file,name, size, rounded);
1293 return;
1294 #endif
1295 #ifdefASM_OUTPUT_SHARED_LOCAL
1296 case asm_dest_local:
1297 ASM_OUTPUT_SHARED_LOCAL (asm_out_file,name, size, rounded);
1298 return;
1299 #endif
1300 default:
1301 break;
1302 }
1303 }
1304
1305 switch (destination)
1306 {
1307 #ifdef ASM_EMIT_BSS
1308 case asm_dest_bss:
1309 ASM_EMIT_BSS(decl, name, size, rounded);
1310 break;
1311 #endif
1312 case asm_dest_common:
1313 ASM_EMIT_COMMON(decl, name, size, rounded);
1314 break;
1315 case asm_dest_local:
1316 ASM_EMIT_LOCAL(decl, name, size, rounded);
1317 break;
1318 default:
1319 abort ();
1320 }
1321
1322 return true;
1323 }
For x86/Linux, above macros containing “SHARED” field aren’tdefined, which indicates at here flag_shared_data does not work.
Macro ASM_EMIT_BSS, for x86/Linux target, is defined by asm_output_aligned_bss.
501 static void
502 asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED, in varasm.c
503 const char *name, unsigned HOST_WIDE_INT size,
504 intalign)
505 {
506 bss_section ();
507 ASM_OUTPUT_ALIGN (file, floor_log2(align / BITS_PER_UNIT));
508 #ifdef ASM_DECLARE_OBJECT_NAME
509 last_assemble_variable_decl= decl;
510 ASM_DECLARE_OBJECT_NAME (file,name, decl);
511 #else
512 /* Standard thing is just output label for theobject. */
513 ASM_OUTPUT_LABEL (file, name);
514 #endif /* ASM_DECLARE_OBJECT_NAME */
515 ASM_OUTPUT_SKIP (file, size ? size : 1);
516 }
First via below function to check if we are already in “.bss”section, swap to “.bss” section if it is not. BSS_SECTION_ASM_OP is “/t.bss”.
457 void
458 bss_section (void) in varasm.c
459 {
460 if (in_section!= in_bss)
461 {
462 fprintf (asm_out_file,"%s/n", BSS_SECTION_ASM_OP);
463 in_section = in_bss;
464 }
465 }
Before we have seen macro ASM_OUTPUT_LABEL, there it is used tooutput label. Here what output is variable, in some machines, they aredifferent in nature. Here, x86/Linux defines following macros to outputvariables specially.
287 #define ASM_DECLARE_OBJECT_NAME(FILE,NAME, DECL) / in elfos.h
288 do /
289 { /
290 HOST_WIDE_INT size; /
291 /
292 ASM_OUTPUT_TYPE_DIRECTIVE(FILE, NAME, "object"); /
293 /
294 size_directive_output= 0; /
295 if (!flag_inhibit_size_directive /
296 && (DECL) &&DECL_SIZE (DECL)) /
297 { /
298 size_directive_output = 1; /
299 size = int_size_in_bytes(TREE_TYPE (DECL)); /
300 ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME,size); /
301 } /
302 /
303 ASM_OUTPUT_LABEL (FILE, NAME); /
304 } /
305 while (0)
Here the difference between variable and label is that, variable hasadditional description which is output by below macro.
186 #ifndef ASM_OUTPUT_TYPE_DIRECTIVE in defaults.h
187 #if defined TYPE_ASM_OP && definedTYPE_OPERAND_FMT
188 #define ASM_OUTPUT_TYPE_DIRECTIVE(STREAM,NAME, TYPE) /
189 do /
190 { /
191 fputs (TYPE_ASM_OP, STREAM); /
192 assemble_name (STREAM, NAME); /
193 fputs (", ", STREAM); /
194 fprintf (STREAM, TYPE_OPERAND_FMT, TYPE); /
195 putc ('/n', STREAM); /
196 } /
197 while (0)
198 #endif
199 #endif
Above TYPE_OPERAND_FMT in elfos.h has definition “@%s”, and TYPE_ASM_OPis “/t.type/t”. SO macro ASM_OUTPUT_TYPE_DIRECTIVE will output some like: “.type b, object”, in which “b” is the variablename.
202 #ifndef ASM_OUTPUT_SIZE_DIRECTIVE
203 #ifdef SIZE_ASM_OP
204 #define ASM_OUTPUT_SIZE_DIRECTIVE(STREAM, NAME,SIZE) /
205 do /
206 { /
207 HOST_WIDE_INT size_ = (SIZE); /
208 fputs (SIZE_ASM_OP, STREAM); /
209 assemble_name (STREAM, NAME); /
210 fprintf (STREAM, ", " HOST_WIDE_INT_PRINT_DEC "/n",size_); /
211 } /
212 while (0)
If flag_inhibit_size_directiveis nonzero, it means to prohibit “.size” in elf format, it is set by option “-finhibit-size-directive”,and the default value is 0. Unless prohibit, using ASM_OUTPUT_SIZE_DIRECTIVE tooutput the size of the variable. HereSIZE_ASM_OP’s definition is “/t.size/t”.The content output looks like: ”.size b,4”, in which “b” is thevariable name.
Next in ASM_DECLARE_OBJECT_NAME at line 303 invokes ASM_OUTPUT_LABLEto output the variable name as label, then in asm_output_aligned_bss atline 515, by ASM_OUTPUT_SKIP output default initializer like “.zero 4”,in which “4” is thesize of the variable.
If it needs be output into “.comm” section, here the output macro ASM_EMIT_COMMONis defined as ASM_OUTPUT_ALIGNED_COMMON.
164 #undef ASM_OUTPUT_ALIGNED_COMMON
165 #define ASM_OUTPUT_ALIGNED_COMMON(FILE,NAME, SIZE, ALIGN)/ in elfos.h
166 do /
167 { /
168 fprintf ((FILE), "%s", COMMON_ASM_OP); /
169 assemble_name((FILE), (NAME)); /
170 fprintf ((FILE),","HOST_WIDE_INT_PRINT_UNSIGNED",%u/n", /
171 (SIZE), (ALIGN) / BITS_PER_UNIT); /
172 } /
173 while (0)
Above COMMON_ASM_OPis “/t.comm/t”, at last the output looks like “.comm b,4,4”, in which “b”is the variable name, the first “4”is the variable size, and the later “4”is the alignment .Note that here it won't output the label of the variable nameand the default initializer.
Similarly, for local variable (note, includes static vairable), ASM_EMIT_LOCALat here is defined as ASM_OUTPUT_ALIGNED_LOCAL.
182 #undef ASM_OUTPUT_ALIGNED_LOCAL
183 #defineASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) /in elfos.h
184 do /
185 { /
186 fprintf ((FILE), "%s",LOCAL_ASM_OP); /
187 assemble_name((FILE), (NAME)); /
188 fprintf ((FILE), "/n"); /
189 ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN); /
190 } /
191 while (0)
Here, LOCAL_ASM_OP is “/t.local/t”, so the output looks like:
.local a
.comm a,4,4
5.13.5.2.2.2.2. Output assemble – variable withinitializer
If global/static variable has initializer, thus coming here. First,below at line 1524, variable_section selects the target section(refer to Select output section).
assemble_variable (continue)
1515 /* Handleinitialized definitions.
1516 Also handle uninitialized globaldefinitions if -fno-common and the
1517 target doesn't support ASM_OUTPUT_BSS. */
1518
1519 /* First make the assembler name(s) global ifappropriate. */
1520 if (TREE_PUBLIC (decl) && DECL_NAME(decl))
1521 globalize_decl(decl);
1522
1523 /* Switch to theappropriate section. */
1524 variable_section (decl, reloc);
1525
1526 /* dbxout.c needsto know this. */
1527 if (in_text_section ())
1528 DECL_IN_TEXT_SECTION (decl) = 1;
1529
1530 /* Output thealignment of this data. */
1531 if (align > BITS_PER_UNIT)
1532 {
1533 ASM_OUTPUT_ALIGN(asm_out_file,
1534 floor_log2 (DECL_ALIGN(decl) / BITS_PER_UNIT));
1535 }
1536
1537 /* Do anymachine/system dependent processing of the object. */
1538 #ifdefASM_DECLARE_OBJECT_NAME
1539 last_assemble_variable_decl = decl;
1540 ASM_DECLARE_OBJECT_NAME(asm_out_file,name, decl);
1541 #else
1542 /* Standard thing isjust output label for the object. */
1543 ASM_OUTPUT_LABEL (asm_out_file, name);
1544 #endif /* ASM_DECLARE_OBJECT_NAME */
1545
1546 if (!dont_output_data)
1547 {
1548 if (DECL_INITIAL (decl) &&DECL_INITIAL (decl) != error_mark_node)
1549 /* Output theactual data. */
1550 output_constant(DECL_INITIAL (decl),
1551 tree_low_cst (DECL_SIZE_UNIT(decl), 1),
1552 align);
1553 else
1554 /* Leave spacefor it. */
1555 assemble_zeros(tree_low_cst (DECL_SIZE_UNIT (decl), 1));
1556 }
1557 }
The rest procedure is very similar with that we see previously. Notethat constant without initializer is handled at line 1555.
- Studying note of GCC-3.4.6 source (172)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- C 如何检测内存出错
- GCC-3.4.6源代码学习笔记(172)
- 孩子为什么不听话?因为你不会批评!
- sqlserver 数据转换 asp.net
- STM32 GPIO
- Studying note of GCC-3.4.6 source (172)
- 资源函数
- SCU 2011 warmup contest 5
- 摘抄一些函数
- 《人生六部书——处世经典 之方圆处世》
- android之字符串自动关联相应程序,主要有email/phone/web
- GCC-3.4.6源代码学习笔记(173)
- word 文字 阴影 背景
- c中的续行符为"/"