struct-dump.c from aMSN at Krugle
Show struct-dump.c syntax highlighted
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include "struct-dump.h"
#ifndef PRId64
# warning Hmm, your C99 support is incomplete, will guess (should be ok for 32bit archs)
# define PRId64 "lld"
# define PRIx64 "llx"
# define PRIu64 "llu"
#endif
/* ---------------------------------------------------------------------- */
struct struct_desc desc_int[] = {{
.type = SINT32,
.name = "int",
},{
/* end of list */
}};
struct struct_desc desc_long[] = {{
.type = SINT32,
.name = "long",
},{
/* end of list */
}};
struct struct_desc desc_timeval[] = {{
/* FIXME */
/* end of list */
}};
/* ---------------------------------------------------------------------- */
int print_struct(FILE *fp, struct struct_desc *desc, void *data,
char *prefix, int tab)
{
char name[256];
unsigned char *ptr = data;
uint64_t u64;
int64_t s64;
uint32_t u32;
int32_t s32;
uint16_t u16;
int16_t s16;
uint8_t u8;
int8_t s8;
int al = sizeof(long)-1; /* struct + union + 64bit alignment */
void *p;
unsigned int i,j,first;
for (i = 0; desc[i].name != NULL; i++) {
sprintf(name,"%s%s",prefix,desc[i].name);
if (STRUCT == desc[i].type) {
strcat(name,".");
ptr = (void*)(((intptr_t)ptr + al) & ~al);
print_struct(fp,desc[i].desc, ptr, name, tab);
ptr += desc[i].length;
if (!tab && desc[i+1].name != NULL)
fprintf(fp,";");
continue;
}
if (UNION == desc[i].type) {
u32 = *((uint32_t*)(ptr-4));
ptr = (void*)(((intptr_t)ptr + al) & ~al);
for (j = 0; desc[i].u[j].name != NULL; j++)
if (desc[i].u[j].value == u32)
break;
if (desc[i].u[j].name != NULL) {
strcat(name,".");
strcat(name,desc[i].u[j].name);
strcat(name,".");
print_struct(fp,desc[i].u[j].desc,
ptr, name, tab);
}
return 0; /* FIXME */
}
if (desc[i].type != PADDING) {
if (tab)
fprintf(fp,"\t%-24s: ",name);
else
fprintf(fp,"%s=",name);
}
switch (desc[i].type) {
case STRING:
fprintf(fp,"\"%-.*s\"",desc[i].length,ptr);
ptr += desc[i].length;
break;
case PTR:
p = *(void**)ptr;
fprintf(fp,"%p",p);
ptr += sizeof(p);
break;
case VER:
u32 = *((uint32_t*)ptr);
fprintf(fp,"%d.%d.%d",
(u32 >> 16) & 0xff,
(u32 >> 8) & 0xff,
u32 & 0xff);
ptr += 4;
break;
case FOURCC:
u32 = *((uint32_t*)ptr);
fprintf(fp,"0x%08x [%c%c%c%c]", u32,
isprint(ptr[0]) ? ptr[0] : '.',
isprint(ptr[1]) ? ptr[1] : '.',
isprint(ptr[2]) ? ptr[2] : '.',
isprint(ptr[3]) ? ptr[3] : '.');
ptr += 4;
break;
case ENUM16:
u16 = *((uint16_t*)ptr);
fprintf(fp,"%s", (u16 < desc[i].length && desc[i].enums[u16])
? desc[i].enums[u16] : "unknown");
ptr += 2;
break;
case ENUM32:
u32 = *((uint32_t*)ptr);
fprintf(fp,"%s", (u32 < desc[i].length && desc[i].enums[u32])
? desc[i].enums[u32] : "unknown");
ptr += 4;
break;
case BITS16:
u16 = *((uint16_t*)ptr);
first = 1;
fprintf(fp,"0x%x [",u16);
for (j = 0; j < 16; j++) {
if (0 == (u16 & (1 << j)))
continue;
fprintf(fp,"%s%s",
first ? "" : ",",
desc[i].bits[j]);
first = 0;
}
fprintf(fp,"]");
ptr += 2;
break;
case BITS32:
u32 = *((uint32_t*)ptr);
first = 1;
fprintf(fp,"0x%x [",u32);
for (j = 0; j < 32; j++) {
if (0 == (u32 & (1 << j)))
continue;
fprintf(fp,"%s%s",
first ? "" : ",",
desc[i].bits[j]);
first = 0;
}
fprintf(fp,"]");
ptr += 4;
break;
case BITS64:
ptr = (void*)(((intptr_t)ptr + al) & ~al);
u64 = *((uint64_t*)ptr);
first = 1;
fprintf(fp,"0x%" PRIx64 " [",u64);
for (j = 0; j < 64; j++) {
if (0 == (u64 & ((int64_t)1 << j)))
continue;
fprintf(fp,"%s%s",
first ? "" : ",",
desc[i].bits[j]);
first = 0;
}
fprintf(fp,"]");
ptr += 8;
break;
case UINT64:
ptr = (void*)(((intptr_t)ptr + al) & ~al);
u64 = *((uint64_t*)ptr);
fprintf(fp,"%" PRIu64,u64);
ptr += 8;
break;
case SINT64:
ptr = (void*)(((intptr_t)ptr + al) & ~al);
s64 = *((int64_t*)ptr);
fprintf(fp,"%" PRId64,s64);
ptr += 8;
break;
case UINT32:
u32 = *((uint32_t*)ptr);
fprintf(fp,"%u",u32);
ptr += 4;
break;
case SINT32:
s32 = *((int32_t*)ptr);
fprintf(fp,"%d",s32);
ptr += 4;
break;
case UINT16:
u16 = *((uint16_t*)ptr);
fprintf(fp,"%u",u16);
ptr += 2;
break;
case SINT16:
s16 = *((int16_t*)ptr);
fprintf(fp,"%d",s16);
ptr += 2;
break;
case UINT8:
u8 = *((uint8_t*)ptr);
fprintf(fp,"%u",u8);
ptr += 1;
break;
case SINT8:
s8 = *((int8_t*)ptr);
fprintf(fp,"%d",s8);
ptr += 1;
break;
case PADDING:
ptr += desc[i].length;
break;
case STRUCT:
case UNION:
/* shouldn't happen */
fprintf(fp,"FIXME [type=%d]\n",desc[i].type);
exit(1);
}
if (tab)
fprintf(fp,"\n");
else if (desc[i+1].name != NULL)
fprintf(fp,";");
}
return 0;
}
/* ---------------------------------------------------------------------- */
int print_ioctl(FILE *fp, struct ioctl_desc *ioctls, char *prefix,
int cmd, void *ptr)
{
int index = _IOC_NR(cmd);
char *name = ioctls[index].name;
struct struct_desc *desc = ioctls[index].desc;
fprintf(fp,"%s%s(", prefix, name ? name : "UNKNOWN");
if (desc) {
print_struct(fp,desc,ptr,"",0);
} else {
fprintf(stderr,"%p",ptr);
}
fprintf(fp,")");
return 0;
}
/* ---------------------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/
See more files for this project here