Segher Boessenkool <seg...@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@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