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:
committed by
waddlesplash
parent
4cb9408437
commit
502309ab5a
@@ -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) {}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user