@@ -413,6 +413,114 @@ lldb::offset_t lldb_private::DumpDataExtractor(
413413 }
414414
415415 switch (item_format) {
416+ case eFormatCheriotCapability: {
417+ if (item_byte_size != 8 ) {
418+ s->Printf (" error: unsupported byte size (%" PRIu64
419+ " ) for cheriot capability format" ,
420+ (uint64_t )item_byte_size);
421+ return offset;
422+ }
423+
424+ // Extract the raw bits of the capability.
425+ uint64_t uval64 = DE.GetMaxU64 (&offset, item_byte_size);
426+ uint32_t addr = uval64;
427+ uint32_t meta = (uval64 >> 32 );
428+ unsigned B = meta & 0x1FF ;
429+ unsigned T = (meta >> 9 ) & 0x1FF ;
430+ unsigned E = (meta >> 18 ) & 0xF ;
431+ unsigned otype = (meta >> 22 ) & 0x7 ;
432+ std::bitset<6 > perms = (meta >> 25 ) & 0x3F ;
433+
434+ bool GL = perms[5 ];
435+ bool LD = false ;
436+ bool MC = false ;
437+ bool SD = false ;
438+ bool SL = false ;
439+ bool LM = false ;
440+ bool LG = false ;
441+ bool SR = false ;
442+ bool EX = false ;
443+ bool U0 = false ;
444+ bool SE = false ;
445+ bool US = false ;
446+
447+ // Cheriot capabilities pack 11 permissions into 6 bits,
448+ // so decoding is non-trivial.
449+ if (perms[4 ] && perms[3 ]) {
450+ LD = MC = SD = true ;
451+ SL = perms[2 ];
452+ LM = perms[1 ];
453+ LD = perms[0 ];
454+ } else if (perms[4 ] && !perms[3 ] && perms[2 ]) {
455+ LD = MC = true ;
456+ LM = perms[1 ];
457+ LG = perms[0 ];
458+ } else if (perms[4 ] && !perms[3 ] && !perms[2 ] && !perms[1 ] && !perms[0 ]) {
459+ SD = MC = true ;
460+ } else if (perms[4 ] && !perms[3 ] && !perms[2 ]) {
461+ LD = perms[1 ];
462+ SD = perms[0 ];
463+ } else if (!perms[4 ] && perms[3 ]) {
464+ EX = LD = MC = true ;
465+ SR = perms[2 ];
466+ LM = perms[1 ];
467+ LG = perms[0 ];
468+ } else {
469+ U0 = perms[2 ];
470+ SE = perms[1 ];
471+ US = perms[0 ];
472+ }
473+
474+ // Render the permissions to a string.
475+ std::string perm_string;
476+ perm_string += GL ? ' G' : ' -' ;
477+ perm_string += ' ' ;
478+ perm_string += LD ? ' R' : ' -' ;
479+ perm_string += SD ? ' W' : ' -' ;
480+ perm_string += MC ? ' c' : ' -' ;
481+ perm_string += LG ? ' g' : ' -' ;
482+ perm_string += LM ? ' m' : ' -' ;
483+ perm_string += SL ? ' l' : ' -' ;
484+ perm_string += ' ' ;
485+ perm_string += EX ? ' X' : ' -' ;
486+ perm_string += SR ? ' a' : ' -' ;
487+ perm_string += ' ' ;
488+ perm_string += SE ? ' S' : ' -' ;
489+ perm_string += US ? ' U' : ' -' ;
490+ perm_string += U0 ? ' 0' : ' -' ;
491+
492+ // Decode otype, and present with a semantic string if possible.
493+ if (otype != 0 && !EX)
494+ otype += 8 ;
495+ constexpr llvm::StringRef otypes[] = {
496+ " [unsealed]" ,
497+ " [IRQ inherit forward sentry]" ,
498+ " [IRQ disable forward sentry]" ,
499+ " [IRQ enable forward sentry]" ,
500+ " [IRQ disable return sentry]" ,
501+ " [IRQ enable return sentry]" ,
502+ };
503+ llvm::StringRef otype_str = (otype < sizeof (otypes)) ? otypes[otype] : " " ;
504+
505+ // Compute the base and top addresses for the bounds.
506+ unsigned e = (E != 15 ) ? E : 24 ;
507+ uint64_t a_top = addr >> (e + 9 );
508+ uint64_t a_mid = (addr >> e) & 0x1FF ;
509+ uint64_t a_hi = (a_mid < B) ? 1 : 0 ;
510+ uint64_t t_hi = (T < B) ? 1 : 0 ;
511+ uint64_t c_b = -a_hi;
512+ uint64_t c_t = t_hi - a_hi;
513+ uint64_t a_top_base = a_top + c_b;
514+ uint64_t a_top_top = a_top + c_t ;
515+ uint64_t base = ((a_top_base << 9 ) + B) << e;
516+ uint64_t top = ((a_top_top << 9 ) + T) << e;
517+ uint64_t len = top - base;
518+
519+ s->Printf (" 0x%08x (v:? 0x%08llx-0x%08llx l:0x%llx o:0x%x%s p: %s)" , addr,
520+ base, top, len, otype, otype_str.data (), perm_string.c_str ());
521+
522+ break ;
523+ }
416524 case eFormatBoolean:
417525 if (item_byte_size <= 8 )
418526 s->Printf (" %s" , DE.GetMaxU64Bitfield (&offset, item_byte_size,
0 commit comments