[0/2] RISC-V: Strict relocation handling

Message ID cover.1697436144.git.research_trasio@irq.a4lg.com
Headers
Series RISC-V: Strict relocation handling |

Message

Tsukasa OI Oct. 16, 2023, 6:02 a.m. UTC
  Hi,

[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).


[Description: 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 [1].  Luís Marques added (non-internal) GP-relative relocations (with
three new relocation types) [2].

[1] <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/eaf0b30db01255e145fd173d8a0946a4b7cce90f>
[2] <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/d49e48097bcad410e7e6d96ebf9d94d6d41dc9c0>

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 both 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 [GPREL] and 66-67 [TPREL]).


[Description: 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.



Sincerely,
Tsukasa




Tsukasa OI (2):
  RISC-V: Reject invalid relocation types
  RISC-V: Renumber internal-only [GT]PREL_[IS] reloc

 bfd/elfnn-riscv.c   |  77 +++++++++++++++++++++++-
 bfd/elfxx-riscv.c   | 140 +++++++++++++++++++++++++-------------------
 include/elf/riscv.h |  15 +++--
 3 files changed, 166 insertions(+), 66 deletions(-)


base-commit: 6674b23fe6409e08de9c36f640bd58127eff9dda