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

Morello: Stop using caprelocs for static binaries #2286

Merged
merged 4 commits into from
Jan 30, 2025

Conversation

bsdjhb
Copy link
Collaborator

@bsdjhb 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

@bsdjhb bsdjhb requested a review from jrtc27 January 8, 2025 14:23
@bsdjhb
Copy link
Collaborator Author

bsdjhb commented Jan 8, 2025

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.

@bsdjhb bsdjhb force-pushed the morello_static_rela branch 2 times, most recently from ee51273 to c9c2b04 Compare January 9, 2025 20:02
@bsdjhb
Copy link
Collaborator Author

bsdjhb commented Jan 29, 2025

Ping?

lib/csu/aarch64/crt1_c.c Outdated Show resolved Hide resolved
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).
@bsdjhb bsdjhb force-pushed the morello_static_rela branch from c9c2b04 to d518dc2 Compare January 29, 2025 20:47
Morello LLVM's lld originally emitted 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.

NB: lld has been fixed in Morello LLVM comit
7e10a9b5b3919d10a5310cb9fe981e79f07b36d1.
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.
@bsdjhb bsdjhb force-pushed the morello_static_rela branch from d518dc2 to 86f30bf Compare January 30, 2025 00:57
@bsdjhb bsdjhb merged commit c7bb34a into CTSRD-CHERI:dev Jan 30, 2025
7 of 8 checks passed
@bsdjhb bsdjhb deleted the morello_static_rela branch January 30, 2025 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants