[IRMemoryMap] Fix the alignment adjustment in Malloc
This prevents Malloc from allocating the same chunk of memory twice, as
a byproduct of an alignment adjustment which gave the client access to
unallocated memory.
Prior to this patch, the newly-added test failed with:
$ lldb-test ir-memory-map ... ir-memory-map-overlap1.test
...
Command: malloc(size=64, alignment=32)
Malloc: address = 0x1000cd080
Command: malloc(size=64, alignment=8)
Malloc: address = 0x1000cd0b0
Malloc error: overlapping allocation detected, previous allocation at [0x1000cd080, 0x1000cd0c0)
Differential Revision: https://reviews.llvm.org/D47551
llvm-svn: 333697
diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index 8fc2b4a..1953e808 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -301,15 +301,21 @@
lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
- size_t alignment_mask = alignment - 1;
size_t allocation_size;
- if (size == 0)
+ if (size == 0) {
+ // FIXME: Malloc(0) should either return an invalid address or assert, in
+ // order to cut down on unnecessary allocations.
allocation_size = alignment;
- else
- allocation_size = (size & alignment_mask)
- ? ((size + alignment) & (~alignment_mask))
- : size;
+ } else {
+ // Round up the requested size to an aligned value.
+ allocation_size = llvm::alignTo(size, alignment);
+
+ // The process page cache does not see the requested alignment. We can't
+ // assume its result will be any more than 1-byte aligned. To work around
+ // this, request `alignment - 1` additional bytes.
+ allocation_size += alignment - 1;
+ }
switch (policy) {
default: