]> git.cworth.org Git - apitrace/blobdiff - retrace_stdc.cpp
Move tracers to wrappers subdirectory.
[apitrace] / retrace_stdc.cpp
index feb06b23d6cf7711e5034279cd02cdf9af085fd2..e6b108bbca679850704365ccb1732bc923006a92 100644 (file)
@@ -28,8 +28,6 @@
 
 #include <string.h>
 
-#include "glproc.hpp"
-
 
 
 #include "trace_parser.hpp"
@@ -47,44 +45,83 @@ struct Region
 typedef std::map<unsigned long long, Region> RegionMap;
 static RegionMap regionMap;
 
-// Iterator to the first region that contains the address
+
+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() &&
-           it != regionMap.end() &&
-           it->first + it->second. size > address) {
-        --it;
+    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 not contains the address
+// 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);
 
-    while (it != regionMap.end() &&
-           it->first + it->second.size > address) {
-        ++it;
-    }
-
     return it;
 }
 
 void
 addRegion(unsigned long long address, void *buffer, unsigned long long size)
 {
-    // Forget all regions that intersect this new one.
+    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) {
-        RegionMap::iterator start = lowerBound(address);
-        if (start != regionMap.end()) {
-            RegionMap::iterator stop = upperBound(address + size);
-            regionMap.erase(start, stop);
+        // 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);
 
@@ -108,8 +145,7 @@ lookupRegion(unsigned long long address) {
         }
     }
 
-    assert(it->first <= address);
-    assert(it->first + it->second.size >= address);
+    assert(contains(it, address));
     return it;
 }
 
@@ -126,8 +162,7 @@ delRegion(unsigned long long address) {
 
 void
 delRegionByPointer(void *ptr) {
-    RegionMap::iterator it = regionMap.begin();
-    while (it != regionMap.end()) {
+    for (RegionMap::iterator it = regionMap.begin(); it != regionMap.end(); ++it) {
         if (it->second.buffer == ptr) {
             regionMap.erase(it);
             return;
@@ -142,7 +177,20 @@ lookupAddress(unsigned long long address) {
     if (it != regionMap.end()) {
         unsigned long long offset = address - it->first;
         assert(offset < it->second.size);
-        return (char *)it->second.buffer + offset;
+        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 (address >= 0x00400000) {
@@ -153,22 +201,22 @@ lookupAddress(unsigned long long address) {
 }
 
 
-class Translator : protected Trace::Visitor
+class Translator : protected trace::Visitor
 {
 protected:
     bool bind;
 
     void *result;
 
-    void visit(Trace::Null *) {
+    void visit(trace::Null *) {
         result = NULL;
     }
 
-    void visit(Trace::Blob *blob) {
+    void visit(trace::Blob *blob) {
         result = blob->toPointer(bind);
     }
 
-    void visit(Trace::Pointer *p) {
+    void visit(trace::Pointer *p) {
         result = lookupAddress(p->value);
     }
 
@@ -178,7 +226,7 @@ public:
         result(NULL)
     {}
 
-    void * operator() (Trace::Value *node) {
+    void * operator() (trace::Value *node) {
         _visit(node);
         return result;
     }
@@ -186,12 +234,12 @@ public:
 
 
 void *
-toPointer(Trace::Value &value, bool bind) {
+toPointer(trace::Value &value, bool bind) {
     return Translator(bind) (&value);
 }
 
 
-static void retrace_malloc(Trace::Call &call) {
+static void retrace_malloc(trace::Call &call) {
     size_t size = call.arg(0).toUInt();
     unsigned long long address = call.ret->toUIntPtr();
 
@@ -209,7 +257,7 @@ static void retrace_malloc(Trace::Call &call) {
 }
 
 
-static void retrace_memcpy(Trace::Call &call) {
+static void retrace_memcpy(trace::Call &call) {
     void * dest = toPointer(call.arg(0));
     void * src  = toPointer(call.arg(1));
     size_t n    = call.arg(2).toUInt();