Patch by Hugo Santos. In his own words:

- moved the network type handling into NetworkTypes.cpp.
- list the known socket options and some of their types (mostly only handling
  integers right now).
- in order to look at the socket options values, i added specialized pointers
  to look at the value pointed by int *, unsigned int *, long *,
  unsigned long *, long long * and unsigned long long *. This proved helpful
  in other situations, such as looking at the msgCode of read_port_etc and
  other similiar cases.
- i added a new option to -d, "pointer_values" to enable/disable this "look
  at integer pointer values" behavior.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20429 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-03-26 22:27:15 +00:00
parent 2f142f6139
commit a71744ba3a
8 changed files with 509 additions and 242 deletions

View File

@ -12,7 +12,6 @@
#include <stdio.h>
#include <string.h>
string
Context::FormatSigned(int64 value, int bytes) const
{
@ -42,7 +41,7 @@ Context::FormatSigned(int64 value, int bytes) const
tmp[--offset] = 'x';
tmp[--offset] = '0';
}
return tmp + offset;
}
@ -61,3 +60,11 @@ Context::FormatFlags(uint64 value) const
snprintf(tmp, sizeof(tmp), "0x%llx", value);
return tmp;
}
string
Context::FormatPointer(const void *address) const
{
char buffer[32];
sprintf(buffer, "%p", address);
return buffer;
}

View File

@ -18,6 +18,7 @@ public:
ENUMERATIONS = 1 << 1,
SIMPLE_STRUCTS = 1 << 2,
COMPLEX_STRUCTS = 1 << 3,
POINTER_VALUES = 1 << 4,
ALL = 0xffffffff
};
@ -41,6 +42,8 @@ public:
string FormatUnsigned(uint64 value) const;
string FormatFlags(uint64 value) const;
string FormatPointer(const void *address) const;
private:
Syscall *fSyscall;
char *fData;

View File

@ -9,7 +9,8 @@ UsePrivateHeaders net ;
SubDirHdrs $(TARGET_COMMON_DEBUG_LOCATE_TARGET) ;
local straceSources =
Context.cpp ioctl.cpp MemoryReader.cpp strace.cpp TypeHandler.cpp
Context.cpp ioctl.cpp MemoryReader.cpp NetworkTypes.cpp
strace.cpp TypeHandler.cpp
;
# Our compiler badly chokes when compiling the generated file. So will

View File

@ -0,0 +1,412 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Hugo Santos <hugosantos@gmail.com>
* Ingo Weinhold <bonefish@cs.tu-berlin.de>
*/
// headers required for network structures
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net_stack_driver.h>
#include "Context.h"
#include "MemoryReader.h"
#include "TypeHandler.h"
template<typename Type>
static bool
obtain_pointer_data(Context &context, Type *data, void *address, uint32 what)
{
if (address == NULL || !context.GetContents(what))
return false;
int32 bytesRead;
status_t err = context.Reader().Read(address, data, sizeof(Type), bytesRead);
if (err != B_OK || bytesRead < (int32)sizeof(Type))
return false;
return true;
}
static string
format_number(uint32 value)
{
char tmp[32];
snprintf(tmp, sizeof(tmp), "%u", (unsigned int)value);
return tmp;
}
static string
read_fdset(Context &context, void *data)
{
// default FD_SETSIZE is 1024
unsigned long tmp[1024 / (sizeof(unsigned long) * 8)];
int32 bytesRead;
status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead);
if (err != B_OK)
return context.FormatPointer(data);
/* implicitly align to unsigned long lower boundary */
int count = bytesRead / sizeof(unsigned long);
int added = 0;
string r;
r.reserve(16);
r = "[";
for (int i = 0; i < count && added < 8; i++) {
for (int j = 0;
j < (int)(sizeof(unsigned long) * 8) && added < 8; j++) {
if (tmp[i] & (1 << j)) {
if (added > 0)
r += " ";
unsigned int fd = i * sizeof(unsigned long) * 8 + j;
r += format_number(fd);
added++;
}
}
}
if (added >= 8)
r += " ...";
r += "]";
return r;
}
template<>
string
TypeHandlerImpl<struct fd_set *>::GetParameterValue(Context &context, Parameter *,
const void *address)
{
void *data = *(void **)address;
if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS))
return read_fdset(context, data);
return context.FormatPointer(data);
}
template<>
string
TypeHandlerImpl<struct fd_set *>::GetReturnValue(Context &context, uint64 value)
{
return context.FormatPointer((void *)value);
}
template<typename Type>
static string
format_pointer_value(Context &context, void *address)
{
Type data;
if (obtain_pointer_data(context, &data, address,Context::COMPLEX_STRUCTS))
return "{" + format_pointer(context, &data) + "}";
return context.FormatPointer(address);
}
static string
get_ipv4_address(struct in_addr *addr)
{
char tmp[32];
snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u",
(unsigned int)(htonl(addr->s_addr) >> 24) & 0xff,
(unsigned int)(htonl(addr->s_addr) >> 16) & 0xff,
(unsigned int)(htonl(addr->s_addr) >> 8) & 0xff,
(unsigned int)(htonl(addr->s_addr) >> 0) & 0xff);
return tmp;
}
static string
format_socket_family(Context &context, int family)
{
if (context.GetContents(Context::ENUMERATIONS)) {
switch (family) {
case AF_INET:
return "AF_INET";
}
}
return "family = " + context.FormatSigned(family);
}
static string
format_socket_type(Context &context, int type)
{
if (context.GetContents(Context::ENUMERATIONS)) {
switch (type) {
case SOCK_RAW:
return "SOCK_RAW";
case SOCK_DGRAM:
return "SOCK_DGRAM";
case SOCK_STREAM:
return "SOCK_STREAM";
}
}
return "type = " + context.FormatSigned(type);
}
static string
format_socket_protocol(Context &context, int protocol)
{
if (context.GetContents(Context::ENUMERATIONS)) {
switch (protocol) {
case IPPROTO_IP:
return "IPPROTO_IP";
case IPPROTO_RAW:
return "IPPROTO_RAW";
case IPPROTO_ICMP:
return "IPPROTO_ICMP";
case IPPROTO_UDP:
return "IPPROTO_UDP";
case IPPROTO_TCP:
return "IPPROTO_TCP";
}
}
return "protocol = " + context.FormatSigned(protocol);
}
static string
format_pointer(Context &context, sockaddr *saddr)
{
string r;
struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
r = format_socket_family(context, saddr->sa_family) + ", ";
switch (saddr->sa_family) {
case AF_INET:
r += get_ipv4_address(&sin->sin_addr);
r += "/";
r += format_number(ntohs(sin->sin_port));
break;
default:
r += "...";
break;
}
return r;
}
static string
format_pointer(Context &context, sockaddr_args *args)
{
string r;
r = "addr = " + format_pointer_value<struct sockaddr>(context, args->address);
r += ", len = " + context.FormatUnsigned(args->address_length);
return r;
}
static string
format_pointer(Context &context, transfer_args *args)
{
string r;
r = "data = " + context.FormatPointer(args->data);
r += ", len = " + context.FormatUnsigned(args->data_length);
r += ", flags = " + context.FormatFlags(args->flags);
r += ", addr = " + format_pointer_value<struct sockaddr>(context, args->address);
return r;
}
struct socket_option_info {
int level;
int option;
const char *name;
TypeHandler *handler;
int length;
};
#define SOCKET_OPTION_INFO_ENTRY(level, option) \
{ level, option, #option, NULL, 0 }
#define SOCKET_OPTION_INFO_ENTRY_TYPE(level, option, type) \
{ level, option, #option, TypeHandlerFactory<type *>::Create(), sizeof(type) }
static const socket_option_info kSocketOptions[] = {
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_ACCEPTCONN),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_BROADCAST, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_DEBUG, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_DONTROUTE, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_KEEPALIVE, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_OOBINLINE, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_REUSEADDR, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_REUSEPORT, int32),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_USELOOPBACK, int32),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_LINGER),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_SNDBUF, uint32),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_SNDLOWAT),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_SNDTIMEO),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_RCVBUF, uint32),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_RCVLOWAT),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_RCVTIMEO),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_ERROR),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_TYPE),
SOCKET_OPTION_INFO_ENTRY_TYPE(SOL_SOCKET, SO_NONBLOCK, int32),
SOCKET_OPTION_INFO_ENTRY(SOL_SOCKET, SO_BINDTODEVICE),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_OPTIONS),
SOCKET_OPTION_INFO_ENTRY_TYPE(IPPROTO_IP, IP_HDRINCL, int),
SOCKET_OPTION_INFO_ENTRY_TYPE(IPPROTO_IP, IP_TOS, int),
SOCKET_OPTION_INFO_ENTRY_TYPE(IPPROTO_IP, IP_TTL, int),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_RECVOPTS),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_RECVRETOPTS),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_RECVDSTADDR),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_RETOPTS),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_MULTICAST_IF),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_MULTICAST_TTL),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_MULTICAST_LOOP),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_ADD_MEMBERSHIP),
SOCKET_OPTION_INFO_ENTRY(IPPROTO_IP, IP_DROP_MEMBERSHIP),
{ -1, -1, NULL, NULL }
};
class SocketOptionsMap {
public:
typedef map<pair<int, int>, const socket_option_info *> ThisMap;
SocketOptionsMap()
{
for (int i = 0; kSocketOptions[i].name != NULL; i++) {
fMap.insert(make_pair(
make_pair(kSocketOptions[i].level,
kSocketOptions[i].option),
&kSocketOptions[i]));
}
}
const socket_option_info *GetEntry(int level, int option) const
{
ThisMap::const_iterator i = fMap.find(make_pair(level, option));
if (i == fMap.end())
return NULL;
return i->second;
}
private:
ThisMap fMap;
};
static const SocketOptionsMap kSocketOptionsMap;
static string
format_pointer(Context &context, sockopt_args *args)
{
const socket_option_info *info =
kSocketOptionsMap.GetEntry(args->level, args->option);
string level, option, value;
if (context.GetContents(Context::ENUMERATIONS)) {
switch (args->level) {
case SOL_SOCKET:
level = "SOL_SOCKET";
break;
case IPPROTO_IP:
level = "IPPROTO_IP";
break;
}
if (info != NULL)
option = info->name;
}
if (info != NULL && info->length == args->length)
value = info->handler->GetParameterValue(context, NULL, &args->value);
else {
value = "value = " + context.FormatPointer(args->value);
value += ", len = " + context.FormatUnsigned(args->length);
}
if (level.empty())
level = "level = " + context.FormatSigned(args->level, sizeof(int));
if (option.empty())
option = "option = " + context.FormatSigned(args->option, sizeof(int));
return level + ", " + option + ", " + value;
}
static string
format_pointer(Context &context, socket_args *args)
{
string r;
r = format_socket_family(context, args->family) + ", ";
r += format_socket_type(context, args->type) + ", ";
r += format_socket_protocol(context, args->protocol);
return r;
}
static string
get_iovec(Context &context, struct iovec *iov, int iovlen)
{
string r = "{";
r += context.FormatPointer(iov);
r += ", " + context.FormatSigned(iovlen);
return r + "}";
}
static string
format_pointer(Context &context, msghdr *h)
{
string r;
r = "name = " + format_pointer_value<struct sockaddr>(context, h->msg_name);
r += ", name_len = " + context.FormatUnsigned(h->msg_namelen);
r += ", iov = " + get_iovec(context, h->msg_iov, h->msg_iovlen);
r += ", control = " + context.FormatPointer(h->msg_control);
r += ", control_len = " + context.FormatUnsigned(h->msg_controllen);
r += ", flags = " + context.FormatFlags(h->msg_flags);
return r;
}
template<typename Type>
class SpecializedPointerTypeHandler : public TypeHandler {
string GetParameterValue(Context &context, Parameter *,
const void *address)
{
return format_pointer_value<Type>(context, *(void **)address);
}
string GetReturnValue(Context &context, uint64 value)
{
return format_pointer_value<Type>(context, (void *)value);
}
};
#define DEFINE_TYPE(name, type) \
TypeHandler *create_##name##_type_handler() \
{ \
return new TypeHandlerImpl<type>(); \
}
#define POINTER_TYPE(name, type) \
TypeHandler *create_##name##_type_handler() \
{ \
return new SpecializedPointerTypeHandler<type>(); \
}
DEFINE_TYPE(fdset_ptr, struct fd_set *);
POINTER_TYPE(sockaddr_args_ptr, struct sockaddr_args);
POINTER_TYPE(transfer_args_ptr, struct transfer_args);
POINTER_TYPE(sockopt_args_ptr, struct sockopt_args);
POINTER_TYPE(socket_args_ptr, struct socket_args);
POINTER_TYPE(msghdr_ptr, struct msghdr);

View File

@ -9,25 +9,10 @@
#include "TypeHandler.h"
// headers required for network structures
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net_stack_driver.h>
#include "Context.h"
#include "MemoryReader.h"
#include "Syscall.h"
// TypeHandlerImpl
template<typename Type>
class TypeHandlerImpl : public TypeHandler {
public:
virtual string GetParameterValue(Context &, Parameter *, const void *);
virtual string GetReturnValue(Context &, uint64 value);
};
template<typename value_t>
static inline value_t
get_value(const void *address)
@ -40,26 +25,6 @@ get_value(const void *address)
// #pragma mark -
// get_pointer_value
static inline
string
get_pointer_value(const void *address)
{
char buffer[32];
sprintf(buffer, "%p", *(void **)address);
return buffer;
}
// get_pointer_value
static inline
string
get_pointer_value(uint64 value)
{
char buffer[32];
sprintf(buffer, "%p", (void*)value);
return buffer;
}
// create_pointer_type_handler
TypeHandler *
create_pointer_type_handler()
@ -126,11 +91,11 @@ TypeHandlerFactory<bool>::Create()
// read_string
static
string
read_string(MemoryReader &reader, void *data)
read_string(Context &context, void *data)
{
char buffer[256];
int32 bytesRead;
status_t error = reader.Read(data, buffer, sizeof(buffer), bytesRead);
status_t error = context.Reader().Read(data, buffer, sizeof(buffer), bytesRead);
if (error == B_OK) {
// return string("\"") + string(buffer, bytesRead) + "\"";
//string result("\"");
@ -149,72 +114,24 @@ read_string(MemoryReader &reader, void *data)
largeBuffer[len + 2] = '\0';
return largeBuffer;
}
return get_pointer_value(&data) + " (" + strerror(error) + ")";
}
static string
format_number(uint32 value)
{
char tmp[32];
snprintf(tmp, sizeof(tmp), "%u", (unsigned int)value);
return tmp;
}
static string
read_fdset(Context &context, void *data)
{
// default FD_SETSIZE is 1024
unsigned long tmp[1024 / (sizeof(unsigned long) * 8)];
int32 bytesRead;
status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead);
if (err != B_OK)
return get_pointer_value(&data);
/* implicitly align to unsigned long lower boundary */
int count = bytesRead / sizeof(unsigned long);
int added = 0;
string r;
r.reserve(16);
r = "[";
for (int i = 0; i < count && added < 8; i++) {
for (int j = 0;
j < (int)(sizeof(unsigned long) * 8) && added < 8; j++) {
if (tmp[i] & (1 << j)) {
if (added > 0)
r += " ";
unsigned int fd = i * sizeof(unsigned long) * 8 + j;
r += format_number(fd);
added++;
}
}
}
if (added >= 8)
r += " ...";
r += "]";
return r;
return context.FormatPointer(data) + " (" + strerror(error) + ")";
}
// const void*
template<>
string
TypeHandlerImpl<const void*>::GetParameterValue(Context &, Parameter *,
TypeHandlerImpl<const void*>::GetParameterValue(Context &context, Parameter *,
const void *address)
{
return get_pointer_value(address);
return context.FormatPointer(*(void **)address);
}
template<>
string
TypeHandlerImpl<const void*>::GetReturnValue(Context &, uint64 value)
TypeHandlerImpl<const void*>::GetReturnValue(Context &context, uint64 value)
{
return get_pointer_value(value);
return context.FormatPointer((void *)value);
}
// const char*
@ -225,9 +142,9 @@ TypeHandlerImpl<const char*>::GetParameterValue(Context &context, Parameter *,
{
void *data = *(void **)address;
if (data != NULL && context.GetContents(Context::STRINGS))
return read_string(context.Reader(), data);
return read_string(context, data);
return get_pointer_value(&data);
return context.FormatPointer(data);
}
template<>
@ -238,25 +155,6 @@ TypeHandlerImpl<const char*>::GetReturnValue(Context &context, uint64 value)
return GetParameterValue(context, NULL, (const void *)&ptr);
}
// struct fd_set *
template<>
string
TypeHandlerImpl<struct fd_set *>::GetParameterValue(Context &context, Parameter *,
const void *address)
{
void *data = *(void **)address;
if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS))
return read_fdset(context, data);
return get_pointer_value(&data);
}
template<>
string
TypeHandlerImpl<struct fd_set *>::GetReturnValue(Context &, uint64 value)
{
return get_pointer_value(value);
}
EnumTypeHandler::EnumTypeHandler(const EnumMap &m) : fMap(m) {}
string
@ -309,133 +207,44 @@ TypeHandlerSelector::GetReturnValue(Context &context, uint64 value)
return fDefault->GetReturnValue(context, value);
}
template<typename Base>
static string
format_pointer_deep(Context &context, void *address)
template<typename Type>
static bool
obtain_pointer_data(Context &context, Type *data, void *address, uint32 what)
{
if (address == NULL || !context.GetContents(Context::COMPLEX_STRUCTS))
return get_pointer_value(&address);
if (address == NULL || !context.GetContents(what))
return false;
Base data;
int32 bytesRead;
status_t err = context.Reader().Read(address, &data, sizeof(Base), bytesRead);
if (err != B_OK || bytesRead < (int32)sizeof(Base))
return get_pointer_value(&address);
status_t err = context.Reader().Read(address, data, sizeof(Type), bytesRead);
if (err != B_OK || bytesRead < (int32)sizeof(Type))
return false;
return format_pointer(context, &data);
return true;
}
template<typename Base>
template<typename Type>
static string
format_pointer_value(Context &context, const void *pointer)
format_signed_integer_pointer(Context &context, void *address)
{
return format_pointer_deep<Base>(context, *(void **)pointer);
Type data;
if (obtain_pointer_data(context, &data, address, Context::POINTER_VALUES))
return "[" + context.FormatSigned(data, sizeof(Type)) + "]";
return context.FormatPointer(address);
}
template<typename Base>
template<typename Type>
static string
format_pointer_value(Context &context, uint64 value)
format_unsigned_integer_pointer(Context &context, void *address)
{
return format_pointer_deep<Base>(context, (void *)value);
}
Type data;
static string
get_ipv4_address(struct in_addr *addr)
{
char tmp[32];
snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u",
(unsigned int)(htonl(addr->s_addr) >> 24) & 0xff,
(unsigned int)(htonl(addr->s_addr) >> 16) & 0xff,
(unsigned int)(htonl(addr->s_addr) >> 8) & 0xff,
(unsigned int)(htonl(addr->s_addr) >> 0) & 0xff);
return tmp;
}
if (obtain_pointer_data(context, &data, address, Context::POINTER_VALUES))
return "[" + context.FormatUnsigned(data) + "]";
static string
format_pointer(Context &context, sockaddr *saddr)
{
string r = "{";
struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
switch (saddr->sa_family) {
case AF_INET:
r += "AF_INET, ";
r += get_ipv4_address(&sin->sin_addr);
r += "/";
r += format_number(ntohs(sin->sin_port));
break;
default:
r += "family = ";
r += context.FormatUnsigned(saddr->sa_family);
r += ", ...";
break;
}
return r + "}";
}
static string
format_pointer(Context &context, sockaddr_args *args)
{
string r = "{";
r += "addr = " + format_pointer_deep<struct sockaddr>(context, args->address);
r += ", len = " + context.FormatUnsigned(args->address_length);
return r + "}";
}
static string
format_pointer(Context &context, transfer_args *args)
{
string r = "{";
r += "data = " + get_pointer_value(&args->data);
r += ", len = " + context.FormatUnsigned(args->data_length);
r += ", flags = " + context.FormatFlags(args->flags);
r += ", addr = " + format_pointer_deep<struct sockaddr>(context, args->address);
return r + "}";
}
static string
format_pointer(Context &context, sockopt_args *args)
{
string r = "{";
r += "level = " + context.FormatSigned(args->level);
r += ", option = " + context.FormatSigned(args->option);
r += ", value = " + get_pointer_value(args->value);
r += ", len = " + context.FormatSigned(args->length);
return r + "}";
}
static string
get_iovec(Context &context, struct iovec *iov, int iovlen)
{
string r = "{";
r += get_pointer_value(&iov);
r += ", " + context.FormatSigned(iovlen);
return r + "}";
}
static string
format_pointer(Context &context, msghdr *h)
{
string r = "{";
r += "name = " + format_pointer_deep<struct sockaddr>(context, h->msg_name);
r += ", name_len = " + context.FormatUnsigned(h->msg_namelen);
r += ", iov = " + get_iovec(context, h->msg_iov, h->msg_iovlen);
r += ", control = " + get_pointer_value(&h->msg_control);
r += ", control_len = " + context.FormatUnsigned(h->msg_controllen);
r += ", flags = " + context.FormatFlags(h->msg_flags);
return r + "}";
return context.FormatPointer(address);
}
template<typename Type>
@ -469,25 +278,33 @@ public:
};
template<typename Type>
class SpecializedPointerTypeHandler : public TypeHandler {
class SignedIntegerPointerTypeHandler : public TypeHandler {
string GetParameterValue(Context &context, Parameter *,
const void *address)
{
return format_pointer_value<Type>(context, address);
return format_signed_integer_pointer<Type>(context, *(void **)address);
}
string GetReturnValue(Context &context, uint64 value)
{
return format_pointer_value<Type>(context, value);
return format_signed_integer_pointer<Type>(context, (void *)value);
}
};
#define DEFINE_TYPE(name, type) \
TypeHandler *create_##name##_type_handler() \
{ \
return new TypeHandlerImpl<type>(); \
template<typename Type>
class UnsignedIntegerPointerTypeHandler : public TypeHandler {
string GetParameterValue(Context &context, Parameter *,
const void *address)
{
return format_unsigned_integer_pointer<Type>(context, *(void **)address);
}
string GetReturnValue(Context &context, uint64 value)
{
return format_unsigned_integer_pointer<Type>(context, (void *)value);
}
};
#define SIGNED_INTEGER_TYPE(type) \
template<> \
TypeHandler * \
@ -504,12 +321,19 @@ class SpecializedPointerTypeHandler : public TypeHandler {
return new UnsignedIntegerTypeHandler<type>(); \
}
#define POINTER_TYPE(name, type) \
#define SIGNED_INTEGER_POINTER_TYPE(name, type) \
TypeHandler *create_##name##_type_handler() \
{ \
return new SpecializedPointerTypeHandler<type>(); \
return new SignedIntegerPointerTypeHandler<type>(); \
}
#define UNSIGNED_INTEGER_POINTER_TYPE(name, type) \
TypeHandler *create_##name##_type_handler() \
{ \
return new UnsignedIntegerPointerTypeHandler<type>(); \
}
SIGNED_INTEGER_TYPE(char);
SIGNED_INTEGER_TYPE(short);
SIGNED_INTEGER_TYPE(int);
@ -522,9 +346,11 @@ UNSIGNED_INTEGER_TYPE(unsigned int);
UNSIGNED_INTEGER_TYPE(unsigned long);
UNSIGNED_INTEGER_TYPE(unsigned long long);
DEFINE_TYPE(fdset_ptr, struct fd_set *);
POINTER_TYPE(sockaddr_args_ptr, struct sockaddr_args);
POINTER_TYPE(transfer_args_ptr, struct transfer_args);
POINTER_TYPE(sockopt_args_ptr, struct sockopt_args);
POINTER_TYPE(msghdr_ptr, struct msghdr);
SIGNED_INTEGER_POINTER_TYPE(int_ptr, int);
SIGNED_INTEGER_POINTER_TYPE(long_ptr, long);
SIGNED_INTEGER_POINTER_TYPE(longlong_ptr, long long);
UNSIGNED_INTEGER_POINTER_TYPE(uint_ptr, unsigned int);
UNSIGNED_INTEGER_POINTER_TYPE(ulong_ptr, unsigned long);
UNSIGNED_INTEGER_POINTER_TYPE(ulonglong_ptr, unsigned long long);

View File

@ -101,6 +101,14 @@ DEFINE_FACTORY(fdset_ptr, struct fd_set *);
DEFINE_FACTORY(sockaddr_args_ptr, struct sockaddr_args *);
DEFINE_FACTORY(transfer_args_ptr, struct transfer_args *);
DEFINE_FACTORY(sockopt_args_ptr, struct sockopt_args *);
DEFINE_FACTORY(socket_args_ptr, struct socket_args *);
DEFINE_FACTORY(int_ptr, int *);
DEFINE_FACTORY(long_ptr, long *);
DEFINE_FACTORY(longlong_ptr, long long *);
DEFINE_FACTORY(uint_ptr, unsigned int *);
DEFINE_FACTORY(ulong_ptr, unsigned long *);
DEFINE_FACTORY(ulonglong_ptr, unsigned long long *);
// partial specialization for generic pointers
template<typename Type>
@ -111,4 +119,11 @@ struct TypeHandlerFactory<Type*> {
}
};
template<typename Type>
class TypeHandlerImpl : public TypeHandler {
public:
string GetParameterValue(Context &, Parameter *, const void *);
string GetReturnValue(Context &, uint64 value);
};
#endif // STRACE_TYPE_HANDLER_H

View File

@ -27,7 +27,7 @@ struct ioctl_info {
static const ioctl_info kIOCtls[] = {
// network stack ioctls
IOCTL_INFO_ENTRY(NET_STACK_SOCKET),
IOCTL_INFO_ENTRY_TYPE(NET_STACK_SOCKET, struct socket_args *),
IOCTL_INFO_ENTRY(NET_STACK_GET_COOKIE),
IOCTL_INFO_ENTRY(NET_STACK_CONTROL_NET_MODULE),
IOCTL_INFO_ENTRY(NET_STACK_GET_NEXT_STAT),

View File

@ -61,7 +61,8 @@ static const char *kUsage =
" -a - Don't print syscall arguments.\n"
" -c - Don't colorize output.\n"
" -d <name> - Filter the types that have their contents retrieved.\n"
" <name> is one of: strings, enums, simple or complex\n"
" <name> is one of: strings, enums, simple, complex or\n"
" pointer_values\n"
" -f - Fast mode. Syscall arguments contents aren't retrieved.\n"
" -h, --help - Print this text.\n"
" -i - Print integers in decimal format instead of hexadecimal.\n"
@ -483,6 +484,8 @@ main(int argc, const char *const *argv)
contentsFlags |= Context::SIMPLE_STRUCTS;
else if (strcasecmp(what, "complex") == 0)
contentsFlags |= Context::COMPLEX_STRUCTS;
else if (strcasecmp(what, "pointer_values") == 0)
contentsFlags |= Context::POINTER_VALUES;
else {
fprintf(stderr, "%s: Unknown content filter `%s'\n",
kCommandName, what);