ART: Fix valgrind failure in image_test64.
Explicitly clear LengthPrefixedArray<ArtMethod> padding
in ImageWriter. This also removes a potential source of
non-deterministic data in compiled boot image.
Bug: 26687569
Bug: 27552451
Change-Id: Icf4bf34c9ea5b3159462760fbf556d287841191d
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index b1b971f..0b69810 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1542,15 +1542,16 @@
}
case kNativeObjectRelocationTypeArtMethodArrayClean:
case kNativeObjectRelocationTypeArtMethodArrayDirty: {
- memcpy(dest, pair.first, LengthPrefixedArray<ArtMethod>::ComputeSize(
- 0,
- ArtMethod::Size(target_ptr_size_),
- ArtMethod::Alignment(target_ptr_size_)));
+ size_t size = ArtMethod::Size(target_ptr_size_);
+ size_t alignment = ArtMethod::Alignment(target_ptr_size_);
+ memcpy(dest, pair.first, LengthPrefixedArray<ArtMethod>::ComputeSize(0, size, alignment));
+ // Clear padding to avoid non-deterministic data in the image (and placate valgrind).
+ reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(dest)->ClearPadding(size, alignment);
break;
+ }
case kNativeObjectRelocationTypeDexCacheArray:
// Nothing to copy here, everything is done in FixupDexCache().
break;
- }
}
}
// Fixup the image method roots.
diff --git a/runtime/base/length_prefixed_array.h b/runtime/base/length_prefixed_array.h
index d632871..8060263 100644
--- a/runtime/base/length_prefixed_array.h
+++ b/runtime/base/length_prefixed_array.h
@@ -18,6 +18,7 @@
#define ART_RUNTIME_BASE_LENGTH_PREFIXED_ARRAY_H_
#include <stddef.h> // for offsetof()
+#include <string.h> // for memset()
#include "stride_iterator.h"
#include "base/bit_utils.h"
@@ -84,6 +85,13 @@
size_ = dchecked_integral_cast<uint32_t>(length);
}
+ // Clear the potentially uninitialized padding between the size_ and actual data.
+ void ClearPadding(size_t element_size = sizeof(T), size_t alignment = alignof(T)) {
+ size_t gap_offset = offsetof(LengthPrefixedArray<T>, data);
+ size_t gap_size = OffsetOfElement(0, element_size, alignment) - gap_offset;
+ memset(reinterpret_cast<uint8_t*>(this) + gap_offset, 0, gap_size);
+ }
+
private:
T& AtUnchecked(size_t index, size_t element_size, size_t alignment) {
return *reinterpret_cast<T*>(