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

ROPI/RWPI Specification (Embedded PIC) #128

Open
lenary opened this issue Jan 28, 2020 · 7 comments
Open

ROPI/RWPI Specification (Embedded PIC) #128

lenary opened this issue Jan 28, 2020 · 7 comments

Comments

@lenary
Copy link
Contributor

lenary commented Jan 28, 2020

Adam Leventhal at Oxide Computer recently asked about a ROPI/RWPI support for RISC-V

This is also something that we (@lowRISC) are interested in, and I think that @alistair23 has been looking at support for this too.

It would be great to coordinate on the development of the specification, before too much of any implementation is written, and the ELF psABI seems like the right place to collaborate (in my opinion). I hope this issue can coordinate discussion on any specification proposals.

@cbiffle
Copy link

cbiffle commented Feb 5, 2020

From my initial analysis there are a few moving parts to this. Please let me know if I've missed anything.

Definition of terms. We are talking about ROPI (read-only position independence) and RWPI (read-write position independence), which are two orthogonal tastes that taste great together:

  • ROPI allows a program's read-only (text+rodata) sections to be placed at an arbitrary address and still work, without relocation. ("Arbitrary" here is subject to alignment constraints, which we'd want to specify.) The offset between read-only sections is assumed constant (i.e. you can't place each section independently). This is related to the more general notion of position independent code (PIC) but is a slightly more precise idea.
  • RWPI allows the read-write sections to be placed independently from the read-only sections, without needing to modify the read-only section. Typically (and specifically on ARM) this means references to the read-write sections are relative to a register.

I'm not aware of an actual spec for the ROPI/RWPI support on ARM. Near as I can tell, it -- and related codegen models like GCC's -msingle-pic-base / -mpic-data-is-text-relative and friends -- are specified by the implementations. I would love to be proven wrong on this.

As a result, I'm thinking about a spec in tandem with toolchain support, so you'll see the two mixed together below.

LLVM/Clang have limited upstream ROPI/RWPI support. It currently appears to be ARM specific. GCC has similar support but under different names. Note that the upstreamed support appears to ban static pointers to moveable segments, such as function pointers in ROPI code, or data pointers in RWPI code. C++ is also banned (because vtables and rtti are difficult to implement with the above restriction).

We should evaluate Keil's ROPI/RWPI-lowering patches. Originally sent upstream in 2015, it doesn't look like the lowering parts of these changes were merged (too intrusive to Clang, it sounds like). Keil appears to be maintaining them for armclang, however. The lowering passes are critical for lifting the restrictions I mentioned in the previous paragraph. (Are the sufficient? I'm not sure; they seem sufficient...) Perhaps if these patches applied to two architectures they wouldn't be perceived as being quite as intrusive? (Jargon note: this is lowering in the sense used by compiler people, where an operation you don't support natively is expressed in terms of smaller ones that you do.)

What degree of changes are needed to the RISC-V ABI?

  • Position-independent RISC-V code is most of the way to ROPI already, if function pointers in text are either banned (as in upstream Clang ropi) or lowered/promoted (as in armclang).
  • The reservation of gp as data pointer seems like sufficient ABI support for RWPI. Code generated to a RWPI model would need to (1) use gp (or sp, presumably) to derive all effective addresses of read-write locations, and (2) fill in static RW pointers at startup time using something like Keil's lowering pass, deriving the correct addresses from gp. (The fact that the RISC-V ABI separates the roles of global pointer and thread pointer is incredibly valuable here.)

@jim-wilson
Copy link
Collaborator

My experience is that embedded pic tends to be very target dependent and everyone creates their own.  ropi/rwpi seems to be ARM's contribution to this genre.

The FDPIC scheme used by nommu embedded linux is fairly standard across targets, though I don't know if there is a formal spec for it.  There is a fdpic register that points at the data section.  Function pointers are represented as function descriptors in the data section, where the first word is the address of the function and the second word if the value for the fdpic register.  This seems to satisfy your requirements, but it does assume that there is a dynamic linker.  There are various target specific fdpic documents available.

Otherwise, having some sort of embedded pic scheme would be nice, but we don't necessarily have to copy what ARM has invented.

@cbiffle
Copy link

cbiffle commented Feb 5, 2020

True -- I referenced ARM's work only because I know it works and is supported in LLVM. It's worth considering alternatives and how they'd affect code generation.

@kito-cheng
Copy link
Collaborator

@cbiffle @lenary did you mind shared what you expected for the Embedded PIC, I mean the reason or requirement for the new code model? current PIC and medany model is not cover all scenario, but I think it would be great to know the requirements before we discuss the new code model.

Capability of position-independent code? capability of access data which is place far from the code? or capability of access (load/store/call) anywhere in 64 bits address space?

@kito-cheng
Copy link
Collaborator

Maciej W. Rozycki from WDC proposing FDPIC for RISC-V on
RISC-V SW Dev mailing list:
https://groups.google.com/a/groups.riscv.org/forum/#!msg/sw-dev/ZjYUJswknQ4/WYRRylTwAAAJ

@kito-cheng
Copy link
Collaborator

@lenary / @lowRISC mention their target scenario is nommu embedded linux in last RISC-V LLVM sync-up meeting.

@asb
Copy link
Collaborator

asb commented Mar 5, 2020

Hi Kito. To clarify, the main use case we're interested in at lowRISC is embedded microcontrollers (e.g. an RV32 core running Tock with loadable applications). Though if the same approach works well for embedded nommu Linux, that's great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants