Skip to content

riscv_linker_reloc_strict_1

Tsukasa OI edited this page Oct 19, 2023 · 2 revisions

Linker: Strict relocation handling

Issue Solved

Background

RISC-V BFD ELF handler has many relocation types but some of them are internal use only (must not be placed on either object file or resulting executable/shared library file).

WARNING: Below is the description of the PATCH v1 and there are some changes in PATCH v2.

PATCH 2/2

And after RISC-V psABI version 1.0 is ratified, this ABI specification is getting improved and enhanced.

Tatsuyuki Ishi enhanced the TLS descriptor model with four new relocation types. Luís Marques added (non-internal) GP-relative relocations (with three new relocation types).

Of which, numbers 47-49 conflict with Binutils' internal relocation types.

Note that, though GP-relative relocations are similar to GNU Binutils' internal ones, psABI ones (proposed by Luís) does not allow changing rd (destination register) to gp/zero, requiring separate relocation types. Also, GNU Binutils' ones only accept one instruction relocations.

That's exactly why psABI's TPREL_LO12_[IS] (corresponding GNU Binutils' R_RISCV_TPREL_LO12_[IS]) and GNU Binutils' internal R_RISCV_TPREL_[IS] are still there.

We are not sure whether those new relocation types will get ratified but at least should be aware of them.

N psABI type (draft) Binutils type
47 GPREL_LO12_I R_RISCV_GPREL_I
48 GPREL_LO12_S R_RISCV_GPREL_S
49 GPREL_HI20 R_RISCV_TPREL_I
50 (reserved) R_RISCV_TPREL_S

So, we should move those internal only relocation types. That's the intent of PATCH 2/2 and moves internal ones them to unused/reserved spaces (41-42 for GPREL and 66-67 for TPREL).

PATCH 1/2

Also in the first place, this kind of change and the current design reusing the same relocation type space both for external ones and internal only ones poses an issue: a new relocation type may be a severe problem on the future.

We haven't rejected such internal use only relocation types such as R_RISCV_GPREL_I and R_RISCV_RVC_LUI. The effect if internal only type is accidentally fed into the older linker is pretty much unpredictable.

Before an accident happens, we should start rejecting unknown relocation types, at least on the linker. PATCH 1/2 allows only known relocation types and explicitly rejects internal only relocation types (when the object file is fed to the linker, the check only happens before linker relaxation occurs, allowing linker relaxation to use internal only relocation types).

By adding separate checks, this patch also rejects unknown relocation types on other tools such as objdump and objcopy.

Changes on the tools (summary)

They did reject unknown big relocation types (e.g. relocation type 191 == 0xBF) but not small relocation types and internal use only ones. PATCH 1/2 makes them to reject those small/internal relocations.

Clone this wiki locally