+ image_memory_t *image_memory = image->type_private;
+ u32 address = image->sections[section].base_address + offset;
+
+ *size_read = 0;
+
+ while ((size - *size_read) > 0)
+ {
+ u32 size_in_cache;
+
+ if (!image_memory->cache
+ || (address < image_memory->cache_address)
+ || (address >= (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE)))
+ {
+ if (!image_memory->cache)
+ image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
+
+ if (target_read_buffer(image_memory->target, address & ~(IMAGE_MEMORY_CACHE_SIZE - 1),
+ IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK)
+ {
+ free(image_memory->cache);
+ return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
+ }
+ image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1);
+ }
+
+ size_in_cache = (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
+
+ memcpy(buffer + *size_read,
+ image_memory->cache + (address - image_memory->cache_address),
+ (size_in_cache > size) ? size : size_in_cache
+ );
+
+ *size_read += (size_in_cache > size) ? size : size_in_cache;
+ address += (size_in_cache > size) ? size : size_in_cache;
+ }