[RFC PATCH 8/8] powerpc/64/asm: don't reassign labels
Daniel Axtens
dja at axtens.net
Fri Feb 26 11:28:38 AEDT 2021
Segher Boessenkool <segher at kernel.crashing.org> writes:
> On Thu, Feb 25, 2021 at 02:10:06PM +1100, Daniel Axtens wrote:
>> The assembler really does not like us reassigning things to the same
>> label:
>>
>> <instantiation>:7:9: error: invalid reassignment of non-absolute variable 'fs_label'
>>
>> This happens across a bunch of platforms:
>> https://github.com/ClangBuiltLinux/linux/issues/1043
>> https://github.com/ClangBuiltLinux/linux/issues/1008
>> https://github.com/ClangBuiltLinux/linux/issues/920
>> https://github.com/ClangBuiltLinux/linux/issues/1050
>>
>> There is no hope of getting this fixed in LLVM, so if we want to build
>> with LLVM_IAS, we need to hack around it ourselves.
>>
>> For us the big problem comes from this:
>>
>> \#define USE_FIXED_SECTION(sname) \
>> fs_label = start_##sname; \
>> fs_start = sname##_start; \
>> use_ftsec sname;
>>
>> \#define USE_TEXT_SECTION()
>> fs_label = start_text; \
>> fs_start = text_start; \
>> .text
>>
>> and in particular fs_label.
>
> The "Setting Symbols" super short chapter reads:
>
> "A symbol can be given an arbitrary value by writing a symbol, followed
> by an equals sign '=', followed by an expression. This is equivalent
> to using the '.set' directive."
>
> And ".set" has
>
> "Set the value of SYMBOL to EXPRESSION. This changes SYMBOL's value and
> type to conform to EXPRESSION. If SYMBOL was flagged as external, it
> remains flagged.
>
> You may '.set' a symbol many times in the same assembly provided that
> the values given to the symbol are constants. Values that are based on
> expressions involving other symbols are allowed, but some targets may
> restrict this to only being done once per assembly. This is because
> those targets do not set the addresses of symbols at assembly time, but
> rather delay the assignment until a final link is performed. This
> allows the linker a chance to change the code in the files, changing the
> location of, and the relative distance between, various different
> symbols.
>
> If you '.set' a global symbol, the value stored in the object file is
> the last value stored into it."
>
> So this really should be fixed in clang: it is basic assembler syntax.
No doubt I have explained this poorly.
LLVM does allow some things, this builds fine for example:
.set foo, 8192
addi %r3, %r3, foo
.set foo, 1234
addi %r3, %r3, foo
However, this does not:
a:
.set foo, a
addi %r3, %r3, foo at l
b:
.set foo, b
addi %r3, %r3, foo-a
clang -target ppc64le -integrated-as foo.s -o foo.o -c
foo.s:5:11: error: invalid reassignment of non-absolute variable 'foo' in '.set' directive
.set foo, b
^
gas otoh, has no issues with reassignment:
$ powerpc64-linux-gnu-as foo.s -c -o foo.o
$ powerpc64-linux-gnu-objdump -dr foo.o
foo.o: file format elf64-powerpc
Disassembly of section .text:
0000000000000000 <a>:
0: 38 63 00 00 addi r3,r3,0
2: R_PPC64_ADDR16_LO .text
0000000000000004 <b>:
4: 38 63 00 04 addi r3,r3,4
It seems the llvm assembler only does a single pass, so they're not keen
on trying to support reassigning labels with non-absolute values.
Kind regards,
Daniel
>
> Segher
More information about the Linuxppc-dev
mailing list