gas: fix bogus error on .org involving expression For years I have been carrying this change, and it was long forgotten what it was originally meant to deal with, hence I've never submitted it. Until I came across an issue with Linux kernel like alternative instruction patching, where the space needed to hold the replacement instruction was allocated using .org. Things built fine for me (since I had the patch in place), and things also built fine on 2.20. But assemblers from at least 2.22 onwards produce an undefined symbol warning for the "orig" label in the new test case, followed by an error complaining that .org would be moving backwards (which is a logical consequence of the undefined symbol getting replaced by plain zero). gas/ 2016-03-22 Jan Beulich * config/tc-hppa.c (get_expression): Also allow expr_section. * config/tc-i386.c (i386_finalize_immediate): Likewise. (i386_finalize_displacement): Likewise. * expr.c (expr): Set retval to expr_section for expressions involving symbols, which cannot be resolved right away. gas/testsuite/ 2016-03-22 Jan Beulich * expr-org.s, expr.org.d: New. * gas.exp: Run new test. --- 2016-03-22/gas/config/tc-hppa.c +++ 2016-03-22/gas/config/tc-hppa.c @@ -1282,6 +1282,7 @@ get_expression (char *str) input_line_pointer = str; seg = expression (&the_insn.exp); if (!(seg == absolute_section + || seg == expr_section || seg == undefined_section || SEG_NORMAL (seg))) { --- 2016-03-22/gas/config/tc-i386.c +++ 2016-03-22/gas/config/tc-i386.c @@ -8043,6 +8043,7 @@ i386_finalize_immediate (segT exp_seg AT && exp_seg != text_section && exp_seg != data_section && exp_seg != bss_section + && exp_seg != expr_section && exp_seg != undefined_section && !bfd_is_com_section (exp_seg)) { @@ -8336,6 +8337,7 @@ i386_finalize_displacement (segT exp_seg && exp_seg != text_section && exp_seg != data_section && exp_seg != bss_section + && exp_seg != expr_section && exp_seg != undefined_section && !bfd_is_com_section (exp_seg)) { --- 2016-03-22/gas/expr.c +++ 2016-03-22/gas/expr.c @@ -1998,7 +1998,11 @@ expr (int rankarg, /* Larger # is highe retval = absolute_section; rightseg = absolute_section; } + else + retval = expr_section; } + else + retval = expr_section; } else { @@ -2010,17 +2014,18 @@ expr (int rankarg, /* Larger # is highe resultP->X_add_number = 0; resultP->X_unsigned = 1; resultP->X_extrabit = 0; + retval = expr_section; } if (retval != rightseg) { - if (retval == undefined_section) + if (retval == expr_section) ; - else if (rightseg == undefined_section) + else if (rightseg == expr_section) retval = rightseg; - else if (retval == expr_section) + else if (retval == undefined_section) ; - else if (rightseg == expr_section) + else if (rightseg == undefined_section) retval = rightseg; else if (retval == reg_section) ; --- 2016-03-22/gas/testsuite/gas/all/expr-org.d +++ 2016-03-22/gas/testsuite/gas/all/expr-org.d @@ -0,0 +1,11 @@ +#objdump: -s -j .data -j .alt +#name: .org with expression (with forward reference) + +.*: .* + +Contents of section \.data: + 0000 [0f][0f]ffff[0f][0f] 01[0 .]* + +Contents of section \.alt: + 0000 00000000 [ .]* +#pass --- 2016-03-22/gas/testsuite/gas/all/expr-org.s +++ 2016-03-22/gas/testsuite/gas/all/expr-org.s @@ -0,0 +1,10 @@ + .data +orig: + .byte 0 + .org orig + (alt_end - alt_begin), 0xff + .pushsection .alt, "a", %progbits +alt_begin: + .long 0 +alt_end: + .popsection + .byte 1 --- 2016-03-22/gas/testsuite/gas/all/gas.exp +++ 2016-03-22/gas/testsuite/gas/all/gas.exp @@ -432,6 +432,11 @@ gas_test_error "weakref4.s" "" "is alrea run_dump_test string if [is_elf_format] { run_dump_test none + +# Targets enabling OBJ_COMPLEX_RELC don't seem to be compatible with this. + if { ![istarget "mep-*-*"] } { + run_dump_test expr-org + } } run_dump_test quoted-sym-names