-
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
Relocations, ELF Markers, and >32-bit Instructions #453
Comments
For instruction alignment, just because your instructions individually can be 16-bit aligned doesn't mean the whole section only needs that. For example, The relocation normally needs to imply the instruction size, yes. Even on X86 where the actual operand may be encoded in a uniform manner despite different instruction prefixes, the number of prefix bytes still gets encoded so you can do relaxation (albeit in a more limited manner there). |
Importantly, I don't think I can see how 48-bit instructions work without having a 16-bit NOP. Ditching the rest of C seems fine, but I think you need at least that one instruction from it. |
Ah, ok I did miss this nuance, that executable section alignment isn't 1:1 with
I will go and read the x86 psABI to understand how it deals with relaxation and long instructions better, thanks for the tip. I think you're agreeing with my intended direction though, which sounds positive to me.
If you have 48-bit instructions (or any odd multiple of 16 bits), those extensions not implying |
I don't mean that they have to be followed by a 16-bit instruction. But for, say, R_RISCV_ALIGN, we currently insert c.nop if the padding is 2 mod 4. This case can't arise with 32-bit-only instructions, but can with 16+32-bit, and can with 32+48-bit. How do you insert 2 bytes of padding without c.nop? (You can of course do it 2n+2 for n > 0 if you have a 48-bit NOP, but n = 0 is a special case) |
Thanks for clarifying, I had momentarily forgotten the "align with nops" requirements. Given the smallest architecture that contains I also read the x86-64 psabi and understand a bit more what's going on there, even though the relaxable relocations are mid-way through an instruction (at the start of an immediate field, which I think always comes last), the types indicate where the instruction started. It's a lot less clean than just having instruction types, and relevant relocations for each instruction type. |
I think the conclusion from the earlier discussion is that for instruction lengths greater than 32-bit, linker relaxation will require at least Zca, and I agree with this point. other than that, here are some additional thoughts I have on the topic: For EF_RISCV_RVC:The definition of this ELF flag has become a bit ambiguous after the introduction of Zc* standards. This ambiguity also extends to the meaning of The current definition is:
However, after introducing For dedicated relocation types for longer instruction length:I can see the possibility of reusing some relocations for longer instructions in the future—for example, using For #393:I still haven’t seen a better solution for this issue…maybe we should push forward on this with Nelson's help. |
I did think about this, as some of the 48-bit instructions in Xqci have 32-bit contiguous immediate fields - the reason I discounted it is because of big-endian. I don't think there are big endian implementations yet, but I also don't think we want to use data relocations (which have to be endianness-aware) on instructions (which are always little endian) or vice-versa. I don't think altering the interpretation of a relocation depending on whether a section is executable or based on the marker symbols (for two examples) is a viable route forwards.
|
Good point on the endian...I didn't aware that, but that definite a potential issue, BTW, we did have few non-standard big endian software support like spike and GNU toolchain. |
I think I might be the first person to use Let's for the moment, imagine there's a
I don't think vendor name symbols are the only thing affected by this - anywhere where we have symbols where their name is important but their definition isn't (such as the proposal for Mapping symbols are not quite the same as this - yes we care about their name, but we also care about their defined location, which we don't for these vendor symbols. Mapping Symbols (at least in RISC-V) are defined local symbols. |
I'm happy to announce that Qualcomm has released an initial version of our psabi extensions, which are available here: https://github.com/quic/riscv-elf-psabi-quic-extensions/releases/tag/v0.1 The discussion here has been very influential on this development specification, thank you for your help with these queries. |
I took a good look through the currently open issues, and none specifically
address any of these issues, but sorry if I missed something. Some of the
discussion in #393 touches on these issues but not in any great depth. I've also
been working with other architectures for a while, so am still getting back up
to speed with the RISC-V psABI details again.
This issue is going to touch on a series of related issues, around support for
longer-than-32-bit instructions. I'm sorry I didn't get this to you in time for
the most recent psABI meeting, but hopefully that gives you time to think about
the issues before the next one.
One of my central queries is about the meaning of
EF_RISCV_RVC
- this denoteswhether you can use 16-bit aligned instructions (rather than 32-bit), and
whether you can use
c
extension instructions during relaxation. I'll note thatLLVM has updated how it interprets this flag, to still mean the former, but for
the latter mean just
Zca
, not all ofC
1 (this should have been expectedwhen
C
was exploded into a lot of sub-extensions, some incompatible with eachother).
What about binaries containing 48-bit instructions? We have a set of public isa
extensions, Xqci 2, which we want to add support for, which contains 48-bit
instructions (something the core ISA standard is yet to ratify encodings for,
but space has been reserved for >32-bit instructions). 48-bit instructions
require us to have 16-bit aligned instructions (or else we would have 64-bit
instructions). In our case, none of the sub-extensions which have 48-bit
instructions also have 16-bit instructions, nor do any
require/imply
C
/Zca
.Both implications of the
EF_RISCV_RVC
flag are also redundant: sections alreadyhave an alignment (with obvious semantics when two sections are merged together:
enforce the higher alignment), and we now have architecture build attributes
which we can query to work out which extensions we are allowed to use during
relaxation.
So, should we be setting the
EF_RISCV_RVC
flag for binaries containing 48-bitinstructions? Maybe it would be ok to keep
EF_RISCV_RVC
clear but still markany code sections as having 16-bit alignment, which the linker should be
honouring? Some guidance as to a reasonable direction to take here would be
helpful. We could allocate ourselves a non-standard extension elf flag to
represent "this object contains 16-bit aligned instructions, but not necessarily
C
/Zca
", but we would like support for these instructions to go upstream andallocating a non-standard extension bit for this seems greedy and potentially
unnecessary.
I have a similar query relating to relocations on 48-bit instructions. The
Xqcibi
sub-extension (described in the release, above) contains some 48-bitbranch immediate instructions (
qc.e.b<cond>i
) where the branch offset isencoded into the exact same bits that would be used by a
b<cond>
instruction.The ISA designers did this so they could use an
R_RISCV_BRANCH
relocation intheir prototype toolchain. My concern is that this is likely to have a knock-on
effect on relaxations and beyond - we have instruction types for a reason, and
we quite like to use them in the ABI (aside: the document/yaml for
Xqci
doesn't mention instruction types, which is a drawback, but I think this is
shared by the
riscv-unified-db
upstream too). Right now, all instructionrelocations end up well-aligned with the start of the instruction they apply to.
Broadly, my question is: do we want to reuse an existing relocation like this
(on a longer instructions of a different type), or would we prefer that all
relocations are correct for the instruction type (and size)? My gut feeling is
that we do want new relocations for new instruction types, to keep relocations
obvious and aligned with instruction boundaries, but I'd be interested to hear
other opinions. I think keeping relocations aligned with instructions and only
applied to instructions with the correct type makes relaxations easier and less
brittle, but I'm not 100% sure on that. The specific implication here is that we
might end up needing quite a lot of new relocations as we get longer
instructions, but I think we'd reasonably quickly stop getting lots more
instructions for materializing addresses.
I think maybe @kito-cheng and @asb might be expecting some of these queries, but keen to hear from others too.
The text was updated successfully, but these errors were encountered: