strace: Introduce FlagsTypeHandler, and use it for O_* modes.

Change-Id: I1569084a71c32834c0ff3d8dc71ef3de9d5a817d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6263
Reviewed-by: Adrien Destugues <[email protected]>
Tested-by: Automation <[email protected]>
This commit is contained in:
Augustin Cavalier
2023-03-28 15:27:05 +00:00
committed by waddlesplash
parent 4cb9408437
commit 502309ab5a
3 changed files with 113 additions and 8 deletions
+49
View File
@@ -10,6 +10,7 @@
#include "TypeHandler.h"
#include <string.h>
#include <String.h>
#include "Context.h"
#include "MemoryReader.h"
@@ -182,6 +183,54 @@ EnumTypeHandler::RenderValue(Context &context, unsigned int value) const
return context.FormatUnsigned(value);
}
FlagsTypeHandler::FlagsTypeHandler(const FlagsList &m) : fList(m) {}
string
FlagsTypeHandler::GetParameterValue(Context &context, Parameter *,
const void *address)
{
return RenderValue(context, get_value<unsigned int>(address));
}
string
FlagsTypeHandler::GetReturnValue(Context &context, uint64 value)
{
return RenderValue(context, value);
}
string
FlagsTypeHandler::RenderValue(Context &context, unsigned int value) const
{
if (context.GetContents(Context::ENUMERATIONS)) {
// Enumerate the list in reverse. That way, any later values which use
// the same bits as earlier values will be processed correctly.
string rendered;
FlagsList::const_reverse_iterator i = fList.rbegin();
for (; i != fList.rend(); i++) {
if ((value & i->value) != i->value)
continue;
if (!rendered.empty())
rendered.insert(0, " | ");
rendered.insert(0, i->name);
value &= ~(i->value);
}
if (value != 0) {
if (!rendered.empty())
rendered += " | ";
char hex[20];
snprintf(hex, 20, "%x", value);
rendered += hex;
}
if (rendered.empty())
rendered = "0";
return rendered;
}
return context.FormatUnsigned(value);
}
TypeHandlerSelector::TypeHandlerSelector(const SelectMap &m, int sibling,
TypeHandler *def)
: fMap(m), fSibling(sibling), fDefault(def) {}
+21 -1
View File
@@ -9,8 +9,9 @@
#ifndef STRACE_TYPE_HANDLER_H
#define STRACE_TYPE_HANDLER_H
#include <string>
#include <list>
#include <map>
#include <string>
#include <arch_config.h>
#include <SupportDefs.h>
@@ -49,6 +50,25 @@ private:
const EnumMap &fMap;
};
class FlagsTypeHandler : public TypeHandler {
public:
struct FlagInfo {
unsigned int value;
const char* name;
};
typedef std::list<FlagInfo> FlagsList;
FlagsTypeHandler(const FlagsList &);
string GetParameterValue(Context &c, Parameter *, const void *);
string GetReturnValue(Context &, uint64 value);
private:
string RenderValue(Context &, unsigned int value) const;
const FlagsList &fList;
};
// currently limited to select ints
class TypeHandlerSelector : public TypeHandler {
public:
+43 -7
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2022, Haiku Inc. All rights reserved.
* Copyright 2022-2023, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -14,6 +14,34 @@
#include "TypeHandler.h"
#define FLAG_INFO_ENTRY(name) \
{ name, #name }
static const FlagsTypeHandler::FlagInfo kOpenFlagInfos[] = {
FLAG_INFO_ENTRY(O_WRONLY),
FLAG_INFO_ENTRY(O_RDWR),
FLAG_INFO_ENTRY(O_EXCL),
FLAG_INFO_ENTRY(O_CREAT),
FLAG_INFO_ENTRY(O_TRUNC),
FLAG_INFO_ENTRY(O_NOCTTY),
FLAG_INFO_ENTRY(O_NOTRAVERSE),
FLAG_INFO_ENTRY(O_CLOEXEC),
FLAG_INFO_ENTRY(O_NONBLOCK),
FLAG_INFO_ENTRY(O_APPEND),
FLAG_INFO_ENTRY(O_SYNC),
FLAG_INFO_ENTRY(O_RSYNC),
FLAG_INFO_ENTRY(O_DSYNC),
FLAG_INFO_ENTRY(O_NOFOLLOW),
FLAG_INFO_ENTRY(O_DIRECT),
FLAG_INFO_ENTRY(O_DIRECTORY),
{ 0, NULL }
};
struct fcntl_info {
unsigned int index;
const char *name;
@@ -31,31 +59,39 @@ static const fcntl_info kFcntls[] = {
FCNTL_INFO_ENTRY(F_GETFD),
FCNTL_INFO_ENTRY_TYPE(F_SETFD, int),
FCNTL_INFO_ENTRY(F_GETFL),
FCNTL_INFO_ENTRY_TYPE(F_SETFL, int),
FCNTL_INFO_ENTRY(F_SETFL),
FCNTL_INFO_ENTRY_TYPE(F_GETLK, struct flock*),
FCNTL_INFO_ENTRY_TYPE(F_SETLK, struct flock*),
FCNTL_INFO_ENTRY_TYPE(F_SETLKW, struct flock*),
{ 0, NULL, NULL }
};
static FlagsTypeHandler::FlagsList kOpenFlags;
static EnumTypeHandler::EnumMap kFcntlNames;
static TypeHandlerSelector::SelectMap kFcntlTypeHandlers;
void
patch_fcntl()
{
for (int i = 0; kOpenFlagInfos[i].name != NULL; i++) {
kOpenFlags.push_back(kOpenFlagInfos[i]);
}
for (int i = 0; kFcntls[i].name != NULL; i++) {
kFcntlNames[kFcntls[i].index] = kFcntls[i].name;
if (kFcntls[i].handler != NULL)
kFcntlTypeHandlers[kFcntls[i].index] = kFcntls[i].handler;
}
Syscall *fcntl = get_syscall("_kern_fcntl");
kFcntlTypeHandlers[F_SETFL] = new FlagsTypeHandler(kOpenFlags);
fcntl->GetParameter("op")->SetHandler(
new EnumTypeHandler(kFcntlNames));
Syscall *open = get_syscall("_kern_open");
open->GetParameter("openMode")->SetHandler(new FlagsTypeHandler(kOpenFlags));
Syscall *fcntl = get_syscall("_kern_fcntl");
fcntl->GetParameter("op")->SetHandler(new EnumTypeHandler(kFcntlNames));
fcntl->GetParameter("argument")->SetHandler(
new TypeHandlerSelector(kFcntlTypeHandlers,
1, TypeHandlerFactory<void *>::Create()));
new TypeHandlerSelector(kFcntlTypeHandlers,
1, TypeHandlerFactory<void *>::Create()));
}