bfd_[fs]printf_vma() truncating values

Jan Beulich jbeulich@suse.com
Tue May 4 06:22:47 GMT 2021


On 04.05.2021 03:16, Alan Modra wrote:
> On Mon, May 03, 2021 at 04:11:11PM +0200, Jan Beulich via Binutils wrote:
>> When putting together 9a8041fd94b7 ("gas: drop sprint_value()") I failed
>> to pay attention to bfd_sprintf_vma() silently truncating values for
>> 32-bit binaries.
> 
> Which is exactly what happens when building for a 32-bit target on a
> 32-bit host.  I don't see there is any problem here.

Good point (I assume you additionally mean a !BFD64 build). But then
I'm observing (for i686) diagnostics like

Warning: 00000001000000f4 shortened to 000000f4
Error: value of 0000000100000090 too large for field of 4 bytes at 00000010

which now have become

Warning: 000000f4 shortened to 000000f4
Error: value of 00000090 too large for field of 4 bytes at 00000010

I suppose these diagnostics, which presumably wouldn't be there on a
!BFD64 build, are all bogus in the first place (ought to be consistent
between BFD64 and !BFD64 builds), but clearly one form at least makes
clear what is happening, while the other leaves one completely in the
dark as to what the assembler is really complaining about.

Jan

	.text

# Bogus "Warning: 00000001000000.. shortened to 00000000000000.." instances with a BFD64 assembler (and --32).
# Bogus "Error: value of 00000001000000.. too large for field of 4 bytes at ..." with a BFD64 assembler (and --32).

# One part of the solution here may be to truncate constants in i386_finalize_immediate() instead of sign-extending
# them.

# It is also somewhat surprising that AT&T and Intel modes behave the same here, despite the lack of a suffix
# making e.g. optimize_imm() behave differently. At the very least this hints at some code being unnecessary
# somewhere.

long:
	mov	$500 - 0x100, %eax
	mov	$500 + 0xffffff00, %edx
	mov	$val - 0x100, %eax
	mov	$val + 0xffffff00, %edx
	mov	$sym - 0x100, %eax
	mov	$sym + 0xffffff00, %edx
	mov	$sym + 500 - 0x100, %eax
	mov	$sym + 500 + 0xffffff00, %edx

	movl	$500 - 0x100, (%eax)
	movl	$500 + 0xffffff00, (%edx)
	movl	$val - 0x100, (%eax)
	movl	$val + 0xffffff00, (%edx)
	movl	$sym - 0x100, (%eax)
	movl	$sym + 0xffffff00, (%edx)
	movl	$sym + 500 - 0x100, (%eax)
	movl	$sym + 500 + 0xffffff00, (%edx)

	add	$500 - 0x100, %ecx
	add	$500 + 0xffffff00, %edx
	add	$val - 0x100, %ecx
	add	$val + 0xffffff00, %edx
	add	$sym - 0x100, %ecx
	add	$sym + 0xffffff00, %edx
	add	$sym + 500 - 0x100, %ecx
	add	$sym + 500 + 0xffffff00, %edx

	addl	$500 - 0x100, (%eax)
	addl	$500 + 0xffffff00, (%edx)
	addl	$val - 0x100, (%eax)
	addl	$val + 0xffffff00, (%edx)
	addl	$sym - 0x100, (%eax)
	addl	$sym + 0xffffff00, (%edx)
	addl	$sym + 500 - 0x100, (%eax)
	addl	$sym + 500 + 0xffffff00, (%edx)

	.intel_syntax noprefix

	mov	eax, 500 - 0x100
	mov	edx, 500 + 0xffffff00
	mov	eax, offset val - 0x100
	mov	edx, offset val + 0xffffff00
	mov	eax, offset sym - 0x100
	mov	edx, offset sym + 0xffffff00
	mov	eax, offset sym + 500 - 0x100
	mov	edx, offset sym + 500 + 0xffffff00

	mov	dword ptr [eax], 500 - 0x100
	mov	dword ptr [edx], 500 + 0xffffff00
	mov	dword ptr [eax], offset val - 0x100
	mov	dword ptr [edx], offset val + 0xffffff00
	mov	dword ptr [eax], offset sym - 0x100
	mov	dword ptr [edx], offset sym + 0xffffff00
	mov	dword ptr [eax], offset sym + 500 - 0x100
	mov	dword ptr [edx], offset sym + 500 + 0xffffff00

	add	ecx, 500 - 0x100
	add	edx, 500 + 0xffffff00
	add	ecx, offset val - 0x100
	add	edx, offset val + 0xffffff00
	add	ecx, offset sym - 0x100
	add	edx, offset sym + 0xffffff00
	add	ecx, offset sym + 500 - 0x100
	add	edx, offset sym + 500 + 0xffffff00

	add	dword ptr [eax], 500 - 0x100
	add	dword ptr [edx], 500 + 0xffffff00
	add	dword ptr [eax], offset val - 0x100
	add	dword ptr [edx], offset val + 0xffffff00
	add	dword ptr [eax], offset sym - 0x100
	add	dword ptr [edx], offset sym + 0xffffff00
	add	dword ptr [eax], offset sym + 500 - 0x100
	add	dword ptr [edx], offset sym + 500 + 0xffffff00

	.equ	val, 400

	ret


More information about the Binutils mailing list