/** * Create new guarded memory. * * Wraps, starting at the given "base_ptr" with guards. Allows reuse of stack allocated helper. * * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes. * @param user_size the size of the user data to be wrapped. * @param tag optional general purpose tag. * * @return user data pointer (inner pointer to supplied "base_ptr"). */ void* wrap_with_guards(void* base_ptr, size_t user_size, const void* tag = NULL) { assert(base_ptr != NULL, "Attempt to wrap NULL with memory guard"); _base_addr = (u_char*)base_ptr; get_head_guard()->build(); get_head_guard()->set_user_size(user_size); get_tail_guard()->build(); set_tag(tag); set_user_bytes(uninitBlockPad); assert(verify_guards(), "Expected valid memory guards"); return get_user_ptr(); }
void GuardedMemory::print_on(outputStream* st) const { if (_base_addr == NULL) { st->print_cr("GuardedMemory(" PTR_FORMAT ") not associated to any memory", p2i(this)); return; } st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT " tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT, p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr())); Guard* guard = get_head_guard(); st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN")); guard = get_tail_guard(); st->print_cr(" Trailer guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN")); u_char udata = *get_user_ptr(); switch (udata) { case uninitBlockPad: st->print_cr(" User data appears unused"); break; case freeBlockPad: st->print_cr(" User data appears to have been freed"); break; default: st->print_cr(" User data appears to be in use"); break; } }
/** * Return the size of the user data. * * @return the size of the user data. */ size_t get_user_size() const { assert(_base_addr, "Not wrapping any memory"); return get_head_guard()->get_user_size(); }
/** * Return the general purpose tag. * * @return the general purpose tag, defaults to NULL. */ void* get_tag() const { return get_head_guard()->get_tag(); }
/** * Set the general purpose tag. * * @param tag general purpose tag. */ void set_tag(const void* tag) { get_head_guard()->set_tag(tag); }
/** * Verify head and tail guards. * * @return true if guards are intact, false would indicate a buffer overrun. */ bool verify_guards() const { if (_base_addr != NULL) { return (get_head_guard()->verify() && get_tail_guard()->verify()); } return false; }