[PATCH] RISC-V: Do fixup for local symbols while with "-mno-relax"

Palmer Dabbelt palmer@dabbelt.com
Wed Dec 13 03:10:44 GMT 2023


On Tue, 12 Dec 2023 18:47:05 PST (-0800), Palmer Dabbelt wrote:
> On Tue, 12 Dec 2023 17:26:03 PST (-0800), i@maskray.me wrote:
>>> In the scenario of generating .ko files, the kernel does not relax the .ko
>>> files. However, due to the large amount of relax and local relocation
>>> information, this increases the size of the .ko files.
>>>
>>> In this patch, it will finish the fixup of the local relocations while with
>>> "-mno-relax" option. This can reduce the size of the relocation table.
>>
>> Thanks for the patch.  I was initially confused by the description.
>> Perhaps clarify it to: "... the Linux kernel uses -mno-relax but still
>> gets a lot of relocations which can be eliminated" and "... resolve
>> some fixups to constants and remove relocations"
>>
>> On Tue, Dec 12, 2023 at 4:31 PM Palmer Dabbelt <palmer@dabbelt.com> wrote:
>>>
>>> On Tue, 12 Dec 2023 02:44:07 PST (-0800), nelson@rivosinc.com wrote:
>>> > There is another stuff, do we need to limit linkers that only can link the
>>> > objects with -mno-relax if this optimization applied?  If so, then we
>>> > probably need,
>>> > 1. An assembler option for this optimization
>>> > 2. Record the object is relaxable or not into the elf attribute?  or
>>> > readelf header?  or ...
>>> > 2.1 Maybe we can record the relaxation information with
>>> > Tag_RISCV_x3_reg_usage?,
>>> > https://sourceware.org/pipermail/binutils/2023-September/129500.html?
>>> > 2.2 Once the object enables relaxation for some code, the object needs to
>>> > be marked as "relaxable", even if it sets `.option norelax' later.
>>> >
>>> > On Tue, Dec 12, 2023 at 5:46 PM Nelson Chu <nelson@rivosinc.com> wrote:
>>> >
>>> >> The idea looks good to me.  Passed regressions of riscv-gnu-toolchain, so
>>> >> committed with some minor changes and indent fixes.
>>> >>
>>> >> There are some TODOs, but no rush to do for now,
>>> >> 1. The implementation is based on the code from bfd/elfnn-riscv.c.  We
>>> >> probably can move the code to bfd/elfxx-riscv.c, so that can reduce
>>> >> duplicate code, just like what we did for the architecture parser.
>>> >> Before that, I renamed functions and variables from *reloc* to *fixup*, to
>>> >> distinguish the code from bfd/elfnn-riscv.c, since they are still a little
>>> >> bit different.
>>> >> 2. Maybe not only pcrel_hi/lo12 relocation with local symbols can be resolved
>>> >> at assembler time.  Other pc-relative relocation, like branch, may also
>>> >> be able to perform related optimizations.
>>
>> Agree that GNU assembler can resolve more PC-relative instructions to
>> a constant without a relocation.
>> For example, LLVM integrated assembler resolves the following `j` to constants:
>>
>>     // clang --target=riscv64-linux-gnu -march=rv64i -mno-relax -c
>>     j .Ltmp1
>>     j .Ltmp1
>>     .Ltmp1:
>>
>> (Though LLVM has its own problem that a `.option relax` anywhere in
>> the assembly file will lose this optimization.)
>>
>>> Nelson and I were just talking about this.  I'd been leaning towards
>>> adding another option along the lines of "-mno-relax-abi", which would
>>> explicitly mean that users can depend on no objects being relaxed.  That
>>> said, I'm not actually sure I can come up with a case where anything
>>> breaks.
>>>
>>> I was specifically worried about things like the compiler doing label
>>> subtraction, but IIUC that can only happen within a single translation
>>> unit so we're safe to take advantage of on R_RISCV_RELAX relocations.
>>>
>>> There's also cases like misaligned globals, but we're already broken
>>> there so I'm not sure it counts.
>>>
>>> So maybe this safe?
>>
>> I lean towards not providing an option.  Beside the previous paragraph
>> that LLVM integrated assembler omits relocations in more cases,
>> architectures not using linker relaxation do optimize out relocations
>> in these cases as well.
>> It's a missing size optimization for RISC-V in the -mno-relax configuration.
>> Users relying on the relocation can switch to `.reloc ., R_RISCV_JAL, xx`.
>
> Sorry for being confusing: I agree resolving local R_RISCV_CALL
> relocations at assembly time (or I guess, not having R_RISCV_CALL at
> all) is safe as long as the call does not cross a R_RISCV_RELAX (or any
> of the normal-smelling boundaries like sections and such).
>
> Nelson and I were wondering if many other PC-relative relocations can be
> processed at assembly time whenever they don't cross a R_RISCV_RELAX

I guess that's a silly statement: of course we can do all the 
assembler-time processing.  I was mixing up compile-time stuff like 
working around the auipc overflows in there -- I think we can also do 
that sort of stuff, I just forgot there was anything going on before the 
assembler.

Probably time to get some sleep...

> boundary (and meet all the other rules the other ports need to deal
> with).  I think there's a bunch where we can, and it's possible just
> having no relaxations in an object is sufficient to enable any of these
> optimizations.
>
> FWIW, I'd still lean towards providing some sort of option/ELF flag that
> just bans relaxation entirely -- we basically don't use it in modern
> Linux user binaries (unless I missed some PIE optimizations going in),
> so we might as well just properly forbid relaxation.


More information about the Binutils mailing list