Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ePIC relocations and rewrite rules #405

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions riscv-elf.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,16 @@ Description:: Additional information about the relocation
<| S - P
.2+| 65 .2+| TLSDESC_CALL .2+| Static | .2+| Annotate call to TLS descriptor resolver function, `%tlsdesc_call(address of %tlsdesc_hi)`, for relaxation purposes only
<|

.2+| 66 .2+| EPIC_HI20 .2+| Static | _U-Type_ .2+| <<Embedded PIC rewrite rules,Embedded PIC rewrite>> for the high 20 bits of a 32-bit PC- or GP-relative offset, `epic_hi(symbol)`
<| Rewrite
.2+| 67 .2+| EPIC_LO12_I .2+| Static | _I-type_ .2+| <<Embedded PIC rewrite rules,Embedded PIC rewrite>> for the low 12 bits of a 32-bit PC- or GP-relative offset, `epic_low(address of %epic_high)`
<| Rewrite
.2+| 68 .2+| EPIC_LO12_S .2+| Static | _S-Type_ .2+| <<Embedded PIC rewrite rules,Embedded PIC rewrite>> for the low 12 bits of a 32-bit PC- or GP-relative offset, `epic_low(address of %epic_high)`
<| Rewrite
.2+| 69 .2+| EPIC_BASE_ADD .2+| Static | _I-type_ .2+| <<Embedded PIC rewrite rules,Embedded PIC rewrite>> of `gp` addition, `%epic_base_add(symbol)`
Copy link
Collaborator

@sorear sorear Feb 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to have EPIC_BASE_ADD point at the %epic_high for consistency, and rename it EPIC_ADD.

We can get rid of EPIC_LO12_I/EPIC_LO12_S and use the overloaded PCREL_LO12_I/PCREL_LO12_S (which are also used for GOT references, so they're already somewhat of misnomers).

It might be worth getting rid of the GPREL* relocations and using EPIC* exclusively, unless GPREL* already made it into a ratified version.

<| Rewrite

.2+| 66-191 .2+| *Reserved* .2+| - | .2+| Reserved for future standard use
<|
.2+| 192-255 .2+| *Reserved* .2+| - | .2+| Reserved for nonstandard ABI extensions
Expand Down Expand Up @@ -849,6 +859,48 @@ def align(addend):
return ALIGN
----

==== Embedded PIC rewrite rules

The Embedded PIC (ePIC) relocations allow addressing a symbol relative to either the PC or the GP, as appropriate for that symbol.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to allow absolute addressing as a third option (for weak symbols, and also usable for symbols not in an output section).


NOTE: Implementations are permitted to specify their own rules for choosing between GP-relative or PC-relative addressing. A possible rule is:

* If the symbol resides in a writable output section, then GP-relative addressing is used;
* If the symbol does not reside in an output section or the section is not writable, then PC-relative addressing is used instead.
kito-cheng marked this conversation as resolved.
Show resolved Hide resolved

The ePIC relocations are applied to a sequence of instructions that initially address a symbol relative to the GP. When PC-relative addressing should be used instead, the ePIC relocations rewrite the instructions to perform PC-relative addressing and add the appropriate PC-relative relocations. When GP-relative addressing should be used, the instruction rewrites do not occur and GP-relative relocations are added. For correctness, the rewrites must occur even when linker relaxations are disabled. Paired `R_RISCV_RELAX` relocations are preserved during the rewrite process, and will pair with relocations added as part of that rewrite.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The ePIC relocations are applied to a sequence of instructions that initially address a symbol relative to the GP. When PC-relative addressing should be used instead, the ePIC relocations rewrite the instructions to perform PC-relative addressing and add the appropriate PC-relative relocations. When GP-relative addressing should be used, the instruction rewrites do not occur and GP-relative relocations are added. For correctness, the rewrites must occur even when linker relaxations are disabled. Paired `R_RISCV_RELAX` relocations are preserved during the rewrite process, and will pair with relocations added as part of that rewrite.
The ePIC relocations are applied to a sequence of instructions that initially address a symbol relative to the GP. When PC-relative addressing should be used instead, the ePIC relocations rewrite the instructions to perform PC-relative addressing. When GP-relative addressing should be used, the instruction rewrites do not occur. For correctness, the rewrites must occur even when linker relaxations are disabled. Relaxation may occur if paired `R_RISCV_RELAX` relocations are present.

The behavior of relocations needs to be specified in terms of observable linker behavior. The output will not contain non-dynamic relocations (and ePIC does not support dynamic linking), so describe it purely in terms of instruction rewrites.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for this change


===== `R_RISCV_EPIC_HI20` [[rels-epic-hi]]

The `R_RISCV_EPIC_HI20` relocation must apply to an `lui` instruction. Its behavior depends on the residence of the referenced symbol, per the <<Embedded PIC rewrite rules,ePIC rewrite rules>>.

* For PC-relative addressing:
** Rewrites the `lui` instruction into an `auipc` instruction with the same operands, by overwriting the opcode field.
** Adds a `R_RISCV_PCREL_HI20` relocation with the same symbol and addend, at the same offset.
* For GP-relative addressing:
** Adds a `R_RISCV_GPREL_HI20` relocation with the same symbol and addend, at the same offset.
Comment on lines +877 to +881
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use observable behavior.

Relaxation may delete the HI20 entirely, unless that is documented elsewhere.


===== `R_RISCV_EPIC_BASE_ADD` [[rels-epic-base]]

The `R_RISCV_EPIC_BASE_ADD` relocation must apply to an `add` or `c.add` instruction. Its behavior depends on the residence of the referenced symbol, per the <<Embedded PIC rewrite rules,ePIC rewrite rules>>.

* For PC-relative addressing, it either:
** Rewrites the addition instruction into a canonical `nop` (`addi x0, x0, 0`) or `c.nop` instruction (if the relocation is being applied to an `add` or `c.add` instruction, respectively), or
** Deletes the `add` or `c.add` instruction.
* For GP-relative addressing:
** Nothing needs to be done.
Copy link
Collaborator Author

@luismarques luismarques Nov 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, I'm hoping we'll have a R_RISCV_GPREL_ADD relocation, for relaxation purposes. If that happens, we can replace this "Nothing needs to be done" with "Optionally adds a R_RISCV_GPREL_ADD relaxation relocation with the same symbol and addend, at the same offset."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this as forward-looking non-normative next?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see if the added note properly addresses your suggestion.

Comment on lines +887 to +891
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only allow the instruction to be deleted if there is a paired R_RISCV_RELAX.

Allow deletion if there is a paired R_RISCV_RELAX and the HI20 was deleted by relaxation.


NOTE: If a `R_RISCV_GPREL_ADD` relaxation relocation is defined in the future, the GP-relative addressing rule could be updated to read: "Optionally adds a `R_RISCV_GPREL_ADD` relaxation relocation with the same symbol and addend, at the same offset."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete, not observable.


===== `R_RISCV_EPIC_LO12_*` [[rels-epic-lo]]

The `R_RISCV_EPIC_LO12_I` and `R_RISCV_EPIC_LO12_S` relocations apply to instructions encoded using the `I` and `S` instruction formats, respectively. For both of them, the symbol points to an instruction with a `R_RISCV_EPIC_HI20` relocation. Their behavior depends on the residence of the symbol referenced by the respective `R_RISCV_EPIC_HI20` relocation, per the <<Embedded PIC rewrite rules,ePIC rewrite rules>>.

* For PC-relative addressing, it either:
** Adds a `R_RISCV_PCREL_LO12_I` or `R_RISCV_PCREL_LO12_S` relocation, as appropriate, with the same symbol and addend, at the same offset.
* For GP-relative addressing:
** Adds a `R_RISCV_GPREL_LO12_I` or `R_RISCV_GPREL_LO12_S` relocation, as appropriate, at the same offset. The symbol and addend of the new relocation are those of the corresponding `R_RISCV_EPIC_HI20` relocation.
Comment on lines +899 to +902
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Describe observable behavior - it relocates and relaxes as if there were an XXX relocation, it does not create an XXX relocation.


=== Thread Local Storage

RISC-V adopts the ELF Thread Local Storage Model in which ELF objects define
Expand Down
Loading