On Tue, Dec 01, 2020 at 01:03:07PM +0100, Richard Biener wrote: > > So yes, we can either do a sorry, error, or could just avoid 64-bit > > relocations (depending on endianity instead of emitting > > .quad expression_that_needs_relocation > > emit > > .long expression_that_needs_relocation, 0 > > or > > .long 0, expression_that_needs_relocation > > So, which way do we want to go? > > 64bit relocs are not required here? That is, can one with > dwarf64 choose 32bit forms for select offsets (like could > dwz exploit this?)?
I guess it depends on whether for 32-bit target and -gdwarf64, when calling dw2_assemble_integer with non-CONST_INT argument we only need positive values or might need negative ones too. Because positive ones can be easily emulated through that .long expression, 0 or .long 0, expression depending on endianity, but I'm afraid there is no way to emit 0 or -1 depending on the sign of expression, when it needs relocations. Looking through dw2_asm_output_delta calls, at least the vast majority of the calls seem to guarantee being positive, not 100% sure about one case in .debug_line views, but I'd hope it is ok too. In most cases, the deltas are between two labels where the first one in the arguments is later in the same section than the other one, or where the second argument is the start of a section or another section base. This patch implements that, dunno if we need also configure tests for that or not, maybe some 32-bit targets use 64-bit ELF and can handle such relocations. 2020-12-01 Jakub Jelinek <ja...@redhat.com> * dwarf2asm.c (dw2_assemble_integer): Handle size twice as large as DWARF2_ADDR_SIZE if x is not a scalar int by emitting it as two halves, one with x and the other with const0_rtx, ordered depending on endianity. --- gcc/dwarf2asm.c.jj 2020-01-12 11:54:36.558411221 +0100 +++ gcc/dwarf2asm.c 2020-12-01 13:42:38.347298352 +0100 @@ -46,6 +46,52 @@ along with GCC; see the file COPYING3. void dw2_assemble_integer (int size, rtx x) { + if (size == 2 * DWARF2_ADDR_SIZE && !CONST_SCALAR_INT_P (x)) + { + /* On 32-bit targets with -gdwarf64, DImode values with + relocations usually result in assembler errors. Assume + all such values are positive and emit the relocation only + in the least significant half. */ + const char *op = integer_asm_op (DWARF2_ADDR_SIZE, FALSE); + if (BYTES_BIG_ENDIAN) + { + if (op) + { + fputs (op, asm_out_file); + fprint_whex (asm_out_file, 0); + fputs (", ", asm_out_file); + output_addr_const (asm_out_file, x); + } + else + { + assemble_integer (const0_rtx, DWARF2_ADDR_SIZE, + BITS_PER_UNIT, 1); + putc ('\n', asm_out_file); + assemble_integer (x, DWARF2_ADDR_SIZE, + BITS_PER_UNIT, 1); + } + } + else + { + if (op) + { + fputs (op, asm_out_file); + output_addr_const (asm_out_file, x); + fputs (", ", asm_out_file); + fprint_whex (asm_out_file, 0); + } + else + { + assemble_integer (x, DWARF2_ADDR_SIZE, + BITS_PER_UNIT, 1); + putc ('\n', asm_out_file); + assemble_integer (const0_rtx, DWARF2_ADDR_SIZE, + BITS_PER_UNIT, 1); + } + } + return; + } + const char *op = integer_asm_op (size, FALSE); if (op) Jakub