X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace.hpp;h=c1e556a97fbb03d726be09de3cb92540de88e5fc;hb=452d3256a3ba7f249222ef857d69c8caaaa753f3;hp=300f00757aed19648a930a7cc8e9e98db3cd70ec;hpb=f5cda41c985730fc27361f3bb36cc2c5ede77e1c;p=apitrace diff --git a/retrace.hpp b/retrace.hpp index 300f007..c1e556a 100644 --- a/retrace.hpp +++ b/retrace.hpp @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2011 Jose Fonseca + * Copyright 2011-2012 Jose Fonseca * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -26,18 +26,24 @@ #ifndef _RETRACE_HPP_ #define _RETRACE_HPP_ +#include #include +#include #include #include #include #include "trace_model.hpp" +#include "trace_parser.hpp" namespace retrace { +extern trace::Parser parser; + + /** * Handle map. * @@ -80,20 +86,119 @@ public: }; +/** + * Similar to alloca(), but implemented with malloc. + */ +class ScopedAllocator +{ +private: + uintptr_t next; + +public: + ScopedAllocator() : + next(0) { + } + + inline void * + alloc(size_t size) { + if (!size) { + return NULL; + } + + uintptr_t * buf = static_cast(malloc(sizeof(uintptr_t) + size)); + if (!buf) { + return NULL; + } + + *buf = next; + next = reinterpret_cast(buf); + assert((next & 1) == 0); + + return static_cast(&buf[1]); + } + + template< class T > + inline T * + alloc(size_t n = 1) { + return static_cast(alloc(sizeof(T) * n)); + } + + /** + * Allocate an array with the same dimensions as the specified value. + */ + template< class T > + inline T * + alloc(const trace::Value *value) { + const trace::Array *array = dynamic_cast(value); + if (array) { + return alloc(array->size()); + } + const trace::Null *null = dynamic_cast(value); + if (null) { + return NULL; + } + assert(0); + return NULL; + } + + /** + * Prevent this pointer from being automatically freed. + */ + template< class T > + inline void + bind(T *ptr) { + if (ptr) { + reinterpret_cast(ptr)[-1] |= 1; + } + } + + inline + ~ScopedAllocator() { + while (next) { + uintptr_t temp = *reinterpret_cast(next); + + bool bind = temp & 1; + temp &= ~1; + + if (!bind) { + free(reinterpret_cast(next)); + } + + next = temp; + } + } +}; + + +void +addRegion(unsigned long long address, void *buffer, unsigned long long size); + +void +delRegionByPointer(void *ptr); + +void * +toPointer(trace::Value &value, bool bind = false); + + /** * Output verbosity when retracing files. */ extern int verbosity; +/** + * Add profiling data to the dump when retracing. + */ +extern bool profiling; + -std::ostream &warning(Trace::Call &call); +std::ostream &warning(trace::Call &call); -void ignore(Trace::Call &call); -void unsupported(Trace::Call &call); +void ignore(trace::Call &call); +void unsupported(trace::Call &call); -typedef void (*Callback)(Trace::Call &call); +typedef void (*Callback)(trace::Call &call); struct Entry { const char *name; @@ -108,6 +213,9 @@ struct stringComparer { }; +extern const Entry stdc_callbacks[]; + + class Retracer { typedef std::map Map; @@ -116,14 +224,16 @@ class Retracer std::vector callbacks; public: - Retracer() {} + Retracer() { + addCallbacks(stdc_callbacks); + } virtual ~Retracer() {} void addCallback(const Entry *entry); void addCallbacks(const Entry *entries); - void retrace(Trace::Call &call); + void retrace(trace::Call &call); };