1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 17:58:12 +00:00

strace: Better support for bitflags, show unrecognized flags

This commit is contained in:
Ben Wiederhake 2021-11-07 13:02:16 +01:00 committed by Andreas Kling
parent d1eb604896
commit 491ed375fc

View file

@ -249,6 +249,59 @@ static T copy_from_process(const T* source)
return value;
}
struct BitflagOption {
int value;
StringView name;
};
#define BITFLAG(NAME) \
BitflagOption { NAME, #NAME }
struct BitflagBase {
int flagset;
// Derivatives must define 'options', like so:
// static constexpr auto options = { BITFLAG(O_CREAT), BITFLAG(O_DIRECTORY) };
};
namespace AK {
template<typename BitflagDerivative>
requires(IsBaseOf<BitflagBase, BitflagDerivative>) && requires { BitflagDerivative::options; }
struct Formatter<BitflagDerivative> : StandardFormatter {
Formatter() = default;
explicit Formatter(StandardFormatter formatter)
: StandardFormatter(formatter)
{
}
void format(FormatBuilder& format_builder, BitflagDerivative const& value)
{
bool had_any_output = false;
int remaining = value.flagset;
for (BitflagOption const& option : BitflagDerivative::options) {
if ((remaining & option.value) != option.value)
continue;
remaining &= ~option.value;
if (had_any_output)
format_builder.put_literal(" | ");
format_builder.put_literal(option.name);
had_any_output = true;
}
if (remaining != 0) {
// No more BitflagOptions are available. Any remaining flags are unrecognized.
if (had_any_output)
format_builder.put_literal(" | ");
format_builder.builder().appendff("0x{:x} (?)", static_cast<unsigned>(remaining));
had_any_output = true;
}
if (!had_any_output)
format_builder.put_literal("0");
}
};
}
struct PointerArgument {
const void* value;
};
@ -377,6 +430,13 @@ static void format_exit(FormattedSyscallBuilder& builder, int status)
builder.add_argument(status);
}
struct OpenOptions : BitflagBase {
static constexpr auto options = {
BITFLAG(O_RDWR), BITFLAG(O_RDONLY), BITFLAG(O_WRONLY), BITFLAG(O_APPEND), BITFLAG(O_CREAT)
// TODO: etc...
};
};
static void format_open(FormattedSyscallBuilder& builder, Syscall::SC_open_params* params_p)
{
auto params = copy_from_process(params_p);
@ -388,24 +448,7 @@ static void format_open(FormattedSyscallBuilder& builder, Syscall::SC_open_param
builder.add_string_argument(params.path);
Vector<StringView> active_flags;
if (params.options & O_RDWR)
active_flags.append("O_RDWR");
else if (params.options & O_RDONLY)
active_flags.append("O_RDONLY");
else if (params.options & O_WRONLY)
active_flags.append("O_WRONLY");
if (params.options & O_APPEND)
active_flags.append("O_APPEND");
if (params.options & O_CREAT)
active_flags.append("O_CREAT");
// TODO: etc...
// TODO: add to FormattedSyscallBuilder
StringBuilder sbuilder;
sbuilder.join(" | ", active_flags);
builder.add_argument(sbuilder.to_string());
builder.add_argument(OpenOptions { params.options });
if (params.options & O_CREAT)
builder.add_argument("{:04o}", params.mode);