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 * 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; }
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); }
// Iterator to the first region that not contains 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; }
// 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); #ifndef NDEBUG if (it != regionMap.end()) { assert(it->first >= address); } #endif return it; }
void setRegionPitch(unsigned long long address, unsigned dimensions, int tracePitch, int realPitch) { RegionMap::iterator it = lookupRegion(address); if (it != regionMap.end()) { Region ®ion = it->second; region.dimensions = dimensions; region.tracePitch = tracePitch; region.realPitch = realPitch; } else { 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); return (char *)it->second.buffer + offset; } if (address >= 0x00400000) { std::cerr << "warning: could not translate address 0x" << std::hex << address << std::dec << "\n"; } return (void *)(uintptr_t)address; }
void addRegion(unsigned long long address, void *buffer, unsigned long long size) { // Forget all regions that intersect this new one. if (0) { RegionMap::iterator start = lowerBound(address); if (start != regionMap.end()) { RegionMap::iterator stop = upperBound(address + size); regionMap.erase(start, stop); } } assert(buffer); Region region; region.buffer = buffer; region.size = size; regionMap[address] = region; }
// 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; } } #ifndef NDEBUG if (it != regionMap.end()) { assert(contains(it, address) || it->first > address); } #endif return it; }
static void lookupAddress(unsigned long long address, Range &range) { RegionMap::const_iterator it = lookupRegion(address); if (it != regionMap.end()) { const Region & region = it->second; unsigned long long offset = address - it->first; assert(offset < region.size); range.ptr = (char *)region.buffer + offset; range.len = region.size - offset; range.dims = region.dimensions; range.tracePitch = region.tracePitch; range.realPitch = region.realPitch; if (retrace::verbosity >= 2) { std::cout << "region " << std::hex << "0x" << address << " <- " << "0x" << (uintptr_t)range.ptr << std::dec << "\n"; } return; } if (retrace::debug > 0 && 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"; } range.ptr = (void *)(uintptr_t)address; range.len = 0; }