X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace_stdc.cpp;h=53cacb997280f4edefa8e03bb8291b0bab639fe8;hb=f182eda5cee47f8f6220bc57756484df9e958727;hp=feb06b23d6cf7711e5034279cd02cdf9af085fd2;hpb=46a4839cd1b65981bec9f33b1d7978b821866a51;p=apitrace diff --git a/retrace_stdc.cpp b/retrace_stdc.cpp index feb06b2..53cacb9 100644 --- a/retrace_stdc.cpp +++ b/retrace_stdc.cpp @@ -28,8 +28,6 @@ #include -#include "glproc.hpp" - #include "trace_parser.hpp" @@ -47,44 +45,72 @@ struct Region typedef std::map 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 (!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 +134,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 +151,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; @@ -153,22 +177,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 +202,7 @@ public: result(NULL) {} - void * operator() (Trace::Value *node) { + void * operator() (trace::Value *node) { _visit(node); return result; } @@ -186,12 +210,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 +233,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();