Why it is not possible?
You have linked to the GAS docs, but what is the rationale for that inability?
Answer: GAS must communicate operations to the linker through the ELF object file, and the only things that can be conveyed like this are +
and -
(-
is just +
a negative value). So this is a fundamental limition of the ELF format, and not just lazyness from GAS devs.
When GAS compiles to the object file, a link step will follow, and it is the relocation which will determine the final value of the symbol.
Question: why can +
be conveyed, but not &
?
Answer: because +
is transitive: (a + b) + c == a + (b + c)
but +
and &
are not "transitive together": (a & b) + c!= a & (b + c)
.
Let us see how +
is conveyed through the ELF format to convince ourselves that &
is not possible.
First learn what relocation is if you are not familiar with it: https://stackoverflow.com/a/30507725/895245
Let's minimize your example with another that would generate the same error:
a: .long s
b: .long s + 0x12345678
/* c: .long s & 1 */
s:
Compile and decompile:
as --32 -o main.o main.S
objdump -dzr main.o
The output contains:
00000000 <a>:
0: 08 00 or %al,(%eax)
0: R_386_32 .text
2: 00 00 add %al,(%eax)
00000004 <b>:
4: 80 56 34 12 adcb $0x12,0x34(%esi)
4: R_386_32 .text
Ignore the disassembly since this is not code, and look just at the symbols, bytes and relocations.
We have two R_386_32
relocations. From the System V ABI for IA-32 (which defines the ELF format), that type of relocation is calculated as:
S + A
where:
S
: the value before relocation in the object file.
Value of a
before relocation == 08 00 00 00
== 8
in little endian
Value of b
before relocation == 80 56 34 12
== 0x12345680
in little endian
A
: addend, a field of the rellocation entry, here 0
(not shown by objdump
), so lets just forget about it.
When relocation happens:
a
will be replaced with:
address of text section + 8
There is a + 8
because s:
is the 8th byte of the text section, preceded by 2 longs.
b
will be replaced with:
address of text section + (0x12345678 + 8)
==
address of text section + 0x12345680
Aha, so that is why 0x12345680
appeared on the object file!
So as we've just seen, it is possible to express +
on the ELF file by just adding to the actual offset.
But it would not possible to express &
with this mechanism (or any other that I know of), because we don't what the address of the text section will be after relocation, so we can't apply &
to it.