format elf64
extrn foo
dd foo+1 ; this is fine
dd foo+0 ; this is fine
dd foo-1 ; <--- error: value out of range.
This can be tracked to a change at version 1.69.41 (Mar 01, 2012).
In exprcalc.inc line 1330:
get_dword_value:
mov [value_size],4
or [operand_flags],1
call calculate_value
cmp al,4
jne check_dword_value
mov [value_type],2
mov eax,[edi]
cdq
cmp edx,[edi+4]
jne range_exceeded
mov ecx,edx
shr ecx,31 ; <--- using sar fixes the bug
cmp cl,[value_sign]
jne range_exceeded
ret
The relocation table is correct for positive offsets.
Relocation section '.rela.flat' at offset 0x48 contains 1 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 00020000000b R_X86_64_32S 0000000000000000 foo + 1
But is impossible to generate for negative offsets.