-
Notifications
You must be signed in to change notification settings - Fork 165
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
base: master
Are you sure you want to change the base?
Conversation
** 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. |
There was a problem hiding this comment.
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."
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
f8dd7ac
to
afaee85
Compare
afaee85
to
b847181
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM :)
@rui314 @MaskRay any comments? generally I would like get at least one more LGTM from someone other than GNU folk, but I know it's kinda embedded stuffs which you may not interested on that, so it's fine if no comment, but I would like to make sure it's at least not looks insane to linker expert. @Nelson1225 You and me has spend times on discussion this before, and we both like this, so I assume you are OK with this, but I guess it would be great to get your explicitly LGTM here again :) |
riscv-elf.adoc
Outdated
* 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. | ||
|
||
NOTE: Implementations are permitted to apply alternative rules for choosing between GP-relative or PC-relative addressing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notes are non-normative, so can't override what's outside a note. If it's not required then the spec above needs to not dictate the rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put the old description as part of the non-normative note. Please check if that addresses your concern.
** 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. |
There was a problem hiding this comment.
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?
b847181
to
7ab01ee
Compare
7ab01ee
to
85e1c31
Compare
I am happy with the GP-relative relocation part (also used by the FDPIC ABI proposal), but I am afraid I am concerned of Also CC @sorear |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a good understanding of the use cases for embedded systems that need PIC but not shared libraries. Is there any freely source available example of something that would use this? If it's needed for a commercial RTOS, is there at least a public manual or datasheet?
@MaskRay Was your comment questioning the existence of the use case for ePIC without shared libraries, suggesting that ePIC should be a special case of FDPIC, or something else?
Assuming that the use case is valid, the general approach looks good. Relocation behavior needs to be described in the language of externally observable linker behavior, not implementation details like synthesized non-dynamic relocations. I think we also need an absolute option, at least for weak symbols but it may be useful more generally.
* 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. | ||
|
||
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for this change
@@ -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. |
There was a problem hiding this comment.
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).
* 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. |
There was a problem hiding this comment.
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.
* For GP-relative addressing: | ||
** Nothing needs to be done. | ||
|
||
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." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete, not observable.
* 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. |
There was a problem hiding this comment.
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.
<| 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)` |
There was a problem hiding this comment.
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.
* 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. |
There was a problem hiding this comment.
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.
My comment is questioning the existence of the use case for ePIC without shared libraries. I think we should consider FDPIC, which works with MMU-less and MMU systems, supports dynamic libraries. After FDPIC support, we can figure out whether there is still ePIC need. (I kinda suspect no.) |
Continuing to follow up on the request to decompose the ePIC PR into multiple PRs, this PR adds the ePIC relocations and rewrite rules.