]> git.cworth.org Git - apitrace/commitdiff
Split retrace swizlling helpers.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 13 May 2012 09:04:19 +0000 (10:04 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 13 May 2012 09:04:19 +0000 (10:04 +0100)
retrace/CMakeLists.txt
retrace/retrace.hpp
retrace/retrace.py
retrace/retrace_stdc.cpp
retrace/retrace_swizzle.cpp [new file with mode: 0644]
retrace/retrace_swizzle.hpp [new file with mode: 0644]

index 00cef67af628155df305c34a5882dc89717d61ac..63fbed63fab1b7564b270661f14be07668955c3d 100644 (file)
@@ -35,6 +35,7 @@ add_library (retrace_common
     retrace.cpp
     retrace_main.cpp
     retrace_stdc.cpp
+    retrace_swizzle.cpp
 )
 
 target_link_libraries (retrace_common
@@ -145,8 +146,6 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR)
 
     include_directories (SYSTEM ${DirectX_D3DX9_INCLUDE_DIR})
     add_executable (d3dretrace
-        retrace.cpp
-        retrace_stdc.cpp
         d3dretrace_main.cpp
         d3dretrace_d3d9.cpp
         d3dretrace_ws.cpp
index 9a1d5ccc2832c7e5c704b7bac9c42edf5014da13..a019de787cae5de55432ba2797f9355cca45c3ad 100644 (file)
@@ -49,48 +49,6 @@ namespace retrace {
 extern trace::Parser parser;
 
 
-/**
- * Handle map.
- *
- * It is just like a regular std::map<T, T> container, but lookups of missing
- * keys return the key instead of default constructor.
- *
- * This is necessary for several GL named objects, where one can either request
- * the implementation to generate an unique name, or pick a value never used
- * before.
- *
- * XXX: In some cases, instead of returning the key, it would make more sense
- * to return an unused data value (e.g., container count).
- */
-template <class T>
-class map
-{
-private:
-    typedef std::map<T, T> base_type;
-    base_type base;
-
-public:
-
-    T & operator[] (const T &key) {
-        typename base_type::iterator it;
-        it = base.find(key);
-        if (it == base.end()) {
-            return (base[key] = key);
-        }
-        return it->second;
-    }
-    
-    const T & operator[] (const T &key) const {
-        typename base_type::const_iterator it;
-        it = base.find(key);
-        if (it == base.end()) {
-            return (base[key] = key);
-        }
-        return it->second;
-    }
-};
-
-
 /**
  * Similar to alloca(), but implemented with malloc.
  */
@@ -174,16 +132,6 @@ public:
 };
 
 
-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.
  */
index 82910213a0d678e379b8a4f1d6e3c26183d1dec2..7ee4a0666cefaa71a511532967a984bd7cb43480 100644 (file)
@@ -470,6 +470,7 @@ class Retracer:
         print '#include "os_time.hpp"'
         print '#include "trace_parser.hpp"'
         print '#include "retrace.hpp"'
+        print '#include "retrace_swizzle.hpp"'
         print
 
         types = api.getAllTypes()
index df3e0c38efe960bad19714e844995a6ded76be2a..dd4d0f477993f2db0ab9d6f670e1e2f1e9dcbd5e 100644 (file)
 
 
 #include <assert.h>
-
 #include <string.h>
 
+#include <iostream>
 
-
-#include "trace_parser.hpp"
 #include "retrace.hpp"
-
-
-namespace retrace {
-
-struct Region
-{
-    void *buffer;
-    unsigned long long size;
-};
-
-typedef std::map<unsigned long long, Region> RegionMap;
-static RegionMap regionMap;
-
-
-static inline bool
-contains(RegionMap::iterator &it, unsigned long long address) {
-    return it->first <= address && (it->first + it->second.size) > address;
-}
-
-
-static inline bool
-intersects(RegionMap::iterator &it, unsigned long long start, unsigned long long size) {
-    unsigned long it_start = it->first;
-    unsigned long it_stop  = it->first + it->second.size;
-    unsigned long stop = start + size;
-    return it_start < stop && start < it_stop;
-}
-
-
-// Iterator to the first region that contains the address, or the first after
-static RegionMap::iterator
-lowerBound(unsigned long long address) {
-    RegionMap::iterator it = regionMap.lower_bound(address);
-
-    while (it != regionMap.begin()) {
-        RegionMap::iterator pred = it;
-        --pred;
-        if (contains(pred, address)) {
-            it = pred;
-        } else {
-            break;
-        }
-    }
-
-    return it;
-}
-
-// Iterator to the first region that starts after the address
-static RegionMap::iterator
-upperBound(unsigned long long address) {
-    RegionMap::iterator it = regionMap.upper_bound(address);
-
-    return it;
-}
-
-void
-addRegion(unsigned long long address, void *buffer, unsigned long long size)
-{
-    if (retrace::verbosity >= 2) {
-        std::cout
-            << "region "
-            << std::hex
-            << "0x" << address << "-0x" << (address + size)
-            << " -> "
-            << "0x" << (uintptr_t)buffer << "-0x" << ((uintptr_t)buffer + size)
-            << std::dec
-            << "\n";
-    }
-
-    if (!address) {
-        // Ignore NULL pointer
-        assert(!buffer);
-        return;
-    }
-
-#ifndef NDEBUG
-    RegionMap::iterator start = lowerBound(address);
-    RegionMap::iterator stop = upperBound(address + size);
-    if (0) {
-        // Forget all regions that intersect this new one.
-        regionMap.erase(start, stop);
-    } else {
-        for (RegionMap::iterator it = start; it != stop; ++it) {
-            std::cerr << std::hex << "warning: "
-                "region 0x" << address << "-0x" << (address + size) << " "
-                "intersects existing region 0x" << it->first << "-0x" << (it->first + it->second.size) << "\n" << std::dec;
-            assert(intersects(it, address, size));
-        }
-    }
-#endif
-
-    assert(buffer);
-
-    Region region;
-    region.buffer = buffer;
-    region.size = size;
-
-    regionMap[address] = region;
-}
-
-static RegionMap::iterator
-lookupRegion(unsigned long long address) {
-    RegionMap::iterator it = regionMap.lower_bound(address);
-
-    if (it == regionMap.end() ||
-        it->first > address) {
-        if (it == regionMap.begin()) {
-            return regionMap.end();
-        } else {
-            --it;
-        }
-    }
-
-    assert(contains(it, address));
-    return it;
-}
-
-void
-delRegion(unsigned long long address) {
-    RegionMap::iterator it = lookupRegion(address);
-    if (it != regionMap.end()) {
-        regionMap.erase(it);
-    } else {
-        assert(0);
-    }
-}
-
-
-void
-delRegionByPointer(void *ptr) {
-    for (RegionMap::iterator it = regionMap.begin(); it != regionMap.end(); ++it) {
-        if (it->second.buffer == ptr) {
-            regionMap.erase(it);
-            return;
-        }
-    }
-    assert(0);
-}
-
-void *
-lookupAddress(unsigned long long address) {
-    RegionMap::iterator it = lookupRegion(address);
-    if (it != regionMap.end()) {
-        unsigned long long offset = address - it->first;
-        assert(offset < it->second.size);
-        void *addr = (char *)it->second.buffer + offset;
-
-        if (retrace::verbosity >= 2) {
-            std::cout
-                << "region "
-                << std::hex
-                << "0x" << address
-                << " <- "
-                << "0x" << (uintptr_t)addr
-                << std::dec
-                << "\n";
-        }
-
-        return addr;
-    }
-
-    if (retrace::debug && address >= 64 * 1024 * 1024) {
-        /* Likely not an offset, but an address that should had been swizzled */
-        std::cerr << "warning: passing high address 0x" << std::hex << address << std::dec << " as uintptr_t\n";
-    }
-
-    return (void *)(uintptr_t)address;
-}
-
-
-class Translator : protected trace::Visitor
-{
-protected:
-    bool bind;
-
-    void *result;
-
-    void visit(trace::Null *) {
-        result = NULL;
-    }
-
-    void visit(trace::Blob *blob) {
-        result = blob->toPointer(bind);
-    }
-
-    void visit(trace::Pointer *p) {
-        result = lookupAddress(p->value);
-    }
-
-public:
-    Translator(bool _bind) :
-        bind(_bind),
-        result(NULL)
-    {}
-
-    void * operator() (trace::Value *node) {
-        _visit(node);
-        return result;
-    }
-};
-
-
-void *
-toPointer(trace::Value &value, bool bind) {
-    return Translator(bind) (&value);
-}
+#include "retrace_swizzle.hpp"
 
 
 static void retrace_malloc(trace::Call &call) {
@@ -250,17 +43,17 @@ static void retrace_malloc(trace::Call &call) {
 
     void *buffer = malloc(size);
     if (!buffer) {
-        std::cerr << "error: failed to allocated " << size << " bytes.";
+        std::cerr << "error: failed to allocate " << size << " bytes.";
         return;
     }
 
-    addRegion(address, buffer, size);
+    retrace::addRegion(address, buffer, size);
 }
 
 
 static void retrace_memcpy(trace::Call &call) {
-    void * dest = toPointer(call.arg(0));
-    void * src  = toPointer(call.arg(1));
+    void * dest = retrace::toPointer(call.arg(0));
+    void * src  = retrace::toPointer(call.arg(1));
     size_t n    = call.arg(2).toUInt();
 
     if (!dest || !src || !n) {
@@ -271,11 +64,8 @@ static void retrace_memcpy(trace::Call &call) {
 }
 
 
-const retrace::Entry stdc_callbacks[] = {
+const retrace::Entry retrace::stdc_callbacks[] = {
     {"malloc", &retrace_malloc},
     {"memcpy", &retrace_memcpy},
     {NULL, NULL}
 };
-
-
-} /* retrace */
diff --git a/retrace/retrace_swizzle.cpp b/retrace/retrace_swizzle.cpp
new file mode 100644 (file)
index 0000000..52dfad2
--- /dev/null
@@ -0,0 +1,242 @@
+/**************************************************************************
+ *
+ * Copyright 2011-2012 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <assert.h>
+
+#include <string.h>
+
+#include "retrace.hpp"
+#include "retrace_swizzle.hpp"
+
+
+namespace retrace {
+
+
+struct Region
+{
+    void *buffer;
+    unsigned long long size;
+};
+
+typedef std::map<unsigned long long, Region> RegionMap;
+static RegionMap regionMap;
+
+
+static inline bool
+contains(RegionMap::iterator &it, unsigned long long address) {
+    return it->first <= address && (it->first + it->second.size) > address;
+}
+
+
+static inline bool
+intersects(RegionMap::iterator &it, unsigned long long start, unsigned long long size) {
+    unsigned long it_start = it->first;
+    unsigned long it_stop  = it->first + it->second.size;
+    unsigned long stop = start + size;
+    return it_start < stop && start < it_stop;
+}
+
+
+// Iterator to the first region that contains the address, or the first after
+static RegionMap::iterator
+lowerBound(unsigned long long address) {
+    RegionMap::iterator it = regionMap.lower_bound(address);
+
+    while (it != regionMap.begin()) {
+        RegionMap::iterator pred = it;
+        --pred;
+        if (contains(pred, address)) {
+            it = pred;
+        } else {
+            break;
+        }
+    }
+
+    return it;
+}
+
+// Iterator to the first region that starts after the address
+static RegionMap::iterator
+upperBound(unsigned long long address) {
+    RegionMap::iterator it = regionMap.upper_bound(address);
+
+    return it;
+}
+
+void
+addRegion(unsigned long long address, void *buffer, unsigned long long size)
+{
+    if (retrace::verbosity >= 2) {
+        std::cout
+            << "region "
+            << std::hex
+            << "0x" << address << "-0x" << (address + size)
+            << " -> "
+            << "0x" << (uintptr_t)buffer << "-0x" << ((uintptr_t)buffer + size)
+            << std::dec
+            << "\n";
+    }
+
+    if (!address) {
+        // Ignore NULL pointer
+        assert(!buffer);
+        return;
+    }
+
+#ifndef NDEBUG
+    RegionMap::iterator start = lowerBound(address);
+    RegionMap::iterator stop = upperBound(address + size);
+    if (0) {
+        // Forget all regions that intersect this new one.
+        regionMap.erase(start, stop);
+    } else {
+        for (RegionMap::iterator it = start; it != stop; ++it) {
+            std::cerr << std::hex << "warning: "
+                "region 0x" << address << "-0x" << (address + size) << " "
+                "intersects existing region 0x" << it->first << "-0x" << (it->first + it->second.size) << "\n" << std::dec;
+            assert(intersects(it, address, size));
+        }
+    }
+#endif
+
+    assert(buffer);
+
+    Region region;
+    region.buffer = buffer;
+    region.size = size;
+
+    regionMap[address] = region;
+}
+
+static RegionMap::iterator
+lookupRegion(unsigned long long address) {
+    RegionMap::iterator it = regionMap.lower_bound(address);
+
+    if (it == regionMap.end() ||
+        it->first > address) {
+        if (it == regionMap.begin()) {
+            return regionMap.end();
+        } else {
+            --it;
+        }
+    }
+
+    assert(contains(it, address));
+    return it;
+}
+
+void
+delRegion(unsigned long long address) {
+    RegionMap::iterator it = lookupRegion(address);
+    if (it != regionMap.end()) {
+        regionMap.erase(it);
+    } else {
+        assert(0);
+    }
+}
+
+
+void
+delRegionByPointer(void *ptr) {
+    for (RegionMap::iterator it = regionMap.begin(); it != regionMap.end(); ++it) {
+        if (it->second.buffer == ptr) {
+            regionMap.erase(it);
+            return;
+        }
+    }
+    assert(0);
+}
+
+void *
+lookupAddress(unsigned long long address) {
+    RegionMap::iterator it = lookupRegion(address);
+    if (it != regionMap.end()) {
+        unsigned long long offset = address - it->first;
+        assert(offset < it->second.size);
+        void *addr = (char *)it->second.buffer + offset;
+
+        if (retrace::verbosity >= 2) {
+            std::cout
+                << "region "
+                << std::hex
+                << "0x" << address
+                << " <- "
+                << "0x" << (uintptr_t)addr
+                << std::dec
+                << "\n";
+        }
+
+        return addr;
+    }
+
+    if (retrace::debug && address >= 64 * 1024 * 1024) {
+        /* Likely not an offset, but an address that should had been swizzled */
+        std::cerr << "warning: passing high address 0x" << std::hex << address << std::dec << " as uintptr_t\n";
+    }
+
+    return (void *)(uintptr_t)address;
+}
+
+
+class Translator : protected trace::Visitor
+{
+protected:
+    bool bind;
+
+    void *result;
+
+    void visit(trace::Null *) {
+        result = NULL;
+    }
+
+    void visit(trace::Blob *blob) {
+        result = blob->toPointer(bind);
+    }
+
+    void visit(trace::Pointer *p) {
+        result = lookupAddress(p->value);
+    }
+
+public:
+    Translator(bool _bind) :
+        bind(_bind),
+        result(NULL)
+    {}
+
+    void * operator() (trace::Value *node) {
+        _visit(node);
+        return result;
+    }
+};
+
+
+void *
+toPointer(trace::Value &value, bool bind) {
+    return Translator(bind) (&value);
+}
+
+
+} /* retrace */
diff --git a/retrace/retrace_swizzle.hpp b/retrace/retrace_swizzle.hpp
new file mode 100644 (file)
index 0000000..fa5e008
--- /dev/null
@@ -0,0 +1,92 @@
+/**************************************************************************
+ *
+ * Copyright 2011-2012 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef _RETRACE_SWIZZLE_HPP_
+#define _RETRACE_SWIZZLE_HPP_
+
+
+#include <map>
+
+#include "trace_model.hpp"
+
+
+namespace retrace {
+
+
+/**
+ * Handle map.
+ *
+ * It is just like a regular std::map<T, T> container, but lookups of missing
+ * keys return the key instead of default constructor.
+ *
+ * This is necessary for several GL named objects, where one can either request
+ * the implementation to generate an unique name, or pick a value never used
+ * before.
+ *
+ * XXX: In some cases, instead of returning the key, it would make more sense
+ * to return an unused data value (e.g., container count).
+ */
+template <class T>
+class map
+{
+private:
+    typedef std::map<T, T> base_type;
+    base_type base;
+
+public:
+
+    T & operator[] (const T &key) {
+        typename base_type::iterator it;
+        it = base.find(key);
+        if (it == base.end()) {
+            return (base[key] = key);
+        }
+        return it->second;
+    }
+    
+    const T & operator[] (const T &key) const {
+        typename base_type::const_iterator it;
+        it = base.find(key);
+        if (it == base.end()) {
+            return (base[key] = key);
+        }
+        return it->second;
+    }
+};
+
+
+void
+addRegion(unsigned long long address, void *buffer, unsigned long long size);
+
+void
+delRegionByPointer(void *ptr);
+
+void *
+toPointer(trace::Value &value, bool bind = false);
+
+
+} /* namespace retrace */
+
+#endif /* _RETRACE_SWIZZLE_HPP_ */