Skip to content

Commit 3072315

Browse files
committed
[CHERIoT] Add a "cheriot capability" memory/register formatter to LLDB.
1 parent fd09919 commit 3072315

File tree

4 files changed

+115
-4
lines changed

4 files changed

+115
-4
lines changed

lldb/include/lldb/lldb-enumerations.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,12 @@ enum Format {
195195
///< character arrays that can contain non printable
196196
///< characters
197197
eFormatAddressInfo, ///< Describe what an address points to (func + offset
198-
///< with file/line, symbol + offset, data, etc)
199-
eFormatHexFloat, ///< ISO C99 hex float string
200-
eFormatInstruction, ///< Disassemble an opcode
201-
eFormatVoid, ///< Do not print this
198+
///< with file/line, symbol + offset, data, etc)
199+
eFormatHexFloat, ///< ISO C99 hex float string
200+
eFormatInstruction, ///< Disassemble an opcode
201+
eFormatVoid, ///< Do not print this
202202
eFormatUnicode8,
203+
eFormatCheriotCapability,
203204
kNumFormats
204205
};
205206

lldb/source/Commands/CommandObjectMemory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,7 @@ class CommandObjectMemoryWrite : public CommandObjectParsed {
13541354
case eFormatAddressInfo:
13551355
case eFormatHexFloat:
13561356
case eFormatInstruction:
1357+
case eFormatCheriotCapability:
13571358
case eFormatVoid:
13581359
result.AppendError("unsupported format for writing memory");
13591360
return;

lldb/source/Core/DumpDataExtractor.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: cheriot capabilities must be 8 bytes");
419+
return offset;
420+
}
421+
422+
uint64_t uval64 = DE.GetMaxU64(&offset, item_byte_size);
423+
uint32_t addr = uval64;
424+
uint32_t meta = (uval64 >> 32);
425+
unsigned B = meta & 0x1FF;
426+
unsigned T = (meta >> 9) & 0x1FF;
427+
unsigned E = (meta >> 18) & 0xF;
428+
unsigned otype = (meta >> 22) & 0x7;
429+
unsigned perms = (meta >> 25) & 0x3F;
430+
unsigned R = (meta >> 31) & 1;
431+
432+
bool LD = false;
433+
bool MC = false;
434+
bool SD = false;
435+
bool SL = false;
436+
bool LM = false;
437+
bool LG = false;
438+
bool SR = false;
439+
bool EX = false;
440+
bool U0 = false;
441+
bool SE = false;
442+
bool US = false;
443+
444+
bool p0 = perms & 0b1;
445+
bool p1 = perms & 0b10;
446+
bool p2 = perms & 0b100;
447+
bool p3 = perms & 0b1000;
448+
bool p4 = perms & 0b10000;
449+
bool GL = perms & 0b100000;
450+
451+
if (p4 && p3) {
452+
LD = MC = SD = true;
453+
SL = p2;
454+
LM = p1;
455+
LD = p0;
456+
} else if (p4 && !p3 && p2) {
457+
LD = MC = true;
458+
LM = p1;
459+
LG = p0;
460+
} else if (p4 && !p3 && !p2 && !p1 && !p0) {
461+
SD = MC = true;
462+
} else if (p4 && !p3 && !p2) {
463+
LD = p1;
464+
SD = p0;
465+
} else if (!p4 && p3) {
466+
EX = LD = MC = true;
467+
SR = p2;
468+
LM = p1;
469+
LG = p0;
470+
} else {
471+
U0 = p2;
472+
SE = p1;
473+
US = p0;
474+
}
475+
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+
if (otype != 0 && !EX)
494+
otype += 8;
495+
496+
constexpr const char *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+
unsigned e = (E != 15) ? E : 24;
506+
uint64_t a_top = addr >> (e + 9);
507+
uint64_t a_mid = (addr >> e) & 0x1FF;
508+
uint64_t a_hi = (a_mid < B) ? 1 : 0;
509+
uint64_t t_hi = (T < B) ? 1 : 0;
510+
uint64_t c_b = -a_hi;
511+
uint64_t c_t = t_hi - a_hi;
512+
uint64_t a_top_base = a_top + c_b;
513+
uint64_t a_top_top = a_top + c_t;
514+
uint64_t base = ((a_top_base << 9) + B) << e;
515+
uint64_t top = ((a_top_top << 9) + T) << e;
516+
517+
s->Printf(
518+
"0x%08x {0x%08llx-0x%08llx l:0x%09llx} p=[%s] otype=[%d%s] R=%d",
519+
addr, base, top, (top - base), perm_string.c_str(), otype,
520+
((otype < sizeof(otypes)) ? otypes[otype] : ""), R);
521+
522+
break;
523+
}
416524
case eFormatBoolean:
417525
if (item_byte_size <= 8)
418526
s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size,

lldb/source/DataFormatters/FormatManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static constexpr FormatInfo g_format_infos[] = {
7272
{eFormatInstruction, 'i', "instruction"},
7373
{eFormatVoid, 'v', "void"},
7474
{eFormatUnicode8, 'u', "unicode8"},
75+
{eFormatCheriotCapability, '\0', "cheriot capability"},
7576
};
7677

7778
static_assert((sizeof(g_format_infos) / sizeof(g_format_infos[0])) ==

0 commit comments

Comments
 (0)