cpu-kvm,arch-x86,arch-arm,dev: Pair operator new with operator delete.

When allocating memory with operator new(size_t), we should also delete
that memory with operator delete(). Note that this is a generic form of
new and delete which do not construct an object in the allocated space,
or delete the object when freeing the space.

There were a number of places where we were over-allocating a structure
so that there would be room after it for other data, at least sometimes
to allocate C structures which would have a trailing array of some other
structure with an undefined size. Those structures were then being
stored in a std::unique_ptr with the default deleter, which just calls
full blown delete and not operator delete.

It seems that this is often ok, and I was not able to find anything that
spelled out in bold letters that it isn't. I did find this sentence:

"If the pointer passed to the standard library deallocation function was
not obtained from the corresponding standard library allocation function,
the behavior is undefined."

On this webpage:

https://en.cppreference.com/w/cpp/memory/new/operator_delete

This is a *little* vague, since they might mean you can't mix malloc and
delete, or new and free. Strictly interpretting it though, it could mean
you can't mix operator new with regular delete, or any other mismatched
combination.

I also found that exactly how this causes problems depends on what heap
allocator you're using. When I used tcmalloc, gem5 would segfault within
that library. When I disabled tcmalloc to run valgrind, the segfault
went away. I think this may be because sometimes you get lucky and
undefined behavior is what you actually wanted, and sometimes you don't.

To fix this problem, this change overrides the deleter on all of these
unique_ptr-s so that they use operator delete. Also, it refactors some
code in arch/x86/kvm/x86_cpu.cc so that the function that allocates
memory with operator new returns a std::unique_ptr instead of a raw
pointer. This raw pointer was always immediately put into a unique_ptr
anyway, and, in addition to tidying up the call sights slightly, also
avoids having to define a custom deleter in each of those locations
instead of once in the allocation function.

Change-Id: I9ebff430996cf603051f5baa8708424819ed8465
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52383
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Gabe Black <gabe.black@gmail.com>
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
6 files changed