/* If has_instr_jmp_targets is true, this routine trashes the note field * of each instr_t to store the offset in order to properly encode * the relative pc for an instr_t jump target */ byte * instrlist_encode_to_copy(dcontext_t *dcontext, instrlist_t *ilist, byte *copy_pc, byte *final_pc, byte *max_pc, bool has_instr_jmp_targets) { instr_t *inst; int len = 0; if (has_instr_jmp_targets || max_pc != NULL) { /* must set note fields first with offset, or compute length */ for (inst = instrlist_first(ilist); inst; inst = instr_get_next(inst)) { if (has_instr_jmp_targets) instr_set_note(inst, (void *)(ptr_int_t)len); len += instr_length(dcontext, inst); } } if (max_pc != NULL && (copy_pc + len > max_pc || POINTER_OVERFLOW_ON_ADD(copy_pc, len))) return NULL; for (inst = instrlist_first(ilist); inst != NULL; inst = instr_get_next(inst)) { byte *pc = instr_encode_to_copy(dcontext, inst, copy_pc, final_pc); if (pc == NULL) return NULL; final_pc += pc - copy_pc; copy_pc = pc; } return copy_pc; }
size_t allocation_size(app_pc start, app_pc *base) { #ifdef WINDOWS app_pc pc = start; MEMORY_BASIC_INFORMATION mbi; app_pc alloc_base; size_t size; if (dr_virtual_query(pc, &mbi, sizeof(mbi)) != sizeof(mbi)) return 0; if (mbi.State == MEM_FREE) { if (base != NULL) *base = NULL; return mbi.RegionSize; } alloc_base = mbi.AllocationBase; pc = (app_pc) mbi.BaseAddress + mbi.RegionSize; size = pc - alloc_base; /* keep querying until reach next alloc base */ do { if (dr_virtual_query(pc, &mbi, sizeof(mbi)) != sizeof(mbi)) break; if (mbi.State == MEM_FREE || mbi.AllocationBase != alloc_base) break; ASSERT(mbi.RegionSize > 0, "error querying memory"); size += mbi.RegionSize; if (POINTER_OVERFLOW_ON_ADD(pc, mbi.RegionSize)) break; pc += mbi.RegionSize; } while (true); ASSERT(alloc_base + size > start || alloc_base + size == NULL, "query mem error"); if (base != NULL) *base = alloc_base; return size; #else /* WINDOWS */ size_t size; if (dr_query_memory(start, base, &size, NULL)) return size; else return 0; #endif /* WINDOWS */ }
static void memory_iteration_test(void) { dr_mem_info_t info; byte *pc = NULL; while (true) { bool res = dr_query_memory_ex(pc, &info); if (!res) { ASSERT(info.type == DR_MEMTYPE_ERROR IF_WINDOWS(|| info.type == DR_MEMTYPE_ERROR_WINKERNEL)); if (info.type == DR_MEMTYPE_ERROR) dr_fprintf(STDERR, "error: memory iteration failed\n"); break; } ASSERT(info.type != DR_MEMTYPE_ERROR IF_WINDOWS(&& info.type != DR_MEMTYPE_ERROR_WINKERNEL)); if (POINTER_OVERFLOW_ON_ADD(pc, info.size)) break; pc += info.size; }