public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Matthew Malcomson <matmal01@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] Update the dl_iterate_phdr implementation Date: Thu, 5 May 2022 12:09:44 +0000 (GMT) [thread overview] Message-ID: <20220505120944.1649F385624D@sourceware.org> (raw) https://gcc.gnu.org/g:524938a9bd4761ec4d782f932c2729f1b778375c commit 524938a9bd4761ec4d782f932c2729f1b778375c Author: Matthew Malcomson <matthew.malcomson@arm.com> Date: Thu Apr 28 09:53:59 2022 +0100 Update the dl_iterate_phdr implementation A hosted unwinder uses dl_iterate_phdr in order to find the location of exception handling information. The structure that this callback receives for Morello now contains a capability. A local internal structure needs to be updated to accomodate this. The existing code works for most cases. This is because the pointer to the exception handling frame section which is found during this iteration has been given metadata to span the entire executable by the kernel and libc. There is one exceptional case. When the load_base of the executable is zero (i.e. for a PDE or statically linked executable) it is not always possible for the kernel and libc to provide a capability with zero as the value and tight bounds spanning the relevant binary. For this case we derive a pointer to the frame using a found address and metadata from the dl_phdr_info->dlpi_phdr member, which is set up to span the executable. In order to improve robustness we also add some extra assertions that metadata is valid and spans relevant addresses. The placement of these assertions are taken from Morello-LLVM's libunwind in order to catch the same sort of problems that Morello LLVM has been adjusted to look for. Diff: --- libgcc/unwind-dw2-fde-dip.c | 58 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index 31fb1548005..9faf5e1dbc3 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -161,6 +161,21 @@ base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data) } } +#ifdef __CHERI_PURE_CAPABILITY__ +static int +valid_cheri_capability (void *x, uintptr_t *base, uintptr_t *top) +{ + int is_valid = __builtin_cheri_tag_get (x); + if (! is_valid) + return 0; + if (!base || !top) + return 1; + *base = __builtin_cheri_base_get (x); + *top = *base + __builtin_cheri_length_get (x); + return 1; +} +#endif + static int _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) { @@ -178,10 +193,13 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) struct object ob; _Unwind_Ptr pc_low = 0, pc_high = 0; - /* MORELLO TODO Update types here dlpi_addr should hold uintptr_t. */ struct ext_dl_phdr_info { +#ifdef __CHERI_PURE_CAPABILITY__ + uintptr_t dlpi_addr; +#else ElfW(Addr) dlpi_addr; +#endif const char *dlpi_name; const ElfW(Phdr) *dlpi_phdr; ElfW(Half) dlpi_phnum; @@ -195,6 +213,14 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) p_eh_frame_hdr = NULL; p_dynamic = NULL; +#ifdef __CHERI_PURE_CAPABILITY__ + /* Check on every object we iterate over that we are provided valid + capabilities by the libc. */ + gcc_assert (valid_cheri_capability (phdr, NULL, NULL)); + gcc_assert (load_base == 0 + || valid_cheri_capability (load_base, NULL, NULL)); +#endif + struct frame_hdr_cache_element *prev_cache_entry = NULL, *last_cache_entry = NULL; @@ -323,9 +349,32 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) if (!p_eh_frame_hdr) return 0; +#ifdef __CHERI_PURE_CAPABILITY__ + /* If we found the FDE we're looking for in a static and position dependent + object, then the `load_base` is zero and does not have associated bounds. + It does not have relevant bounds because restrictions on the cheri bounds + encoding mean that a zero valued capability can not have large bounds. In + this case the kernel and libc ensure that dlpi_phdr spans the executable + mapping (while its value is not interesting here). + + The dlpi_phdr pointer would have provided the provenance for the + `p_eh_frame_hdr` pointer. Hence in this case we want to use the *address* + stored in p_eh_frame_hdr->p_vaddr with the metadata of the capability + pointing to p_eh_frame_hdr. */ + if (load_base == 0) + hdr = __builtin_cheri_address_set (p_eh_frame_hdr, p_eh_frame_hdr->p_vaddr); + else +#endif /* Read .eh_frame_hdr header. */ hdr = (const struct unw_eh_frame_hdr *) __RELOC_POINTER (p_eh_frame_hdr->p_vaddr, load_base); + +#ifdef __CHERI_PURE_CAPABILITY__ + uintptr_t base, top; + gcc_assert (valid_cheri_capability (hdr, &base, &top)); + gcc_assert (base <= data->pc && top > data->pc); +#endif + if (hdr->version != 1) return 1; @@ -427,6 +476,13 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) } } +#ifdef __CHERI_PURE_CAPABILITY__ + /* Any encoding other than DW_EH_PE_pcrel would mean that our eh_frame + pointer would not be a valid capability. Here we're reading from eh_frame + and hence would need provenance. */ + gcc_assert (valid_cheri_capability (eh_frame, NULL, NULL)); +#endif + /* We have no sorted search table, so need to go the slow way. As soon as GLIBC will provide API so to notify that a library has been removed, we could cache this (and thus use search_object). */
reply other threads:[~2022-05-05 12:09 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220505120944.1649F385624D@sourceware.org \ --to=matmal01@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).