@@ -413,6 +413,115 @@ 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+ unsigned R = (meta >> 31 ) & 1 ;
434+
435+ bool GL = perms[5 ];
436+ bool LD = false ;
437+ bool MC = false ;
438+ bool SD = false ;
439+ bool SL = false ;
440+ bool LM = false ;
441+ bool LG = false ;
442+ bool SR = false ;
443+ bool EX = false ;
444+ bool U0 = false ;
445+ bool SE = false ;
446+ bool US = false ;
447+
448+ // Cheriot capabilities pack 11 permissions into 6 bits,
449+ // so decoding is non-trivial.
450+ if (perms[4 ] && perms[3 ]) {
451+ LD = MC = SD = true ;
452+ SL = perms[2 ];
453+ LM = perms[1 ];
454+ LD = perms[0 ];
455+ } else if (perms[4 ] && !perms[3 ] && perms[2 ]) {
456+ LD = MC = true ;
457+ LM = perms[1 ];
458+ LG = perms[0 ];
459+ } else if (perms[4 ] && !perms[3 ] && !perms[2 ] && !perms[1 ] && !perms[0 ]) {
460+ SD = MC = true ;
461+ } else if (perms[4 ] && !perms[3 ] && !perms[2 ]) {
462+ LD = perms[1 ];
463+ SD = perms[0 ];
464+ } else if (!perms[4 ] && perms[3 ]) {
465+ EX = LD = MC = true ;
466+ SR = perms[2 ];
467+ LM = perms[1 ];
468+ LG = perms[0 ];
469+ } else {
470+ U0 = perms[2 ];
471+ SE = perms[1 ];
472+ US = perms[0 ];
473+ }
474+
475+ // Render the permissions to a string.
476+ std::string perm_string;
477+ perm_string += GL ? ' G' : ' -' ;
478+ perm_string += ' ' ;
479+ perm_string += LD ? ' R' : ' -' ;
480+ perm_string += SD ? ' W' : ' -' ;
481+ perm_string += MC ? ' c' : ' -' ;
482+ perm_string += LG ? ' g' : ' -' ;
483+ perm_string += LM ? ' m' : ' -' ;
484+ perm_string += SL ? ' l' : ' -' ;
485+ perm_string += ' ' ;
486+ perm_string += EX ? ' X' : ' -' ;
487+ perm_string += SR ? ' a' : ' -' ;
488+ perm_string += ' ' ;
489+ perm_string += SE ? ' S' : ' -' ;
490+ perm_string += US ? ' U' : ' -' ;
491+ perm_string += U0 ? ' 0' : ' -' ;
492+
493+ // Decode otype, and present with a semantic string if possible.
494+ if (otype != 0 && !EX)
495+ otype += 8 ;
496+ llvm::StringRef otypes[] = {
497+ " , unsealed" ,
498+ " , IRQ inherit forward sentry" ,
499+ " , IRQ disable forward sentry" ,
500+ " , IRQ enable forward sentry" ,
501+ " , IRQ disable return sentry" ,
502+ " , IRQ enable return sentry" ,
503+ };
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+
518+ s->Printf (
519+ " 0x%08x {0x%08llx-0x%08llx l:0x%09llx} p=[%s] otype=[%d%s] R=%d" ,
520+ addr, base, top, (top - base), perm_string.c_str (), otype,
521+ ((otype < sizeof (otypes)) ? otypes[otype].data () : " " ), R);
522+
523+ break ;
524+ }
416525 case eFormatBoolean:
417526 if (item_byte_size <= 8 )
418527 s->Printf (" %s" , DE.GetMaxU64Bitfield (&offset, item_byte_size,
0 commit comments