-
Notifications
You must be signed in to change notification settings - Fork 61
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
Morello: Stop using caprelocs for static binaries #2286
base: dev
Are you sure you want to change the base?
Conversation
bsdjhb
commented
Jan 8, 2025
- csu: Add support for ELF relocations to init caps for static binaries
- morello: Support R_MORELLO_RELATIVE relocations in static binaries
- rtld: Workaround Morello LLVM lld bug with local-caprelocs=elf
- Enable --local-caprelocs=elf for Morello
I have a request to fix the bug in Morello lld at https://git.morello-project.org/morello/llvm-project/-/merge_requests/307, but it may be a while before we can assume it is fixed. The workaround should let us work with existing lld for now and we can eventually drop it. |
#ifdef __CHERI_PURE_CAPABILITY__ | ||
#if defined(__aarch64__) | ||
__asm__ ( | ||
"adrp %0, __rela_dyn_start\n\t" |
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.
Can we put this in crt.h as some #define FOO(x) ({ __typeof__(x) *_p; __asm__ ("adrp %0, %c1; add %0, %0, :lo12:%c1" : "=C"(_p) : "i"(&x)); _p; })
? Hybrid can define it to just &x
.
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.
(Or crt1_c.c where CHERI_INIT_RELA lives)
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.
Then it can also be part of the second commit that adds Morello support specifically
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.
Oh, yeah, that might be fine, and certainly cleaner. PCREL_PTR() maybe?
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.
Sure, seems fine, name doesn't hugely matter, it's internal to csu
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.
After adding a description in the commit log I ended up going with RODATA_PTR() for the name.
This is to support the --local-caprelocs=elf flag to lld. When this is specified, an ELF relocation table is emitted. The table is identified by the hidden symbols __rela_dyn_start and __rela_dyn_end. If an architecture defines CHERI_INIT_RELA, then crt_init_globals() will look for this table. For each relocation found, an MD function provided by the architecture is called to handle the relocation. The function's signature is: elf_reloc(const Elf_Rela *, void * __capability data_cap, const void * __capability code_cap, Elf_Addr relocbase) In addition, an architecture must define a RODATA_PTR helper macro which accepts a symbol name as its sole argument and returns a readable pointer. For hybrid this can just use the normal address-of operator, but for purecap this has to avoid depending on an ELF relocation and instead derive the pointer from an existing capability such as PCC.
A shared header containing the implementation of elf_reloc is used to avoid duplicating code between hybrid and purecap. The init_cap_from_fragment function is copied directly from rtld (might be nice to move that function to a shared header).
Morello LLVM's lld always emits PLT-related .dynamic entries when ELF local caprelocs are used even if the PLT is empty. This confuses rtld which tries to treat the start of the binary as a GOT PLT. In particular, rtld itself ends up with an empty PLT and so rtld tries to write to its ELF header which crashes since the page is mapped read-only. Workaround this by ignoring DT_JMPREL and DT_PLTGOT entries whose value is 0. The PLT GOT and PLT relocation table can never be at the start of a valid binary.
9bb66ed
to
ee51273
Compare
This is done in bsd.{lib,prog}.mk instead of bsd.cpu.mk as it can't be turned off for the lib32 build otherwise.
ee51273
to
c9c2b04
Compare