From 885b0e5bcdbb871217dea6501ab611230ad56cc6 Mon Sep 17 00:00:00 2001 From: Dapeng Gao Date: Wed, 8 May 2024 17:50:03 +0100 Subject: [PATCH] c18n: Improve tracing output, introduce struct utrace_c18n --- lib/libsysdecode/utrace.c | 38 +++++++++++++++++++++++++--------- libexec/rtld-elf/rtld_c18n.c | 14 ++++++++----- libexec/rtld-elf/rtld_utrace.h | 34 +++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/lib/libsysdecode/utrace.c b/lib/libsysdecode/utrace.c index 61404263aea3..c490ac476c70 100644 --- a/lib/libsysdecode/utrace.c +++ b/lib/libsysdecode/utrace.c @@ -87,6 +87,29 @@ print_utrace_mrs(FILE *fp, void *p) } return (1); } + +static int +print_utrace_c18n(FILE *fp, void *p) +{ + struct utrace_c18n *ut = p; + + switch (ut->event) { + case UTRACE_COMPARTMENT_ENTER: + fprintf(fp, "RTLD: c18n: %s -> %s at [%zu] %s (%02hhx)", + ut->caller, ut->callee, ut->symnum, ut->symbol, ut->fsig); + break; + case UTRACE_COMPARTMENT_LEAVE: + fprintf(fp, "RTLD: c18n: %s <- %s at [%zu] %s (%02hhx)", + ut->caller, ut->callee, ut->symnum, ut->symbol, ut->fsig); + break; + default: + return (0); + } + fprintf(fp, "\nnsp = %#p\nosp = %#p, previous = %#p\n" + "fp = %#p, pc = %#p", ut->sp, ut->osp, ut->previous, + ut->fp, ut->pc); + return (1); +} #endif #ifdef __LP64__ @@ -200,16 +223,6 @@ print_utrace_rtld(FILE *fp, void *p) case UTRACE_RTLD_ERROR: fprintf(fp, "RTLD: error: %s\n", ut->name); break; - case UTRACE_COMPARTMENT_ENTER: - fprintf(fp, - "RTLD: c18n: enter %s from %s at [%zu] %s (%p)", - ut->callee, ut->caller, ut->mapsize, ut->symbol, ut->handle); - break; - case UTRACE_COMPARTMENT_LEAVE: - fprintf(fp, - "RTLD: c18n: leave %s to %s at [%zu] %s", - ut->callee, ut->caller, ut->mapsize, ut->symbol); - break; default: return (0); @@ -279,10 +292,15 @@ sysdecode_utrace(FILE *fp, void *p, size_t len) static const char rtld_utrace_sig[RTLD_UTRACE_SIG_SZ] = RTLD_UTRACE_SIG; #ifdef __CHERI_PURE_CAPABILITY__ static const char mrs_utrace_sig[MRS_UTRACE_SIG_SZ] = MRS_UTRACE_SIG; + static const char c18n_utrace_sig[C18N_UTRACE_SIG_SZ] = C18N_UTRACE_SIG; if (len == sizeof(struct utrace_mrs) && bcmp(p, mrs_utrace_sig, sizeof(mrs_utrace_sig)) == 0) return (print_utrace_mrs(fp, p)); + + if (len == sizeof(struct utrace_c18n) && bcmp(p, c18n_utrace_sig, + sizeof(c18n_utrace_sig)) == 0) + return (print_utrace_c18n(fp, p)); #endif if (len == sizeof(struct utrace_rtld) && bcmp(p, rtld_utrace_sig, diff --git a/libexec/rtld-elf/rtld_c18n.c b/libexec/rtld-elf/rtld_c18n.c index 3b377070b90c..7b441a4798dd 100644 --- a/libexec/rtld-elf/rtld_c18n.c +++ b/libexec/rtld-elf/rtld_c18n.c @@ -1136,8 +1136,7 @@ tramp_hook_impl(int event, const struct tramp_header *hdr, const char *sym; const char *callee; const char *caller; - struct utrace_rtld ut; - static const char rtld_utrace_sig[RTLD_UTRACE_SIG_SZ] = RTLD_UTRACE_SIG; + struct utrace_c18n ut; if (ld_compartment_utrace != NULL) { if (hdr->symnum == 0) @@ -1147,10 +1146,15 @@ tramp_hook_impl(int event, const struct tramp_header *hdr, callee = comparts.data[index_to_cid(tf->callee)].name; caller = comparts.data[index_to_cid(tf->caller)].name; - memcpy(ut.sig, rtld_utrace_sig, sizeof(ut.sig)); + memcpy(ut.sig, C18N_UTRACE_SIG, C18N_UTRACE_SIG_SZ); ut.event = event; - ut.handle = hdr->target; - ut.mapsize = hdr->symnum; + ut.symnum = hdr->symnum; + ut.fp = tf->fp; + ut.pc = tf->pc; + ut.sp = tf->sp; + ut.osp = tf->osp; + ut.previous = tf->previous; + memcpy(&ut.fsig, &hdr->sig, sizeof(ut.fsig)); strlcpy(ut.symbol, sym, sizeof(ut.symbol)); strlcpy(ut.callee, callee, sizeof(ut.callee)); strlcpy(ut.caller, caller, sizeof(ut.caller)); diff --git a/libexec/rtld-elf/rtld_utrace.h b/libexec/rtld-elf/rtld_utrace.h index d81280c33f0a..8c0f87d9b1ff 100644 --- a/libexec/rtld-elf/rtld_utrace.h +++ b/libexec/rtld-elf/rtld_utrace.h @@ -44,8 +44,6 @@ #define UTRACE_DLSYM_START 11 #define UTRACE_DLSYM_STOP 12 #define UTRACE_RTLD_ERROR 13 -#define UTRACE_COMPARTMENT_ENTER 14 -#define UTRACE_COMPARTMENT_LEAVE 15 #define RTLD_UTRACE_SIG_SZ 4 #define RTLD_UTRACE_SIG "RTLD" @@ -57,14 +55,30 @@ struct utrace_rtld { void *mapbase; /* Used for 'parent' and 'init/fini' */ size_t mapsize; int refcnt; /* Used for 'mode' */ - union { - char name[MAXPATHLEN]; - struct { - char symbol[MAXPATHLEN / 2]; - char callee[MAXPATHLEN / 4]; - char caller[MAXPATHLEN / 4]; - }; - }; + char name[MAXPATHLEN]; }; +#ifdef __CHERI_PURE_CAPABILITY__ +#define UTRACE_COMPARTMENT_ENTER 1 +#define UTRACE_COMPARTMENT_LEAVE 2 + +#define C18N_UTRACE_SIG_SZ 4 +#define C18N_UTRACE_SIG "C18N" + +struct utrace_c18n { + char sig[C18N_UTRACE_SIG_SZ]; + int event; + size_t symnum; + void *fp; + void *pc; + void *sp; + void *osp; + void *previous; + uint8_t fsig; + char symbol[256]; + char callee[128]; + char caller[128]; +}; +#endif + #endif