gas: consistently emit diagnostics for non-zero data emission to .bss/.struct gas/ 2015-12-07 Jan Beulich * read.c (in_bss): New. (do_align): Use it to also warn for non-zero fill in .bss. (do_org): Likewise. (s_space): Likewise. (s_fill): Error on bad use in .bss/.struct. (float_cons): Likewise. (emit_leb128_expr): Likewise. (emit_expr_with_reloc): Defer handling use inside .struct. Also error on non-zero item added to .bss. (stringer_append_char): Error on non-zero character. gas/ 2015-12-07 Jan Beulich * gas/elf/bad-bss.d, gas/elf/bad-bss.err: New. * gas/elf/bss.d, gas/elf/bss.s: New. * gas/elf/elf.exp: Run new tests. --- 2015-12-07/gas/read.c +++ 2015-12-07/gas/read.c @@ -1337,6 +1337,14 @@ convert_to_bignum (expressionS *exp, int exp->X_add_number = i; } +static bfd_boolean +in_bss (void) +{ + flagword flags = bfd_get_section_flags (stdoutput, now_seg); + + return (flags & SEC_ALLOC) && !(flags & (SEC_LOAD | SEC_HAS_CONTENTS)); +} + /* For most MRI pseudo-ops, the line actually ends at the first nonquoted space. This function looks for that point, stuffs a null in, and sets *STOPCP to the character that used to be there, and @@ -1402,13 +1410,17 @@ s_abort (int ignore ATTRIBUTE_UNUSED) static void do_align (int n, char *fill, int len, int max) { - if (now_seg == absolute_section) + if (now_seg == absolute_section || in_bss ()) { if (fill != NULL) while (len-- > 0) if (*fill++ != '\0') { - as_warn (_("ignoring fill value in absolute section")); + if (now_seg == absolute_section) + as_warn (_("ignoring fill value in absolute section")); + else + as_warn (_("ignoring fill value in section `%s'"), + segment_name (now_seg)); break; } fill = NULL; @@ -2207,6 +2219,20 @@ s_fill (int ignore ATTRIBUTE_UNUSED) if (size && !need_pass_2) { + if (now_seg == absolute_section) + { + if (rep_exp.X_op != O_constant) + as_bad (_("non-constant fill count for absolute section")); + else if (fill && rep_exp.X_add_number != 0) + as_bad (_("attempt to fill absolute section with non-zero value")); + abs_section_offset += rep_exp.X_add_number * size; + } + else if (fill + && (rep_exp.X_op != O_constant || rep_exp.X_add_number != 0) + && in_bss ()) + as_bad (_("attempt to fill section `%s' with non-zero value"), + segment_name (now_seg)); + if (rep_exp.X_op == O_constant) { p = frag_var (rs_fill, (int) size, (int) size, @@ -2777,6 +2803,10 @@ do_org (segT segment, expressionS *exp, symbolS *sym = exp->X_add_symbol; offsetT off = exp->X_add_number * OCTETS_PER_BYTE; + if (fill && in_bss ()) + as_warn (_("ignoring fill value in section `%s'"), + segment_name (now_seg)); + if (exp->X_op != O_constant && exp->X_op != O_symbol) { /* Handle complex expressions. */ @@ -3331,10 +3361,11 @@ s_space (int mult) val.X_add_number = 0; } - if (val.X_op != O_constant - || val.X_add_number < - 0x80 - || val.X_add_number > 0xff - || (mult != 0 && mult != 1 && val.X_add_number != 0)) + if ((val.X_op != O_constant + || val.X_add_number < - 0x80 + || val.X_add_number > 0xff + || (mult != 0 && mult != 1 && val.X_add_number != 0)) + && (now_seg != absolute_section && !in_bss ())) { resolve_expression (&exp); if (exp.X_op != O_constant) @@ -3375,6 +3406,8 @@ s_space (int mult) /* If we are in the absolute section, just bump the offset. */ if (now_seg == absolute_section) { + if (val.X_op != O_constant || val.X_add_number != 0) + as_warn (_("ignoring fill value in absolute section")); abs_section_offset += repeat; goto getout; } @@ -3412,7 +3445,10 @@ s_space (int mult) make_expr_symbol (&exp), (offsetT) 0, (char *) 0); } - if (p) + if ((val.X_op != O_constant || val.X_add_number != 0) && in_bss ()) + as_warn (_("ignoring fill value in section `%s'"), + segment_name (now_seg)); + else if (p) *p = val.X_add_number; } @@ -4213,15 +4249,6 @@ emit_expr_with_reloc (expressionS *exp, op = exp->X_op; - /* Allow `.word 0' in the absolute section. */ - if (now_seg == absolute_section) - { - if (op != O_constant || exp->X_add_number != 0) - as_bad (_("attempt to store value in absolute section")); - abs_section_offset += nbytes; - return; - } - /* Handle a negative bignum. */ if (op == O_uminus && exp->X_add_number == 0 @@ -4271,6 +4298,20 @@ emit_expr_with_reloc (expressionS *exp, op = O_constant; } + /* Allow `.word 0' in the absolute section. */ + if (now_seg == absolute_section) + { + if (op != O_constant || exp->X_add_number != 0) + as_bad (_("attempt to store value in absolute section")); + abs_section_offset += nbytes; + return; + } + + /* Allow `.word 0' in BSS style sections. */ + if ((op != O_constant || exp->X_add_number != 0) && in_bss ()) + as_bad (_("attempt to store non-zero value in section `%s'"), + segment_name (now_seg)); + p = frag_more ((int) nbytes); if (reloc != TC_PARSE_CONS_RETURN_NONE) @@ -4854,6 +4895,21 @@ float_cons (/* Clobbers input_line-point return; } + if (now_seg == absolute_section) + { + as_bad (_("attempt to store float in absolute section")); + ignore_rest_of_line (); + return; + } + + if (in_bss ()) + { + as_bad (_("attempt to store float in section `%s'"), + segment_name (now_seg)); + ignore_rest_of_line (); + return; + } + #ifdef md_flush_pending_output md_flush_pending_output (); #endif @@ -5186,6 +5242,18 @@ emit_leb128_expr (expressionS *exp, int op = O_big; } + if (now_seg == absolute_section) + { + if (op != O_constant || exp->X_add_number != 0) + as_bad (_("attempt to store value in absolute section")); + abs_section_offset++; + return; + } + + if ((op != O_constant || exp->X_add_number != 0) && in_bss ()) + as_bad (_("attempt to store non-zero value in section `%s'"), + segment_name (now_seg)); + /* Let check_eh_frame know that data is being emitted. nbytes == -1 is a signal that this is leb128 data. It shouldn't optimize this away. */ nbytes = (unsigned int) -1; @@ -5255,6 +5323,10 @@ s_leb128 (int sign) static void stringer_append_char (int c, int bitsize) { + if (c && in_bss ()) + as_bad (_("attempt to store non-empty string in section `%s'"), + segment_name (now_seg)); + if (!target_big_endian) FRAG_APPEND_1_CHAR (c); --- 2015-12-07/gas/testsuite/gas/elf/bad-bss.d +++ 2015-12-07/gas/testsuite/gas/elf/bad-bss.d @@ -0,0 +1,4 @@ +#name: bad .bss / .struct data allocation directives +#source: bss.s +#error-output: bad-bss.err +#target: i?86-*-* x86_64-*-* ia64-*-* arm-*-* aarch64-*-* --- 2015-12-07/gas/testsuite/gas/elf/bad-bss.err +++ 2015-12-07/gas/testsuite/gas/elf/bad-bss.err @@ -0,0 +1,63 @@ +.*bss\.s: Assembler messages: +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store float in section .\.bss. +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-empty string in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-empty string in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to fill section .\.bss. with non-zero value +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss. +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store float in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-empty string in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-empty string in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to fill section .\.bss\.local. with non-zero value +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.bss\.local. +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store float in section .\.private. +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-empty string in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-empty string in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to fill section .\.private. with non-zero value +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.private. +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.private. +.*bss\.s:[1-9][0-9]*: Error: attempt to store non-zero value in section .\.private. +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Warning: zero assumed.* +.*bss\.s:[1-9][0-9]*: Error: attempt to store value in absolute section +.*bss\.s:[1-9][0-9]*: Error: attempt to store value in absolute section +.*bss\.s:[1-9][0-9]*: Error: attempt to store value in absolute section +.*bss\.s:[1-9][0-9]*: Error: attempt to store float in absolute section +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in absolute section +.*bss\.s:[1-9][0-9]*: Error: attempt to fill absolute section with non-zero value +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in absolute section +.*bss\.s:[1-9][0-9]*: Warning: ignoring fill value in absolute section +.*bss\.s:[1-9][0-9]*: Error: attempt to store value in absolute section +.*bss\.s:[1-9][0-9]*: Error: attempt to store value in absolute section --- 2015-12-07/gas/testsuite/gas/elf/bss.d +++ 2015-12-07/gas/testsuite/gas/elf/bss.d @@ -0,0 +1,24 @@ +#name: good .bss / .struct data allocation directives +#as: --defsym okay=1 +#warning: Warning: zero assumed +#readelf: -sSW +#target: i?86-*-* x86_64-*-* ia64-*-* arm-*-* aarch64-*-* + +There are [1-9][0-9]* section headers, starting at offset 0x[0-9a-f]*: + +Section Headers: +#... + *\[ [1-9]\] *\.bss +NOBITS +0*0 +0[0-9a-f]* 0*(28|40) +0*0 +WA +0 +0 +32 + *\[ [1-9]\] *\.bss\.local +NOBITS +0*0 +0[0-9a-f]* 0*(28|40) +0*0 +WA +0 +0 +32 + *\[ [1-9]\] *\.private +NOBITS +0*0 +0[0-9a-f]* 0*(28|40) +0*0 +WA +0 +0 +32 +#... +Symbol table '\.symtab' contains [1-9][0-9]* entries: +#... + *[0-9]*: 0*28 *0 NOTYPE *LOCAL *DEFAULT *[1-9] endof_bss +#... + *[0-9]*: 0*28 *0 NOTYPE *LOCAL *DEFAULT *[1-9] endof_bss_local +#... + *[0-9]*: 0*28 *0 NOTYPE *LOCAL *DEFAULT *[1-9] endof_private +#... + *[0-9]*: 0*27 *0 NOTYPE *LOCAL *DEFAULT *ABS endof_struct +#pass --- 2015-12-07/gas/testsuite/gas/elf/bss.s +++ 2015-12-07/gas/testsuite/gas/elf/bss.s @@ -0,0 +1,56 @@ + .macro bss name + + .long 0 + .long , + + .balign 32 + + .ifnes "\name", "struct" + .ascii "" + .asciz "" + .endif + + .fill 1, 1 + .org .+1 + .skip 1 + .sleb128 + .sleb128 0 + .uleb128 + .uleb128 0 + + .ifndef okay + + .long 1 + .long . + .long x + .float 0.0 + + .balign 32, -1 + + .ifnes "\name", "struct" + .ascii "0" + .asciz "0" + .endif + + .fill 1, 1, -1 + .org .+1, -1 + .skip 1, -1 + .sleb128 -1 + .uleb128 1 + + .endif + +endof_\name: + .endm + + .bss + bss bss + + .section .bss.local, "aw" + bss bss_local + + .section .private, "aw", %nobits + bss private + + .struct + bss struct --- 2015-12-07/gas/testsuite/gas/elf/elf.exp +++ 2015-12-07/gas/testsuite/gas/elf/elf.exp @@ -204,6 +204,8 @@ if { [is_elf_format] } then { run_dump_test "dwarf2-2" run_dump_test "dwarf2-3" run_dump_test "dwarf2-4" + run_dump_test "bss" + run_dump_test "bad-bss" run_dump_test "bad-section-flag" run_dump_test "bad-size" run_dump_test "bad-group"