Invalid operands for binary AND (&)

I have this "prefabricated" file (containing only )

// declare protected region as somewhere within the stack .equiv prot_start, $stack_top & 0xFFFFFF00 - 0x1400 .equiv prot_end, $stack_top & 0xFFFFFF00 - 0x0C00 

In conjunction with this linker script:

 SECTIONS { "$stack_top" = 0x10000; } 

Assembly creates this output

 file.s: Assembler messages: file.s: Error: invalid operands (*UND* and *ABS* sections) for `&' when setting `prot_start' file.s: Error: invalid operands (*UND* and *ABS* sections) for `&' when setting `prot_end' 

How can I do this job?

+4
source share
2 answers

Darn:

Infix Operators

Infix operators take two arguments, one on either side. Operators take precedence, but operations with equal priority are performed from left to right. In addition to + or - , both arguments must be absolute , and the result is absolute.

+1
source

Why is this impossible?

You are associated with GAS documents, but what is the reason for this inability?

Answer: GAS must associate operations with the linker through the ELF object file, and the only thing that can be passed as follows: + and - ( - - this is just + negative value). Thus, this is a fundamental limitation of the ELF format, and not just laziness from the developers of GAS.

When the GAS is compiled into an object file, the step of the link will follow, and this is the move that will determine the final value of the character.

Question: why can I pass + , but not & ?

Answer: because + transitive: (a + b) + c == a + (b + c) , but + and & are not "transitive together": (a & b) + c!= a & (b + c)

Let's see how + is transmitted through the ELF format to convince ourselves that & not possible.

First find out what a move is if you are not familiar with it: fooobar.com/questions/4539 / ...

Let minimize your example with another that will 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 disassembly, as this is not code, and look only at characters, bytes, and permutations.

We have two relocations R_386_32 . From System V ABI for IA-32 (which defines the ELF format), this type of movement is calculated as:

 S + A 

Where:

  • S : value before moving in the object file.

    A value before moving == 08 00 00 00 == 8 in little endian

    b value before moving == 80 56 34 12 == 0x12345680 in little endian

  • a : addend, rellocation entry field, here 0 (not shown objdump ), so let's just forget about it.

When the move occurs:

  • a will be replaced by:

     address of text section + 8 

    There is + 8 , because s: is the 8th byte of the text section, preceded by 2 longs.

  • b will be replaced by:

      address of text section + (0x12345678 + 8) == address of text section + 0x12345680 

    Aha, therefore 0x12345680 appeared in the object file!

So, as we just saw, you can express + in the ELF file by simply adding to the actual offset.

But it would be impossible to express & with the help of this mechanism (or any other that I know), because we do not know what the address of the text section will be after the transfer, therefore we cannot apply & to it.

+3
source

Source: https://habr.com/ru/post/1499466/


All Articles