Skip to content

Conversation

@kwitaszczyk
Copy link
Member

@kwitaszczyk kwitaszczyk commented Sep 4, 2025

Print capability registers in the same format as GDB does.

Example output:

      pcc  0xb09040003e77bc8effff00000365f214  0xffff00000365f214 [rxR,0xffff000003657910-0xffff00000365fce0]
      ddc  0xffffc000000100050000000000000000  0x0 [rwxRWE,0x0-0xffffffffffffffff]
       c0  0xdc1040006100a000ffffa000c00fa0a0  0xffffa000c00fa0a0 [rwRW,0xffffa000c00fa000-0xffffa000c00fa100]
       c1  0x9010400079b139a2ffff0000023839a2  0xffff0000023839a2 [rR,0xffff0000023839a2-0xffff0000023839b1]
       c2  0xdc1040003aff76faffff000003575e00  0xffff000003575e00 [rwRW,0xffff0000034edf00-0xffff000003575f00]
       c3  0xdc10400049f049b0ffff0000034049b0  0xffff0000034049b0 [rwRW,0xffff0000034049b0-0xffff0000034049f0]
       c4  0xdc1040006e286e27ffff000003216e27  0xffff000003216e27 [rwRW,0xffff000003216e27-0xffff000003216e28]
       c5  0xdc10400047000600ffffa000c0110600  0xffffa000c0110600 [rwRW,0xffffa000c0110600-0xffffa000c0110700]
       c6  0xdc1040006e286e27ffff000003216e27  0xffff000003216e27 [rwRW,0xffff000003216e27-0xffff000003216e28]
       c7  0xb090400010ee198effff00000235b37a  0xffff00000235b37a [rxR,0xffff000002331000-0xffff00000321d000]
       c8  0x00000000000000000000000000000006  0x6 [,0x0-0xffffffffffffffff] (invalid)
       c9  0x00000000000000000000000000000067  0x67 [,0x0-0xffffffffffffffff] (invalid)
      c10  0x00000000000000000000000000000000  0x0 [,0x0-0xffffffffffffffff] (invalid)
      c11  0x00000000000000000000000000000080  0x80 [,0x0-0xffffffffffffffff] (invalid)
      c12  0x00000000000000000000000000000070  0x70 [,0x0-0xffffffffffffffff] (invalid)
      c13  0x00000000000000000000000000000000  0x0 [,0x0-0xffffffffffffffff] (invalid)
      c14  0x00000000000000000000000100000000  0x100000000 [,0x0-0xffffffffffffffff] (invalid)
      c15  0x00000000000000000000000000000000  0x0 [,0x0-0xffffffffffffffff] (invalid)
      c16  0xb0904000be77bc8effff00000365f215  0xffff00000365f215 [rxR,0xffff000003657910-0xffff00000365fce0] (sentry)
      c17  0x00000000000000000000000000000000  0x0 [,0x0-0xffffffffffffffff] (invalid)
      c18  0xdc10400043008100ffff000002328100  0xffff000002328100 [rwRW,0xffff000002328100-0xffff000002328300]
      c19  0xdc1040004d400890ffff0000005d0890  0xffff0000005d0890 [rwRW,0xffff0000005d0890-0xffff0000005d0d40]
      c20  0x90104000672d66f4ffff0000024366f4  0xffff0000024366f4 [rR,0xffff0000024366f4-0xffff00000243672d]
      c21  0xdc10400049f049b0ffff0000034049b0  0xffff0000034049b0 [rwRW,0xffff0000034049b0-0xffff0000034049f0]
      c22  0xdc1040005ea0de70ffff00000309de70  0xffff00000309de70 [rwRW,0xffff00000309de70-0xffff00000309dea0]
      c23  0x9010400079b139a2ffff0000023839a2  0xffff0000023839a2 [rR,0xffff0000023839a2-0xffff0000023839b1]
      c24  0xdc1040004a1049f0ffff0000034049f0  0xffff0000034049f0 [rwRW,0xffff0000034049f0-0xffff000003404a10]
      c25  0xdc1040006100a000ffffa000c00fa000  0xffffa000c00fa000 [rwRW,0xffffa000c00fa000-0xffffa000c00fa100]
      c26  0x00000000000000000000000000000000  0x0 [,0x0-0xffffffffffffffff] (invalid)
      c27  0x90104000485ec857ffff00000245c857  0xffff00000245c857 [rR,0xffff00000245c857-0xffff00000245c85e]
      c28  0x90104000586f1861ffff0000023a1861  0xffff0000023a1861 [rR,0xffff0000023a1861-0xffff0000023a186f]
      c29  0xffffc0003007e007ffff0000005a2e00  0xffff0000005a2e00 [rwxRWE,0xffff00000059e000-0xffff0000005a3000]
      c30  0xbfffc000fc80fb90ffff00000087fc59  0xffff00000087fc59 [rxRWE,0xffff00000087fb90-0xffff00000087fc80] (sentry)
      csp  0xffffc00000073007ffff0000005a7ff0  0xffff0000005a7ff0 [rwxRWE,0xffff0000005a3000-0xffff0000005a8000]
   PSTATE  644000c5 -ZC- EL1h

target/arm/cpu.c Outdated
CAP_cc(get_perms)(capreg) & CAP_CC(PERM_STORE_CAP) ? "W" : "",
cap_get_base(capreg),
cap_get_top(capreg),
(!capreg->cr_tag || CAP_cc(is_cap_sealed)(capreg)) ? " (" : "",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could maybe add a local variable for this expression:

     bool have_attributes = (!capreg->cr_tag || CAP_cc(is_cap_sealed)(capreg));

It's also a shame you can't use some sort of string builder. If it is ok to make multiple calls to qemu_fprintf() I would suggest splitting up this logic using a bool comma (and perhaps not even needing the helper I suggested above), so something like:

     bool comma;

     ...
     comma = false;
#define PRINT_ATTR(name)  do { \
     qemu_fprintf(f, "%s%s", comma ? ", ", "("); \
     comma = true; \
} while (0)

     if (!capreg->cr_tag)
         PRINT_ATTR("invalid");
     if (CAP_cc(is_cap_sealed(capreg))
         PRINT_ATTR(cap_get_otype_unsigned(capreg) == CAP_CC(OTYPE_SENTRY) ?
             "sentry" : "sealed");
     if (comma)
         qemu_fprintf(f, ")");
#undef PRINT_ATTR
     qemu_fprintf(f, "\n");

Can maybe simplify printing of permissions similarly by splitting up into multiple calls, but those don't have the same duplicated logic that the attribute handling code has.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for encouraging to improve this!

I've changed this code not to use the CAP_cc() interface but the cap_*() API internal to QEMU.

Given that comma approach would need a conditional qemu_fprintf() call for ")" and that multiple qemu_fprintf() calls would depend on have_attributes, I've decided not to use the comma approach but use additional if statements instead.

Regarding the permissions, I think having a variable for permissions (perms) and CAP_* macros makes the qemu_fprintf() call simple enough.

What do you think?

Print capability registers in the same format as GDB does.

Discussed with:	@bsdjhb
qemu_fprintf(f, " (");
if (!capreg->cr_tag) {
qemu_fprintf(f, "invalid");
if (!cap_is_unsealed(capreg)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comma approach is to avoid duplicate checks like this. Note that you check !capreg->cr_tag twice and !cap_is_unsealed() three times currently. If we ever added an additional attribute you would have to add checks for that attribute in all these places as well along with its own check. For only two effective attributes that's probably ok, but it doesn't really scale well if we added more in the future. The comma approach is more about the readability/future maintainability as it only requires checking attribute condition once, and adding a new attribute in the future only requires adding code for that attribute without having to update the various other attribute handlers. It is also a bit unusual to conditionally add a trailing comma vs conditionally adding a leading comma (or pipe when doing bitmasks). You also still end up with a call to qemu_fprintf() for the closing ) character still. This is probably fine, but I would probably rework it if we ever had to change it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants