[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
This commit is contained in:
Vedant Kumar 2018-05-31 22:08:59 +00:00
parent 99d60e0dab
commit 5b71e75ed3
4 changed files with 49 additions and 33 deletions

View File

@ -0,0 +1,25 @@
malloc 0 1
malloc 1 1
malloc 2 1
malloc 2 2
malloc 2 4
malloc 3 1
malloc 3 2
malloc 3 4
malloc 128 1
malloc 128 2
malloc 128 4
malloc 128 128
malloc 2048 1
malloc 2048 2
malloc 2048 4
malloc 3968 1
malloc 3968 2
malloc 3968 4
malloc 0 1

View File

@ -0,0 +1,10 @@
malloc 8 16
malloc 16 8
malloc 64 32
malloc 1 8
malloc 64 32
malloc 64 8
malloc 1024 32
malloc 1 16
malloc 8 16
malloc 1024 16

View File

@ -1,28 +1,3 @@
# RUN: %cxx %p/Inputs/call-function.cpp -g -o %t
# RUN: lldb-test ir-memory-map %t %s
malloc 0 1
malloc 1 1
malloc 2 1
malloc 2 2
malloc 2 4
malloc 3 1
malloc 3 2
malloc 3 4
malloc 128 1
malloc 128 2
malloc 128 4
malloc 128 128
malloc 2048 1
malloc 2048 2
malloc 2048 4
malloc 3968 1
malloc 3968 2
malloc 3968 4
malloc 0 1
# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-basic.test
# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-overlap1.test

View File

@ -301,15 +301,21 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
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: