summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--adbconnection/adbconnection.cc7
-rw-r--r--build/Android.bp6
-rw-r--r--dex2oat/dex2oat_test.cc12
-rw-r--r--dex2oat/linker/image_writer.cc259
-rw-r--r--dex2oat/linker/image_writer.h46
-rw-r--r--dex2oat/linker/oat_writer.cc3
-rw-r--r--dex2oat/linker/oat_writer_test.cc3
-rw-r--r--dexlayout/dex_visualize.cc2
-rw-r--r--dexlayout/dexlayout_main.cc2
-rw-r--r--dexlist/dexlist.cc2
-rw-r--r--dt_fd_forward/dt_fd_forward.cc13
-rw-r--r--libartbase/base/common_art_test.cc2
-rw-r--r--libartbase/base/scoped_flock.cc3
-rw-r--r--libartbase/base/unix_file/fd_file.cc2
-rw-r--r--libartbase/base/unix_file/fd_file_test.cc3
-rw-r--r--libartbase/base/zip_archive_test.cc5
-rw-r--r--oatdump/oatdump.cc11
-rw-r--r--profman/profile_assistant_test.cc4
-rw-r--r--profman/profman.cc10
-rw-r--r--runtime/arch/x86/instruction_set_features_x86.cc21
-rw-r--r--runtime/arch/x86/instruction_set_features_x86.h2
-rw-r--r--runtime/arch/x86/instruction_set_features_x86_test.cc36
-rw-r--r--runtime/gc/space/image_space.cc16
-rw-r--r--runtime/hprof/hprof.cc5
-rw-r--r--runtime/image.cc2
-rw-r--r--runtime/image.h5
-rw-r--r--runtime/monitor_android.cc2
-rw-r--r--runtime/native/dalvik_system_VMDebug.cc3
-rw-r--r--runtime/oat_file_assistant_test.cc16
29 files changed, 201 insertions, 302 deletions
diff --git a/adbconnection/adbconnection.cc b/adbconnection/adbconnection.cc
index 205013335b..ba25393f0d 100644
--- a/adbconnection/adbconnection.cc
+++ b/adbconnection/adbconnection.cc
@@ -20,6 +20,7 @@
#include "android-base/endian.h"
#include "android-base/stringprintf.h"
+#include "base/file_utils.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/mutex.h"
@@ -428,11 +429,11 @@ void AdbConnectionState::SendAgentFds(bool require_handshake) {
cmsg->cmsg_type = SCM_RIGHTS;
// Duplicate the fds before sending them.
- android::base::unique_fd read_fd(dup(adb_connection_socket_));
+ android::base::unique_fd read_fd(art::DupCloexec(adb_connection_socket_));
CHECK_NE(read_fd.get(), -1) << "Failed to dup read_fd_: " << strerror(errno);
- android::base::unique_fd write_fd(dup(adb_connection_socket_));
+ android::base::unique_fd write_fd(art::DupCloexec(adb_connection_socket_));
CHECK_NE(write_fd.get(), -1) << "Failed to dup write_fd: " << strerror(errno);
- android::base::unique_fd write_lock_fd(dup(adb_write_event_fd_));
+ android::base::unique_fd write_lock_fd(art::DupCloexec(adb_write_event_fd_));
CHECK_NE(write_lock_fd.get(), -1) << "Failed to dup write_lock_fd: " << strerror(errno);
dt_fd_forward::FdSet {
diff --git a/build/Android.bp b/build/Android.bp
index 47a540d521..09d3a183f9 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -18,6 +18,8 @@ bootstrap_go_package {
}
art_clang_tidy_errors = [
+ "android-cloexec-dup",
+ "android-cloexec-open",
"bugprone-argument-comment",
"bugprone-lambda-function-name",
"bugprone-unused-raii", // Protect scoped things like MutexLock.
@@ -35,7 +37,9 @@ art_clang_tidy_errors = [
"misc-unused-using-decls",
]
// Should be: strings.Join(art_clang_tidy_errors, ",").
-art_clang_tidy_errors_str = "bugprone-argument-comment"
+art_clang_tidy_errors_str = "android-cloexec-dup"
+ + ",android-cloexec-open"
+ + ",bugprone-argument-comment"
+ ",bugprone-lambda-function-name"
+ ",bugprone-unused-raii"
+ ",bugprone-unused-return-value"
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 6f53861a3d..fbad1af55a 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -634,7 +634,9 @@ class Dex2oatLayoutTest : public Dex2oatTest {
const std::string& dex_location,
size_t num_classes,
uint32_t checksum) {
- int profile_test_fd = open(test_profile.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
+ int profile_test_fd = open(test_profile.c_str(),
+ O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
+ 0644);
CHECK_GE(profile_test_fd, 0);
ProfileCompilationInfo info;
@@ -1698,7 +1700,7 @@ TEST_F(Dex2oatTest, CompactDexGenerationFailureMultiDex) {
// Create a multidex file with only one dex that gets rejected for cdex conversion.
ScratchFile apk_file;
{
- FILE* file = fdopen(dup(apk_file.GetFd()), "w+b");
+ FILE* file = fdopen(DupCloexec(apk_file.GetFd()), "w+b");
ZipWriter writer(file);
// Add vdex to zip.
writer.StartEntry("classes.dex", ZipWriter::kCompress);
@@ -1837,7 +1839,7 @@ TEST_F(Dex2oatTest, DontExtract) {
std::unique_ptr<File> vdex_file(OS::OpenFileForReading(vdex_location.c_str()));
ASSERT_TRUE(vdex_file != nullptr);
ASSERT_GT(vdex_file->GetLength(), 0u);
- FILE* file = fdopen(dup(dm_file.GetFd()), "w+b");
+ FILE* file = fdopen(DupCloexec(dm_file.GetFd()), "w+b");
ZipWriter writer(file);
auto write_all_bytes = [&](File* file) {
std::unique_ptr<uint8_t[]> bytes(new uint8_t[file->GetLength()]);
@@ -1963,7 +1965,7 @@ TEST_F(Dex2oatTest, QuickenedInput) {
TEST_F(Dex2oatTest, CompactDexInvalidSource) {
ScratchFile invalid_dex;
{
- FILE* file = fdopen(dup(invalid_dex.GetFd()), "w+b");
+ FILE* file = fdopen(DupCloexec(invalid_dex.GetFd()), "w+b");
ZipWriter writer(file);
writer.StartEntry("classes.dex", ZipWriter::kAlign32);
DexFile::Header header = {};
@@ -2005,7 +2007,7 @@ TEST_F(Dex2oatTest, CompactDexInZip) {
// Create a zip containing the invalid dex.
ScratchFile invalid_dex_zip;
{
- FILE* file = fdopen(dup(invalid_dex_zip.GetFd()), "w+b");
+ FILE* file = fdopen(DupCloexec(invalid_dex_zip.GetFd()), "w+b");
ZipWriter writer(file);
writer.StartEntry("classes.dex", ZipWriter::kCompress);
ASSERT_GE(writer.WriteBytes(&header, sizeof(header)), 0);
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 6410c7a6d9..ddc9f433cf 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -27,7 +27,6 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
-#include "base/bit_memory_region.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
#include "base/globals.h"
@@ -88,14 +87,6 @@ using ::art::mirror::String;
namespace art {
namespace linker {
-static inline size_t RelocationIndex(size_t relocation_offset, PointerSize target_ptr_size) {
- static_assert(sizeof(GcRoot<mirror::Object>) == sizeof(mirror::HeapReference<mirror::Object>),
- "Expecting heap GC roots and references to have the same size.");
- DCHECK_LE(sizeof(GcRoot<mirror::Object>), static_cast<size_t>(target_ptr_size));
- DCHECK_ALIGNED(relocation_offset, sizeof(GcRoot<mirror::Object>));
- return relocation_offset / sizeof(GcRoot<mirror::Object>);
-}
-
static ArrayRef<const uint8_t> MaybeCompressData(ArrayRef<const uint8_t> source,
ImageHeader::StorageMode image_storage_mode,
/*out*/ std::vector<uint8_t>* storage) {
@@ -672,22 +663,6 @@ bool ImageWriter::Write(int image_fd,
return false;
}
- // Write out relocations.
- size_t relocations_position_in_file = bitmap_position_in_file + bitmap_section.Size();
- ArrayRef<const uint8_t> relocations = MaybeCompressData(
- ArrayRef<const uint8_t>(image_info.relocation_bitmap_),
- image_storage_mode_,
- &compressed_data);
- image_header->sections_[ImageHeader::kSectionImageRelocations] =
- ImageSection(bitmap_section.Offset() + bitmap_section.Size(), relocations.size());
- if (!image_file->PwriteFully(relocations.data(),
- relocations.size(),
- relocations_position_in_file)) {
- PLOG(ERROR) << "Failed to write image file relocations " << image_filename;
- image_file->Erase();
- return false;
- }
-
int err = image_file->Flush();
if (err < 0) {
PLOG(ERROR) << "Failed to flush image file " << image_filename << " with result " << err;
@@ -708,9 +683,7 @@ bool ImageWriter::Write(int image_fd,
}
if (VLOG_IS_ON(compiler)) {
- size_t separately_written_section_size = bitmap_section.Size() +
- image_header->GetImageRelocationsSection().Size() +
- sizeof(ImageHeader);
+ size_t separately_written_section_size = bitmap_section.Size() + sizeof(ImageHeader);
size_t total_uncompressed_size = raw_image_data.size() + separately_written_section_size,
total_compressed_size = image_data.size() + separately_written_section_size;
@@ -721,7 +694,7 @@ bool ImageWriter::Write(int image_fd,
}
}
- CHECK_EQ(relocations_position_in_file + relocations.size(),
+ CHECK_EQ(bitmap_position_in_file + bitmap_section.Size(),
static_cast<size_t>(image_file->GetLength()));
if (image_file->FlushCloseOrErase() != 0) {
@@ -2366,8 +2339,6 @@ void ImageWriter::CreateHeader(size_t oat_index) {
const size_t bitmap_bytes = image_info.image_bitmap_->Size();
auto* bitmap_section = &sections[ImageHeader::kSectionImageBitmap];
*bitmap_section = ImageSection(RoundUp(image_end, kPageSize), RoundUp(bitmap_bytes, kPageSize));
- // The relocations section shall be finished later as we do not know its actual size yet.
-
if (VLOG_IS_ON(compiler)) {
LOG(INFO) << "Creating header for " << oat_filenames_[oat_index];
size_t idx = 0;
@@ -2394,7 +2365,7 @@ void ImageWriter::CreateHeader(size_t oat_index) {
// Create the header, leave 0 for data size since we will fill this in as we are writing the
// image.
- ImageHeader* header = new (image_info.image_.Begin()) ImageHeader(
+ new (image_info.image_.Begin()) ImageHeader(
PointerToLowMemUInt32(image_info.image_begin_),
image_end,
sections.data(),
@@ -2411,28 +2382,6 @@ void ImageWriter::CreateHeader(size_t oat_index) {
static_cast<uint32_t>(target_ptr_size_),
image_storage_mode_,
/*data_size*/0u);
-
- // Resize relocation bitmap for recording reference/pointer relocations.
- size_t number_of_relocation_locations = RelocationIndex(image_end, target_ptr_size_);
- DCHECK(image_info.relocation_bitmap_.empty());
- image_info.relocation_bitmap_.resize(
- BitsToBytesRoundUp(number_of_relocation_locations * (compile_app_image_ ? 2u : 1u)));
- // Record header relocations.
- RecordImageRelocation(&header->image_begin_, oat_index);
- RecordImageRelocation(&header->oat_file_begin_, oat_index);
- RecordImageRelocation(&header->oat_data_begin_, oat_index);
- RecordImageRelocation(&header->oat_data_end_, oat_index);
- RecordImageRelocation(&header->oat_file_end_, oat_index);
- if (compile_app_image_) {
- RecordImageRelocation(&header->boot_image_begin_, oat_index, /* app_to_boot_image */ true);
- RecordImageRelocation(&header->boot_oat_begin_, oat_index, /* app_to_boot_image */ true);
- } else {
- DCHECK_EQ(header->boot_image_begin_, 0u);
- DCHECK_EQ(header->boot_oat_begin_, 0u);
- }
- RecordImageRelocation(&header->image_roots_, oat_index);
- // Skip non-null check for `patch_delta_` as it is actually 0 but still needs to be recorded.
- RecordImageRelocation</* kCheckNotNull */ false>(&header->patch_delta_, oat_index);
}
ArtMethod* ImageWriter::GetImageMethodAddress(ArtMethod* method) {
@@ -2492,28 +2441,23 @@ class ImageWriter::FixupRootVisitor : public RootVisitor {
ImageWriter* const image_writer_;
};
-void ImageWriter::CopyAndFixupImTable(ImTable* orig, ImTable* copy, size_t oat_index) {
+void ImageWriter::CopyAndFixupImTable(ImTable* orig, ImTable* copy) {
for (size_t i = 0; i < ImTable::kSize; ++i) {
ArtMethod* method = orig->Get(i, target_ptr_size_);
void** address = reinterpret_cast<void**>(copy->AddressOfElement(i, target_ptr_size_));
- CopyAndFixupPointer(address, method, oat_index);
+ CopyAndFixupPointer(address, method);
DCHECK_EQ(copy->Get(i, target_ptr_size_), NativeLocationInImage(method));
}
}
-void ImageWriter::CopyAndFixupImtConflictTable(ImtConflictTable* orig,
- ImtConflictTable* copy,
- size_t oat_index) {
+void ImageWriter::CopyAndFixupImtConflictTable(ImtConflictTable* orig, ImtConflictTable* copy) {
const size_t count = orig->NumEntries(target_ptr_size_);
for (size_t i = 0; i < count; ++i) {
ArtMethod* interface_method = orig->GetInterfaceMethod(i, target_ptr_size_);
ArtMethod* implementation_method = orig->GetImplementationMethod(i, target_ptr_size_);
- CopyAndFixupPointer(copy->AddressOfInterfaceMethod(i, target_ptr_size_),
- interface_method,
- oat_index);
- CopyAndFixupPointer(copy->AddressOfImplementationMethod(i, target_ptr_size_),
- implementation_method,
- oat_index);
+ CopyAndFixupPointer(copy->AddressOfInterfaceMethod(i, target_ptr_size_), interface_method);
+ CopyAndFixupPointer(
+ copy->AddressOfImplementationMethod(i, target_ptr_size_), implementation_method);
DCHECK_EQ(copy->GetInterfaceMethod(i, target_ptr_size_),
NativeLocationInImage(interface_method));
DCHECK_EQ(copy->GetImplementationMethod(i, target_ptr_size_),
@@ -2538,8 +2482,7 @@ void ImageWriter::CopyAndFixupNativeData(size_t oat_index) {
memcpy(dest, pair.first, sizeof(ArtField));
CopyAndFixupReference(
reinterpret_cast<ArtField*>(dest)->GetDeclaringClassAddressWithoutBarrier(),
- reinterpret_cast<ArtField*>(pair.first)->GetDeclaringClass(),
- oat_index);
+ reinterpret_cast<ArtField*>(pair.first)->GetDeclaringClass());
break;
}
case NativeObjectRelocationType::kRuntimeMethod:
@@ -2572,15 +2515,14 @@ void ImageWriter::CopyAndFixupNativeData(size_t oat_index) {
case NativeObjectRelocationType::kIMTable: {
ImTable* orig_imt = reinterpret_cast<ImTable*>(pair.first);
ImTable* dest_imt = reinterpret_cast<ImTable*>(dest);
- CopyAndFixupImTable(orig_imt, dest_imt, oat_index);
+ CopyAndFixupImTable(orig_imt, dest_imt);
break;
}
case NativeObjectRelocationType::kIMTConflictTable: {
auto* orig_table = reinterpret_cast<ImtConflictTable*>(pair.first);
CopyAndFixupImtConflictTable(
orig_table,
- new(dest)ImtConflictTable(orig_table->NumEntries(target_ptr_size_), target_ptr_size_),
- oat_index);
+ new(dest)ImtConflictTable(orig_table->NumEntries(target_ptr_size_), target_ptr_size_));
break;
}
}
@@ -2590,10 +2532,8 @@ void ImageWriter::CopyAndFixupNativeData(size_t oat_index) {
for (size_t i = 0; i < ImageHeader::kImageMethodsCount; ++i) {
ArtMethod* method = image_methods_[i];
CHECK(method != nullptr);
- CopyAndFixupPointer(reinterpret_cast<void**>(&image_header->image_methods_[i]),
- method,
- oat_index,
- PointerSize::k32);
+ CopyAndFixupPointer(
+ reinterpret_cast<void**>(&image_header->image_methods_[i]), method, PointerSize::k32);
}
FixupRootVisitor root_visitor(this);
@@ -2618,9 +2558,6 @@ void ImageWriter::CopyAndFixupNativeData(size_t oat_index) {
MutexLock lock(Thread::Current(), *Locks::intern_table_lock_);
DCHECK(!temp_intern_table.strong_interns_.tables_.empty());
DCHECK(!temp_intern_table.strong_interns_.tables_[0].empty()); // Inserted at the beginning.
- for (const GcRoot<mirror::String>& slot : temp_intern_table.strong_interns_.tables_[0]) {
- RecordImageRelocation(&slot, oat_index);
- }
}
// Write the class table(s) into the image. class_table_bytes_ may be 0 if there are multiple
// class loaders. Writing multiple class tables into the image is currently unsupported.
@@ -2649,9 +2586,6 @@ void ImageWriter::CopyAndFixupNativeData(size_t oat_index) {
ReaderMutexLock lock(self, temp_class_table.lock_);
DCHECK(!temp_class_table.classes_.empty());
DCHECK(!temp_class_table.classes_[0].empty()); // The ClassSet was inserted at the beginning.
- for (const ClassTable::TableSlot& slot : temp_class_table.classes_[0]) {
- RecordImageRelocation(&slot, oat_index);
- }
}
}
@@ -2668,15 +2602,13 @@ void ImageWriter::CopyAndFixupObjects() {
void ImageWriter::FixupPointerArray(mirror::Object* dst,
mirror::PointerArray* arr,
mirror::Class* klass,
- Bin array_type,
- size_t oat_index) {
+ Bin array_type) {
CHECK(klass->IsArrayClass());
CHECK(arr->IsIntArray() || arr->IsLongArray()) << klass->PrettyClass() << " " << arr;
// Fixup int and long pointers for the ArtMethod or ArtField arrays.
const size_t num_elements = arr->GetLength();
- CopyAndFixupReference(dst->GetFieldObjectReferenceAddr<kVerifyNone>(Class::ClassOffset()),
- arr->GetClass(),
- oat_index);
+ CopyAndFixupReference(
+ dst->GetFieldObjectReferenceAddr<kVerifyNone>(Class::ClassOffset()), arr->GetClass());
auto* dest_array = down_cast<mirror::PointerArray*>(dst);
for (size_t i = 0, count = num_elements; i < count; ++i) {
void* elem = arr->GetElementPtrSize<void*>(i, target_ptr_size_);
@@ -2698,7 +2630,7 @@ void ImageWriter::FixupPointerArray(mirror::Object* dst,
UNREACHABLE();
}
}
- CopyAndFixupPointer(dest_array->ElementAddress(i, target_ptr_size_), elem, oat_index);
+ CopyAndFixupPointer(dest_array->ElementAddress(i, target_ptr_size_), elem);
}
}
@@ -2729,14 +2661,14 @@ void ImageWriter::CopyAndFixupObject(Object* obj) {
// safe since we mark all of the objects that may reference non immune objects as gray.
CHECK(dst->AtomicSetMarkBit(0, 1));
}
- FixupObject(obj, dst, oat_index);
+ FixupObject(obj, dst);
}
// Rewrite all the references in the copied object to point to their image address equivalent
class ImageWriter::FixupVisitor {
public:
- FixupVisitor(ImageWriter* image_writer, Object* copy, size_t oat_index)
- : image_writer_(image_writer), copy_(copy), oat_index_(oat_index) {
+ FixupVisitor(ImageWriter* image_writer, Object* copy)
+ : image_writer_(image_writer), copy_(copy) {
}
// Ignore class roots since we don't have a way to map them to the destination. These are handled
@@ -2751,9 +2683,7 @@ class ImageWriter::FixupVisitor {
ObjPtr<Object> ref = obj->GetFieldObject<Object, kVerifyNone>(offset);
// Copy the reference and record the fixup if necessary.
image_writer_->CopyAndFixupReference(
- copy_->GetFieldObjectReferenceAddr<kVerifyNone>(offset),
- ref.Ptr(),
- oat_index_);
+ copy_->GetFieldObjectReferenceAddr<kVerifyNone>(offset), ref);
}
// java.lang.ref.Reference visitor.
@@ -2766,13 +2696,12 @@ class ImageWriter::FixupVisitor {
protected:
ImageWriter* const image_writer_;
mirror::Object* const copy_;
- size_t oat_index_;
};
class ImageWriter::FixupClassVisitor final : public FixupVisitor {
public:
- FixupClassVisitor(ImageWriter* image_writer, Object* copy, size_t oat_index)
- : FixupVisitor(image_writer, copy, oat_index) {}
+ FixupClassVisitor(ImageWriter* image_writer, Object* copy)
+ : FixupVisitor(image_writer, copy) {}
void operator()(ObjPtr<Object> obj, MemberOffset offset, bool is_static ATTRIBUTE_UNUSED) const
REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
@@ -2828,14 +2757,13 @@ T* ImageWriter::NativeCopyLocation(T* obj) {
class ImageWriter::NativeLocationVisitor {
public:
- NativeLocationVisitor(ImageWriter* image_writer, size_t oat_index)
- : image_writer_(image_writer),
- oat_index_(oat_index) {}
+ explicit NativeLocationVisitor(ImageWriter* image_writer)
+ : image_writer_(image_writer) {}
template <typename T>
T* operator()(T* ptr, void** dest_addr) const REQUIRES_SHARED(Locks::mutator_lock_) {
if (ptr != nullptr) {
- image_writer_->CopyAndFixupPointer(dest_addr, ptr, oat_index_);
+ image_writer_->CopyAndFixupPointer(dest_addr, ptr);
}
// TODO: The caller shall overwrite the value stored by CopyAndFixupPointer()
// with the value we return here. We should try to avoid the duplicate work.
@@ -2844,12 +2772,11 @@ class ImageWriter::NativeLocationVisitor {
private:
ImageWriter* const image_writer_;
- const size_t oat_index_;
};
-void ImageWriter::FixupClass(mirror::Class* orig, mirror::Class* copy, size_t oat_index) {
- orig->FixupNativePointers(copy, target_ptr_size_, NativeLocationVisitor(this, oat_index));
- FixupClassVisitor visitor(this, copy, oat_index);
+void ImageWriter::FixupClass(mirror::Class* orig, mirror::Class* copy) {
+ orig->FixupNativePointers(copy, target_ptr_size_, NativeLocationVisitor(this));
+ FixupClassVisitor visitor(this, copy);
ObjPtr<mirror::Object>(orig)->VisitReferences(visitor, visitor);
if (kBitstringSubtypeCheckEnabled && compile_app_image_) {
@@ -2877,7 +2804,7 @@ void ImageWriter::FixupClass(mirror::Class* orig, mirror::Class* copy, size_t oa
copy->SetClinitThreadId(static_cast<pid_t>(0));
}
-void ImageWriter::FixupObject(Object* orig, Object* copy, size_t oat_index) {
+void ImageWriter::FixupObject(Object* orig, Object* copy) {
DCHECK(orig != nullptr);
DCHECK(copy != nullptr);
if (kUseBakerReadBarrier) {
@@ -2889,13 +2816,13 @@ void ImageWriter::FixupObject(Object* orig, Object* copy, size_t oat_index) {
auto it = pointer_arrays_.find(down_cast<mirror::PointerArray*>(orig));
if (it != pointer_arrays_.end()) {
// Should only need to fixup every pointer array exactly once.
- FixupPointerArray(copy, down_cast<mirror::PointerArray*>(orig), klass, it->second, oat_index);
+ FixupPointerArray(copy, down_cast<mirror::PointerArray*>(orig), klass, it->second);
pointer_arrays_.erase(it);
return;
}
}
if (orig->IsClass()) {
- FixupClass(orig->AsClass<kVerifyNone>(), down_cast<mirror::Class*>(copy), oat_index);
+ FixupClass(orig->AsClass<kVerifyNone>(), down_cast<mirror::Class*>(copy));
} else {
ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
Runtime::Current()->GetClassLinker()->GetClassRoots();
@@ -2905,11 +2832,9 @@ void ImageWriter::FixupObject(Object* orig, Object* copy, size_t oat_index) {
auto* dest = down_cast<mirror::Executable*>(copy);
auto* src = down_cast<mirror::Executable*>(orig);
ArtMethod* src_method = src->GetArtMethod();
- CopyAndFixupPointer(dest, mirror::Executable::ArtMethodOffset(), src_method, oat_index);
+ CopyAndFixupPointer(dest, mirror::Executable::ArtMethodOffset(), src_method);
} else if (klass == GetClassRoot<mirror::DexCache>(class_roots)) {
- FixupDexCache(down_cast<mirror::DexCache*>(orig),
- down_cast<mirror::DexCache*>(copy),
- oat_index);
+ FixupDexCache(down_cast<mirror::DexCache*>(orig), down_cast<mirror::DexCache*>(copy));
} else if (klass->IsClassLoaderClass()) {
mirror::ClassLoader* copy_loader = down_cast<mirror::ClassLoader*>(copy);
// If src is a ClassLoader, set the class table to null so that it gets recreated by the
@@ -2920,7 +2845,7 @@ void ImageWriter::FixupObject(Object* orig, Object* copy, size_t oat_index) {
// roots.
copy_loader->SetAllocator(nullptr);
}
- FixupVisitor visitor(this, copy, oat_index);
+ FixupVisitor visitor(this, copy);
orig->VisitReferences(visitor, visitor);
}
}
@@ -2928,8 +2853,7 @@ void ImageWriter::FixupObject(Object* orig, Object* copy, size_t oat_index) {
template <typename T>
void ImageWriter::FixupDexCacheArrayEntry(std::atomic<mirror::DexCachePair<T>>* orig_array,
std::atomic<mirror::DexCachePair<T>>* new_array,
- uint32_t array_index,
- size_t oat_index) {
+ uint32_t array_index) {
static_assert(sizeof(std::atomic<mirror::DexCachePair<T>>) == sizeof(mirror::DexCachePair<T>),
"Size check for removing std::atomic<>.");
mirror::DexCachePair<T>* orig_pair =
@@ -2937,15 +2861,14 @@ void ImageWriter::FixupDexCacheArrayEntry(std::atomic<mirror::DexCachePair<T>>*
mirror::DexCachePair<T>* new_pair =
reinterpret_cast<mirror::DexCachePair<T>*>(&new_array[array_index]);
CopyAndFixupReference(
- new_pair->object.AddressWithoutBarrier(), orig_pair->object.Read(), oat_index);
+ new_pair->object.AddressWithoutBarrier(), orig_pair->object.Read());
new_pair->index = orig_pair->index;
}
template <typename T>
void ImageWriter::FixupDexCacheArrayEntry(std::atomic<mirror::NativeDexCachePair<T>>* orig_array,
std::atomic<mirror::NativeDexCachePair<T>>* new_array,
- uint32_t array_index,
- size_t oat_index) {
+ uint32_t array_index) {
static_assert(
sizeof(std::atomic<mirror::NativeDexCachePair<T>>) == sizeof(mirror::NativeDexCachePair<T>),
"Size check for removing std::atomic<>.");
@@ -2956,9 +2879,8 @@ void ImageWriter::FixupDexCacheArrayEntry(std::atomic<mirror::NativeDexCachePair
reinterpret_cast<DexCache::ConversionPair64*>(new_array) + array_index;
*new_pair = *orig_pair; // Copy original value and index.
if (orig_pair->first != 0u) {
- CopyAndFixupPointer(reinterpret_cast<void**>(&new_pair->first),
- reinterpret_cast64<void*>(orig_pair->first),
- oat_index);
+ CopyAndFixupPointer(
+ reinterpret_cast<void**>(&new_pair->first), reinterpret_cast64<void*>(orig_pair->first));
}
} else {
DexCache::ConversionPair32* orig_pair =
@@ -2967,26 +2889,22 @@ void ImageWriter::FixupDexCacheArrayEntry(std::atomic<mirror::NativeDexCachePair
reinterpret_cast<DexCache::ConversionPair32*>(new_array) + array_index;
*new_pair = *orig_pair; // Copy original value and index.
if (orig_pair->first != 0u) {
- CopyAndFixupPointer(reinterpret_cast<void**>(&new_pair->first),
- reinterpret_cast32<void*>(orig_pair->first),
- oat_index);
+ CopyAndFixupPointer(
+ reinterpret_cast<void**>(&new_pair->first), reinterpret_cast32<void*>(orig_pair->first));
}
}
}
void ImageWriter::FixupDexCacheArrayEntry(GcRoot<mirror::CallSite>* orig_array,
GcRoot<mirror::CallSite>* new_array,
- uint32_t array_index,
- size_t oat_index) {
- CopyAndFixupReference(new_array[array_index].AddressWithoutBarrier(),
- orig_array[array_index].Read(),
- oat_index);
+ uint32_t array_index) {
+ CopyAndFixupReference(
+ new_array[array_index].AddressWithoutBarrier(), orig_array[array_index].Read());
}
template <typename EntryType>
void ImageWriter::FixupDexCacheArray(DexCache* orig_dex_cache,
DexCache* copy_dex_cache,
- size_t oat_index,
MemberOffset array_offset,
uint32_t size) {
EntryType* orig_array = orig_dex_cache->GetFieldPtr64<EntryType*>(array_offset);
@@ -2994,45 +2912,37 @@ void ImageWriter::FixupDexCacheArray(DexCache* orig_dex_cache,
if (orig_array != nullptr) {
// Though the DexCache array fields are usually treated as native pointers, we clear
// the top 32 bits for 32-bit targets.
- CopyAndFixupPointer(copy_dex_cache, array_offset, orig_array, oat_index, PointerSize::k64);
+ CopyAndFixupPointer(copy_dex_cache, array_offset, orig_array, PointerSize::k64);
EntryType* new_array = NativeCopyLocation(orig_array);
for (uint32_t i = 0; i != size; ++i) {
- FixupDexCacheArrayEntry(orig_array, new_array, i, oat_index);
+ FixupDexCacheArrayEntry(orig_array, new_array, i);
}
}
}
-void ImageWriter::FixupDexCache(DexCache* orig_dex_cache,
- DexCache* copy_dex_cache,
- size_t oat_index) {
+void ImageWriter::FixupDexCache(DexCache* orig_dex_cache, DexCache* copy_dex_cache) {
FixupDexCacheArray<mirror::StringDexCacheType>(orig_dex_cache,
copy_dex_cache,
- oat_index,
DexCache::StringsOffset(),
orig_dex_cache->NumStrings());
FixupDexCacheArray<mirror::TypeDexCacheType>(orig_dex_cache,
copy_dex_cache,
- oat_index,
DexCache::ResolvedTypesOffset(),
orig_dex_cache->NumResolvedTypes());
FixupDexCacheArray<mirror::MethodDexCacheType>(orig_dex_cache,
copy_dex_cache,
- oat_index,
DexCache::ResolvedMethodsOffset(),
orig_dex_cache->NumResolvedMethods());
FixupDexCacheArray<mirror::FieldDexCacheType>(orig_dex_cache,
copy_dex_cache,
- oat_index,
DexCache::ResolvedFieldsOffset(),
orig_dex_cache->NumResolvedFields());
FixupDexCacheArray<mirror::MethodTypeDexCacheType>(orig_dex_cache,
copy_dex_cache,
- oat_index,
DexCache::ResolvedMethodTypesOffset(),
orig_dex_cache->NumResolvedMethodTypes());
FixupDexCacheArray<GcRoot<mirror::CallSite>>(orig_dex_cache,
copy_dex_cache,
- oat_index,
DexCache::ResolvedCallSitesOffset(),
orig_dex_cache->NumResolvedCallSites());
@@ -3141,9 +3051,8 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig,
memcpy(copy, orig, ArtMethod::Size(target_ptr_size_));
- CopyAndFixupReference(copy->GetDeclaringClassAddressWithoutBarrier(),
- orig->GetDeclaringClassUnchecked(),
- oat_index);
+ CopyAndFixupReference(
+ copy->GetDeclaringClassAddressWithoutBarrier(), orig->GetDeclaringClassUnchecked());
// OatWriter replaces the code_ with an offset value. Here we re-adjust to a pointer relative to
// oat_begin_
@@ -3156,7 +3065,7 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig,
if (orig_table != nullptr) {
// Special IMT conflict method, normal IMT conflict method or unimplemented IMT method.
quick_code = GetOatAddress(StubType::kQuickIMTConflictTrampoline);
- CopyAndFixupPointer(copy, ArtMethod::DataOffset(target_ptr_size_), orig_table, oat_index);
+ CopyAndFixupPointer(copy, ArtMethod::DataOffset(target_ptr_size_), orig_table);
} else if (UNLIKELY(orig == runtime->GetResolutionMethod())) {
quick_code = GetOatAddress(StubType::kQuickResolutionTrampoline);
} else {
@@ -3190,9 +3099,6 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig,
// Note this is not the code_ pointer, that is handled above.
copy->SetEntryPointFromJniPtrSize(
GetOatAddress(StubType::kJNIDlsymLookup), target_ptr_size_);
- MemberOffset offset = ArtMethod::EntryPointFromJniOffset(target_ptr_size_);
- const void* dest = reinterpret_cast<const uint8_t*>(copy) + offset.Uint32Value();
- RecordImageRelocation(dest, oat_index, /* app_to_boot_image */ compile_app_image_);
} else {
CHECK(copy->GetDataPtrSize(target_ptr_size_) == nullptr);
}
@@ -3200,9 +3106,6 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig,
}
if (quick_code != nullptr) {
copy->SetEntryPointFromQuickCompiledCodePtrSize(quick_code, target_ptr_size_);
- MemberOffset offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(target_ptr_size_);
- const void* dest = reinterpret_cast<const uint8_t*>(copy) + offset.Uint32Value();
- RecordImageRelocation(dest, oat_index, /* app_to_boot_image */ IsInBootOatFile(quick_code));
}
}
@@ -3366,55 +3269,15 @@ ImageWriter::ImageInfo::ImageInfo()
: intern_table_(new InternTable),
class_table_(new ClassTable) {}
-template <bool kCheckNotNull /* = true */>
-void ImageWriter::RecordImageRelocation(const void* dest,
- size_t oat_index,
- bool app_to_boot_image /* = false */) {
- // Check that we're not recording a relocation for null.
- if (kCheckNotNull) {
- DCHECK(reinterpret_cast<const uint32_t*>(dest)[0] != 0u);
- }
- // Calculate the offset within the image.
- ImageInfo* image_info = &image_infos_[oat_index];
- DCHECK(image_info->image_.HasAddress(dest))
- << "MemMap range " << static_cast<const void*>(image_info->image_.Begin())
- << "-" << static_cast<const void*>(image_info->image_.End())
- << " does not contain " << dest;
- size_t offset = reinterpret_cast<const uint8_t*>(dest) - image_info->image_.Begin();
- ImageHeader* const image_header = reinterpret_cast<ImageHeader*>(image_info->image_.Begin());
- size_t image_end = image_header->GetClassTableSection().End();
- DCHECK_LT(offset, image_end);
- // Calculate the location index.
- size_t size = RelocationIndex(image_end, target_ptr_size_);
- size_t index = RelocationIndex(offset, target_ptr_size_);
- if (app_to_boot_image) {
- index += size;
- }
- // Mark the location in the bitmap.
- DCHECK(compile_app_image_ || !app_to_boot_image);
- MemoryRegion region(image_info->relocation_bitmap_.data(), image_info->relocation_bitmap_.size());
- BitMemoryRegion bit_region(region, /* bit_offset */ 0u, compile_app_image_ ? 2u * size : size);
- DCHECK(!bit_region.LoadBit(index));
- bit_region.StoreBit(index, /* value*/ true);
-}
-
template <typename DestType>
-void ImageWriter::CopyAndFixupReference(DestType* dest,
- ObjPtr<mirror::Object> src,
- size_t oat_index) {
+void ImageWriter::CopyAndFixupReference(DestType* dest, ObjPtr<mirror::Object> src) {
static_assert(std::is_same<DestType, mirror::CompressedReference<mirror::Object>>::value ||
std::is_same<DestType, mirror::HeapReference<mirror::Object>>::value,
"DestType must be a Compressed-/HeapReference<Object>.");
dest->Assign(GetImageAddress(src.Ptr()));
- if (src != nullptr) {
- RecordImageRelocation(dest, oat_index, /* app_to_boot_image */ IsInBootImage(src.Ptr()));
- }
}
-void ImageWriter::CopyAndFixupPointer(void** target,
- void* value,
- size_t oat_index,
- PointerSize pointer_size) {
+void ImageWriter::CopyAndFixupPointer(void** target, void* value, PointerSize pointer_size) {
void* new_value = NativeLocationInImage(value);
if (pointer_size == PointerSize::k32) {
*reinterpret_cast<uint32_t*>(target) = reinterpret_cast32<uint32_t>(new_value);
@@ -3422,24 +3285,22 @@ void ImageWriter::CopyAndFixupPointer(void** target,
*reinterpret_cast<uint64_t*>(target) = reinterpret_cast64<uint64_t>(new_value);
}
DCHECK(value != nullptr);
- RecordImageRelocation(target, oat_index, /* app_to_boot_image */ IsInBootImage(value));
}
-void ImageWriter::CopyAndFixupPointer(void** target, void* value, size_t oat_index)
+void ImageWriter::CopyAndFixupPointer(void** target, void* value)
REQUIRES_SHARED(Locks::mutator_lock_) {
- CopyAndFixupPointer(target, value, oat_index, target_ptr_size_);
+ CopyAndFixupPointer(target, value, target_ptr_size_);
}
void ImageWriter::CopyAndFixupPointer(
- void* object, MemberOffset offset, void* value, size_t oat_index, PointerSize pointer_size) {
+ void* object, MemberOffset offset, void* value, PointerSize pointer_size) {
void** target =
reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(object) + offset.Uint32Value());
- return CopyAndFixupPointer(target, value, oat_index, pointer_size);
+ return CopyAndFixupPointer(target, value, pointer_size);
}
-void ImageWriter::CopyAndFixupPointer(
- void* object, MemberOffset offset, void* value, size_t oat_index) {
- return CopyAndFixupPointer(object, offset, value, oat_index, target_ptr_size_);
+void ImageWriter::CopyAndFixupPointer(void* object, MemberOffset offset, void* value) {
+ return CopyAndFixupPointer(object, offset, value, target_ptr_size_);
}
} // namespace linker
diff --git a/dex2oat/linker/image_writer.h b/dex2oat/linker/image_writer.h
index 93e4be5558..6f43527785 100644
--- a/dex2oat/linker/image_writer.h
+++ b/dex2oat/linker/image_writer.h
@@ -289,7 +289,7 @@ class ImageWriter final {
* Creates ImageSection objects that describe most of the sections of a
* boot or AppImage. The following sections are not included:
* - ImageHeader::kSectionImageBitmap
- * - ImageHeader::kSectionImageRelocations
+ * - ImageHeader::kSectionStringReferenceOffsets
*
* In addition, the ImageHeader is not covered here.
*
@@ -397,12 +397,6 @@ class ImageWriter final {
// Class table associated with this image for serialization.
std::unique_ptr<ClassTable> class_table_;
-
- // Relocations of references/pointers. For boot image, it contains one bit
- // for each location that can be relocated. For app image, it contains twice
- // that many bits, first half contains relocations within this image and the
- // second half contains relocations for references to the boot image.
- std::vector<uint8_t> relocation_bitmap_;
};
// We use the lock word to store the offset of the object in the image.
@@ -496,11 +490,9 @@ class ImageWriter final {
void CopyAndFixupObject(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_);
void CopyAndFixupMethod(ArtMethod* orig, ArtMethod* copy, size_t oat_index)
REQUIRES_SHARED(Locks::mutator_lock_);
- void CopyAndFixupImTable(ImTable* orig, ImTable* copy, size_t oat_index)
+ void CopyAndFixupImTable(ImTable* orig, ImTable* copy)
REQUIRES_SHARED(Locks::mutator_lock_);
- void CopyAndFixupImtConflictTable(ImtConflictTable* orig,
- ImtConflictTable* copy,
- size_t oat_index)
+ void CopyAndFixupImtConflictTable(ImtConflictTable* orig, ImtConflictTable* copy)
REQUIRES_SHARED(Locks::mutator_lock_);
/*
@@ -517,45 +509,37 @@ class ImageWriter final {
*/
void CopyMetadata();
- template <bool kCheckNotNull = true>
- void RecordImageRelocation(const void* dest, size_t oat_index, bool app_to_boot_image = false);
- void FixupClass(mirror::Class* orig, mirror::Class* copy, size_t oat_index)
+ void FixupClass(mirror::Class* orig, mirror::Class* copy)
REQUIRES_SHARED(Locks::mutator_lock_);
- void FixupObject(mirror::Object* orig, mirror::Object* copy, size_t oat_index)
+ void FixupObject(mirror::Object* orig, mirror::Object* copy)
REQUIRES_SHARED(Locks::mutator_lock_);
template <typename T>
void FixupDexCacheArrayEntry(std::atomic<mirror::DexCachePair<T>>* orig_array,
std::atomic<mirror::DexCachePair<T>>* new_array,
- uint32_t array_index,
- size_t oat_index)
+ uint32_t array_index)
REQUIRES_SHARED(Locks::mutator_lock_);
template <typename T>
void FixupDexCacheArrayEntry(std::atomic<mirror::NativeDexCachePair<T>>* orig_array,
std::atomic<mirror::NativeDexCachePair<T>>* new_array,
- uint32_t array_index,
- size_t oat_index)
+ uint32_t array_index)
REQUIRES_SHARED(Locks::mutator_lock_);
void FixupDexCacheArrayEntry(GcRoot<mirror::CallSite>* orig_array,
GcRoot<mirror::CallSite>* new_array,
- uint32_t array_index,
- size_t oat_index)
+ uint32_t array_index)
REQUIRES_SHARED(Locks::mutator_lock_);
template <typename EntryType>
void FixupDexCacheArray(mirror::DexCache* orig_dex_cache,
mirror::DexCache* copy_dex_cache,
- size_t oat_index,
MemberOffset array_offset,
uint32_t size)
REQUIRES_SHARED(Locks::mutator_lock_);
void FixupDexCache(mirror::DexCache* orig_dex_cache,
- mirror::DexCache* copy_dex_cache,
- size_t oat_index)
+ mirror::DexCache* copy_dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
void FixupPointerArray(mirror::Object* dst,
mirror::PointerArray* arr,
mirror::Class* klass,
- Bin array_type,
- size_t oat_index)
+ Bin array_type)
REQUIRES_SHARED(Locks::mutator_lock_);
// Get quick code for non-resolution/imt_conflict/abstract method.
@@ -711,18 +695,18 @@ class ImageWriter final {
// Copy a reference and record image relocation.
template <typename DestType>
- void CopyAndFixupReference(DestType* dest, ObjPtr<mirror::Object> src, size_t oat_index)
+ void CopyAndFixupReference(DestType* dest, ObjPtr<mirror::Object> src)
REQUIRES_SHARED(Locks::mutator_lock_);
// Copy a native pointer and record image relocation.
- void CopyAndFixupPointer(void** target, void* value, size_t oat_index, PointerSize pointer_size)
+ void CopyAndFixupPointer(void** target, void* value, PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
- void CopyAndFixupPointer(void** target, void* value, size_t oat_index)
+ void CopyAndFixupPointer(void** target, void* value)
REQUIRES_SHARED(Locks::mutator_lock_);
void CopyAndFixupPointer(
- void* object, MemberOffset offset, void* value, size_t oat_index, PointerSize pointer_size)
+ void* object, MemberOffset offset, void* value, PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
- void CopyAndFixupPointer(void* object, MemberOffset offset, void* value, size_t oat_index)
+ void CopyAndFixupPointer(void* object, MemberOffset offset, void* value)
REQUIRES_SHARED(Locks::mutator_lock_);
/*
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index acd49d5b45..23c486d05b 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -26,6 +26,7 @@
#include "base/bit_vector-inl.h"
#include "base/enums.h"
#include "base/file_magic.h"
+#include "base/file_utils.h"
#include "base/indenter.h"
#include "base/logging.h" // For VLOG
#include "base/os.h"
@@ -3430,7 +3431,7 @@ bool OatWriter::LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_fil
&error_msg);
} else if (oat_dex_file->source_.IsRawFile()) {
File* raw_file = oat_dex_file->source_.GetRawFile();
- int dup_fd = dup(raw_file->Fd());
+ int dup_fd = DupCloexec(raw_file->Fd());
if (dup_fd < 0) {
PLOG(ERROR) << "Failed to dup dex file descriptor (" << raw_file->Fd() << ") at " << location;
return false;
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index 7382208d51..83fb17cf05 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -19,6 +19,7 @@
#include "arch/instruction_set_features.h"
#include "art_method-inl.h"
#include "base/enums.h"
+#include "base/file_utils.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
@@ -765,7 +766,7 @@ void OatTest::TestZipFileInput(bool verify) {
{
// Test using the AddZipDexFileSource() interface with the zip file handle.
- File zip_fd(dup(zip_file.GetFd()), /*check_usage=*/ false);
+ File zip_fd(DupCloexec(zip_file.GetFd()), /*check_usage=*/ false);
ASSERT_NE(-1, zip_fd.Fd());
ScratchFile tmp_base, tmp_oat(tmp_base, ".oat"), tmp_vdex(tmp_base, ".vdex");
diff --git a/dexlayout/dex_visualize.cc b/dexlayout/dex_visualize.cc
index 4a36744e97..27cec8d951 100644
--- a/dexlayout/dex_visualize.cc
+++ b/dexlayout/dex_visualize.cc
@@ -53,7 +53,7 @@ class Dumper {
bool OpenAndPrintHeader(size_t dex_index) {
// Open the file and emit the gnuplot prologue.
- out_file_ = fopen(MultidexName("layout", dex_index, ".gnuplot").c_str(), "w");
+ out_file_ = fopen(MultidexName("layout", dex_index, ".gnuplot").c_str(), "we");
if (out_file_ == nullptr) {
return false;
}
diff --git a/dexlayout/dexlayout_main.cc b/dexlayout/dexlayout_main.cc
index d212e71f06..41b60da133 100644
--- a/dexlayout/dexlayout_main.cc
+++ b/dexlayout/dexlayout_main.cc
@@ -190,7 +190,7 @@ int DexlayoutDriver(int argc, char** argv) {
// Open profile file.
std::unique_ptr<ProfileCompilationInfo> profile_info;
if (options.profile_file_name_) {
- int profile_fd = open(options.profile_file_name_, O_RDONLY);
+ int profile_fd = open(options.profile_file_name_, O_RDONLY | O_CLOEXEC);
if (profile_fd < 0) {
PLOG(ERROR) << "Can't open " << options.profile_file_name_;
return 1;
diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc
index adb6a54d8a..7d3ae71d5f 100644
--- a/dexlist/dexlist.cc
+++ b/dexlist/dexlist.cc
@@ -257,7 +257,7 @@ int dexlistDriver(int argc, char** argv) {
// Open alternative output file.
if (gOptions.outputFileName) {
- gOutFile = fopen(gOptions.outputFileName, "w");
+ gOutFile = fopen(gOptions.outputFileName, "we");
if (!gOutFile) {
PLOG(ERROR) << "Can't open " << gOptions.outputFileName;
free(gOptions.argCopy);
diff --git a/dt_fd_forward/dt_fd_forward.cc b/dt_fd_forward/dt_fd_forward.cc
index 116cdf84ed..a99f7850c0 100644
--- a/dt_fd_forward/dt_fd_forward.cc
+++ b/dt_fd_forward/dt_fd_forward.cc
@@ -105,12 +105,21 @@ static void SendListenMessage(const android::base::unique_fd& fd) {
TEMP_FAILURE_RETRY(send(fd, kListenStartMessage, sizeof(kListenStartMessage), MSG_EOR));
}
+// Copy from file_utils, so we do not need to depend on libartbase.
+static int DupCloexec(int fd) {
+#if defined(__linux__)
+ return fcntl(fd, F_DUPFD_CLOEXEC, 0);
+#else
+ return dup(fd);
+#endif
+}
+
jdwpTransportError FdForwardTransport::SetupListen(int listen_fd) {
std::lock_guard<std::mutex> lk(state_mutex_);
if (!ChangeState(TransportState::kClosed, TransportState::kListenSetup)) {
return ERR(ILLEGAL_STATE);
} else {
- listen_fd_.reset(dup(listen_fd));
+ listen_fd_.reset(DupCloexec(listen_fd));
SendListenMessage(listen_fd_);
CHECK(ChangeState(TransportState::kListenSetup, TransportState::kListening));
return OK;
@@ -339,7 +348,7 @@ IOResult FdForwardTransport::ReceiveFdsFromSocket(bool* do_handshake) {
write_lock_fd_.reset(out_fds.write_lock_fd_);
// We got the fds. Send ack.
- close_notify_fd_.reset(dup(listen_fd_));
+ close_notify_fd_.reset(DupCloexec(listen_fd_));
SendAcceptMessage(close_notify_fd_);
return IOResult::kOk;
diff --git a/libartbase/base/common_art_test.cc b/libartbase/base/common_art_test.cc
index 9485fcaa0c..987ceb64df 100644
--- a/libartbase/base/common_art_test.cc
+++ b/libartbase/base/common_art_test.cc
@@ -62,7 +62,7 @@ ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
: ScratchFile(other.GetFilename() + suffix) {}
ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
- int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
+ int fd = open(filename_.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0666);
CHECK_NE(-1, fd);
file_.reset(new File(fd, GetFilename(), true));
}
diff --git a/libartbase/base/scoped_flock.cc b/libartbase/base/scoped_flock.cc
index beee501986..2f16fb2820 100644
--- a/libartbase/base/scoped_flock.cc
+++ b/libartbase/base/scoped_flock.cc
@@ -22,6 +22,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include "file_utils.h"
#include "unix_file/fd_file.h"
namespace art {
@@ -98,7 +99,7 @@ ScopedFlock LockedFile::DupOf(const int fd, const std::string& path,
// destructor. Callers should explicitly flush files they're writing to if
// that is the desired behaviour.
ScopedFlock locked_file(
- new LockedFile(dup(fd), path, /* check_usage= */ false, read_only_mode));
+ new LockedFile(DupCloexec(fd), path, /* check_usage= */ false, read_only_mode));
if (locked_file->Fd() == -1) {
*error_msg = StringPrintf("Failed to duplicate open file '%s': %s",
locked_file->GetPath().c_str(), strerror(errno));
diff --git a/libartbase/base/unix_file/fd_file.cc b/libartbase/base/unix_file/fd_file.cc
index de60277432..76894c6a8a 100644
--- a/libartbase/base/unix_file/fd_file.cc
+++ b/libartbase/base/unix_file/fd_file.cc
@@ -431,7 +431,7 @@ bool FdFile::Unlink() {
bool is_current = false;
{
struct stat this_stat, current_stat;
- int cur_fd = TEMP_FAILURE_RETRY(open(file_path_.c_str(), O_RDONLY));
+ int cur_fd = TEMP_FAILURE_RETRY(open(file_path_.c_str(), O_RDONLY | O_CLOEXEC));
if (cur_fd > 0) {
// File still exists.
if (fstat(fd_, &this_stat) == 0 && fstat(cur_fd, &current_stat) == 0) {
diff --git a/libartbase/base/unix_file/fd_file_test.cc b/libartbase/base/unix_file/fd_file_test.cc
index 9c39bb50ec..3a9cf59148 100644
--- a/libartbase/base/unix_file/fd_file_test.cc
+++ b/libartbase/base/unix_file/fd_file_test.cc
@@ -15,6 +15,7 @@
*/
#include "base/common_art_test.h" // For ScratchFile
+#include "base/file_utils.h"
#include "gtest/gtest.h"
#include "fd_file.h"
#include "random_access_file_test.h"
@@ -25,7 +26,7 @@ class FdFileTest : public RandomAccessFileTest {
protected:
RandomAccessFile* MakeTestFile() override {
FILE* tmp = tmpfile();
- int fd = dup(fileno(tmp));
+ int fd = art::DupCloexec(fileno(tmp));
fclose(tmp);
return new FdFile(fd, false);
}
diff --git a/libartbase/base/zip_archive_test.cc b/libartbase/base/zip_archive_test.cc
index b9238811ca..969cf1297c 100644
--- a/libartbase/base/zip_archive_test.cc
+++ b/libartbase/base/zip_archive_test.cc
@@ -23,6 +23,7 @@
#include <memory>
#include "base/common_art_test.h"
+#include "file_utils.h"
#include "os.h"
#include "unix_file/fd_file.h"
@@ -41,7 +42,7 @@ TEST_F(ZipArchiveTest, FindAndExtract) {
ScratchFile tmp;
ASSERT_NE(-1, tmp.GetFd());
- std::unique_ptr<File> file(new File(dup(tmp.GetFd()), tmp.GetFilename(), false));
+ std::unique_ptr<File> file(new File(DupCloexec(tmp.GetFd()), tmp.GetFilename(), false));
ASSERT_TRUE(file.get() != nullptr);
bool success = zip_entry->ExtractToFile(*file, &error_msg);
ASSERT_TRUE(success) << error_msg;
@@ -49,7 +50,7 @@ TEST_F(ZipArchiveTest, FindAndExtract) {
file.reset(nullptr);
uint32_t computed_crc = crc32(0L, Z_NULL, 0);
- int fd = open(tmp.GetFilename().c_str(), O_RDONLY);
+ int fd = open(tmp.GetFilename().c_str(), O_RDONLY | O_CLOEXEC);
ASSERT_NE(-1, fd);
const size_t kBufSize = 32768;
uint8_t buf[kBufSize];
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 467542df61..86a36f292b 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1954,7 +1954,6 @@ class ImageDumper {
const auto& intern_section = image_header_.GetInternedStringsSection();
const auto& class_table_section = image_header_.GetClassTableSection();
const auto& bitmap_section = image_header_.GetImageBitmapSection();
- const auto& relocations_section = image_header_.GetImageRelocationsSection();
stats_.header_bytes = header_bytes;
@@ -1994,11 +1993,7 @@ class ImageDumper {
CHECK_ALIGNED(bitmap_section.Offset(), kPageSize);
stats_.alignment_bytes += RoundUp(bitmap_offset, kPageSize) - bitmap_offset;
- // There should be no space between the bitmap and relocations.
- CHECK_EQ(bitmap_section.Offset() + bitmap_section.Size(), relocations_section.Offset());
-
stats_.bitmap_bytes += bitmap_section.Size();
- stats_.relocations_bytes += relocations_section.Size();
stats_.art_field_bytes += field_section.Size();
stats_.art_method_bytes += method_section.Size();
stats_.dex_cache_arrays_bytes += dex_cache_arrays_section.Size();
@@ -2431,7 +2426,6 @@ class ImageDumper {
size_t interned_strings_bytes;
size_t class_table_bytes;
size_t bitmap_bytes;
- size_t relocations_bytes;
size_t alignment_bytes;
size_t managed_code_bytes;
@@ -2461,7 +2455,6 @@ class ImageDumper {
interned_strings_bytes(0),
class_table_bytes(0),
bitmap_bytes(0),
- relocations_bytes(0),
alignment_bytes(0),
managed_code_bytes(0),
managed_code_bytes_ignoring_deduplication(0),
@@ -2625,7 +2618,6 @@ class ImageDumper {
"interned_string_bytes = %8zd (%2.0f%% of art file bytes)\n"
"class_table_bytes = %8zd (%2.0f%% of art file bytes)\n"
"bitmap_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "relocations_bytes = %8zd (%2.0f%% of art file bytes)\n"
"alignment_bytes = %8zd (%2.0f%% of art file bytes)\n\n",
header_bytes, PercentOfFileBytes(header_bytes),
object_bytes, PercentOfFileBytes(object_bytes),
@@ -2637,13 +2629,12 @@ class ImageDumper {
PercentOfFileBytes(interned_strings_bytes),
class_table_bytes, PercentOfFileBytes(class_table_bytes),
bitmap_bytes, PercentOfFileBytes(bitmap_bytes),
- relocations_bytes, PercentOfFileBytes(relocations_bytes),
alignment_bytes, PercentOfFileBytes(alignment_bytes))
<< std::flush;
CHECK_EQ(file_bytes,
header_bytes + object_bytes + art_field_bytes + art_method_bytes +
dex_cache_arrays_bytes + interned_strings_bytes + class_table_bytes +
- bitmap_bytes + relocations_bytes + alignment_bytes);
+ bitmap_bytes + alignment_bytes);
}
os << "object_bytes breakdown:\n";
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 31dfbc03e7..e9d3290faa 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -1192,7 +1192,7 @@ TEST_F(ProfileAssistantTest, MergeProfilesWithFilter) {
// Run profman and pass the dex file with --apk-fd.
android::base::unique_fd apk_fd(
- open(GetTestDexFileName("ProfileTestMultiDex").c_str(), O_RDONLY));
+ open(GetTestDexFileName("ProfileTestMultiDex").c_str(), O_RDONLY)); // NOLINT
ASSERT_GE(apk_fd.get(), 0);
std::string profman_cmd = GetProfmanCmd();
@@ -1270,7 +1270,7 @@ TEST_F(ProfileAssistantTest, CopyAndUpdateProfileKey) {
// Run profman and pass the dex file with --apk-fd.
android::base::unique_fd apk_fd(
- open(GetTestDexFileName("ProfileTestMultiDex").c_str(), O_RDONLY));
+ open(GetTestDexFileName("ProfileTestMultiDex").c_str(), O_RDONLY)); // NOLINT
ASSERT_GE(apk_fd.get(), 0);
std::string profman_cmd = GetProfmanCmd();
diff --git a/profman/profman.cc b/profman/profman.cc
index d989c8c849..734cdf498e 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -477,7 +477,7 @@ class ProfMan final {
std::unique_ptr<const ProfileCompilationInfo> LoadProfile(const std::string& filename, int fd) {
if (!filename.empty()) {
- fd = open(filename.c_str(), O_RDWR);
+ fd = open(filename.c_str(), O_RDWR | O_CLOEXEC);
if (fd < 0) {
LOG(ERROR) << "Cannot open " << filename << strerror(errno);
return nullptr;
@@ -641,7 +641,7 @@ class ProfMan final {
bool GetClassNamesAndMethods(const std::string& profile_file,
std::vector<std::unique_ptr<const DexFile>>* dex_files,
std::set<std::string>* out_lines) {
- int fd = open(profile_file.c_str(), O_RDONLY);
+ int fd = open(profile_file.c_str(), O_RDONLY | O_CLOEXEC);
if (!FdIsValid(fd)) {
LOG(ERROR) << "Cannot open " << profile_file << strerror(errno);
return false;
@@ -1022,7 +1022,7 @@ class ProfMan final {
int fd = reference_profile_file_fd_;
if (!FdIsValid(fd)) {
CHECK(!reference_profile_file_.empty());
- fd = open(reference_profile_file_.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
+ fd = open(reference_profile_file_.c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
if (fd < 0) {
LOG(ERROR) << "Cannot open " << reference_profile_file_ << strerror(errno);
return kInvalidFd;
@@ -1155,7 +1155,9 @@ class ProfMan final {
}
}
// ShouldGenerateTestProfile confirms !test_profile_.empty().
- int profile_test_fd = open(test_profile_.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
+ int profile_test_fd = open(test_profile_.c_str(),
+ O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
+ 0644);
if (profile_test_fd < 0) {
LOG(ERROR) << "Cannot open " << test_profile_ << strerror(errno);
return -1;
diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc
index 98462512da..e9e983cda2 100644
--- a/runtime/arch/x86/instruction_set_features_x86.cc
+++ b/runtime/arch/x86/instruction_set_features_x86.cc
@@ -35,27 +35,39 @@ static constexpr const char* x86_known_variants[] = {
"atom",
"sandybridge",
"silvermont",
+ "kabylake",
};
static constexpr const char* x86_variants_with_ssse3[] = {
"atom",
"sandybridge",
"silvermont",
+ "kabylake",
};
static constexpr const char* x86_variants_with_sse4_1[] = {
"sandybridge",
"silvermont",
+ "kabylake",
};
static constexpr const char* x86_variants_with_sse4_2[] = {
"sandybridge",
"silvermont",
+ "kabylake",
};
static constexpr const char* x86_variants_with_popcnt[] = {
"sandybridge",
"silvermont",
+ "kabylake",
+};
+static constexpr const char* x86_variants_with_avx[] = {
+ "kabylake",
+};
+
+static constexpr const char* x86_variants_with_avx2[] = {
+ "kabylake",
};
X86FeaturesUniquePtr X86InstructionSetFeatures::Create(bool x86_64,
@@ -93,9 +105,12 @@ X86FeaturesUniquePtr X86InstructionSetFeatures::FromVariant(
bool has_SSE4_2 = FindVariantInArray(x86_variants_with_sse4_2,
arraysize(x86_variants_with_sse4_2),
variant);
- bool has_AVX = false;
- bool has_AVX2 = false;
-
+ bool has_AVX = FindVariantInArray(x86_variants_with_avx,
+ arraysize(x86_variants_with_avx),
+ variant);
+ bool has_AVX2 = FindVariantInArray(x86_variants_with_avx2,
+ arraysize(x86_variants_with_avx2),
+ variant);
bool has_POPCNT = FindVariantInArray(x86_variants_with_popcnt,
arraysize(x86_variants_with_popcnt),
variant);
diff --git a/runtime/arch/x86/instruction_set_features_x86.h b/runtime/arch/x86/instruction_set_features_x86.h
index 6bd626319e..34d908b69a 100644
--- a/runtime/arch/x86/instruction_set_features_x86.h
+++ b/runtime/arch/x86/instruction_set_features_x86.h
@@ -67,6 +67,8 @@ class X86InstructionSetFeatures : public InstructionSetFeatures {
bool HasPopCnt() const { return has_POPCNT_; }
+ bool HasAVX2() const { return has_AVX2_; }
+
protected:
// Parse a string of the form "ssse3" adding these to a new InstructionSetFeatures.
std::unique_ptr<const InstructionSetFeatures>
diff --git a/runtime/arch/x86/instruction_set_features_x86_test.cc b/runtime/arch/x86/instruction_set_features_x86_test.cc
index 33eac0f0a6..cdf15af9b9 100644
--- a/runtime/arch/x86/instruction_set_features_x86_test.cc
+++ b/runtime/arch/x86/instruction_set_features_x86_test.cc
@@ -143,4 +143,40 @@ TEST(X86InstructionSetFeaturesTest, X86FeaturesFromSilvermontVariant) {
EXPECT_FALSE(x86_features->Equals(x86_default_features.get()));
}
+TEST(X86InstructionSetFeaturesTest, X86FeaturesFromKabylakeVariant) {
+ // Build features for a 32-bit kabylake x86 processor.
+ std::string error_msg;
+ std::unique_ptr<const InstructionSetFeatures> x86_features(
+ InstructionSetFeatures::FromVariant(InstructionSet::kX86, "kabylake", &error_msg));
+ ASSERT_TRUE(x86_features.get() != nullptr) << error_msg;
+ EXPECT_EQ(x86_features->GetInstructionSet(), InstructionSet::kX86);
+ EXPECT_TRUE(x86_features->Equals(x86_features.get()));
+ EXPECT_STREQ("ssse3,sse4.1,sse4.2,avx,avx2,popcnt",
+ x86_features->GetFeatureString().c_str());
+ EXPECT_EQ(x86_features->AsBitmap(), 63U);
+
+ // Build features for a 32-bit x86 default processor.
+ std::unique_ptr<const InstructionSetFeatures> x86_default_features(
+ InstructionSetFeatures::FromVariant(InstructionSet::kX86, "default", &error_msg));
+ ASSERT_TRUE(x86_default_features.get() != nullptr) << error_msg;
+ EXPECT_EQ(x86_default_features->GetInstructionSet(), InstructionSet::kX86);
+ EXPECT_TRUE(x86_default_features->Equals(x86_default_features.get()));
+ EXPECT_STREQ("-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ x86_default_features->GetFeatureString().c_str());
+ EXPECT_EQ(x86_default_features->AsBitmap(), 0U);
+
+ // Build features for a 64-bit x86-64 kabylake processor.
+ std::unique_ptr<const InstructionSetFeatures> x86_64_features(
+ InstructionSetFeatures::FromVariant(InstructionSet::kX86_64, "kabylake", &error_msg));
+ ASSERT_TRUE(x86_64_features.get() != nullptr) << error_msg;
+ EXPECT_EQ(x86_64_features->GetInstructionSet(), InstructionSet::kX86_64);
+ EXPECT_TRUE(x86_64_features->Equals(x86_64_features.get()));
+ EXPECT_STREQ("ssse3,sse4.1,sse4.2,avx,avx2,popcnt",
+ x86_64_features->GetFeatureString().c_str());
+ EXPECT_EQ(x86_64_features->AsBitmap(), 63U);
+
+ EXPECT_FALSE(x86_64_features->Equals(x86_features.get()));
+ EXPECT_FALSE(x86_64_features->Equals(x86_default_features.get()));
+ EXPECT_FALSE(x86_features->Equals(x86_default_features.get()));
+ }
} // namespace art
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 6e6023d68c..9e679573bd 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -509,21 +509,11 @@ class ImageSpace::Loader {
const size_t image_bitmap_offset = RoundUp(sizeof(ImageHeader) + image_header->GetDataSize(),
kPageSize);
const size_t end_of_bitmap = image_bitmap_offset + bitmap_section.Size();
- const ImageSection& relocations_section = image_header->GetImageRelocationsSection();
- if (relocations_section.Offset() != bitmap_section.Offset() + bitmap_section.Size()) {
+ if (end_of_bitmap != image_file_size) {
*error_msg = StringPrintf(
- "Relocations do not start immediately after bitmap: %u vs. %u + %u.",
- relocations_section.Offset(),
- bitmap_section.Offset(),
- bitmap_section.Size());
- return nullptr;
- }
- const size_t end_of_relocations = end_of_bitmap + relocations_section.Size();
- if (end_of_relocations != image_file_size) {
- *error_msg = StringPrintf(
- "Image file size does not equal end of relocations: size=%" PRIu64 " vs. %zu.",
+ "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.",
image_file_size,
- end_of_relocations);
+ end_of_bitmap);
return nullptr;
}
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 438af12beb..832bacbb3d 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -41,6 +41,7 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/array_ref.h"
+#include "base/file_utils.h"
#include "base/globals.h"
#include "base/macros.h"
#include "base/mutex.h"
@@ -761,13 +762,13 @@ class Hprof : public SingleRootVisitor {
// Where exactly are we writing to?
int out_fd;
if (fd_ >= 0) {
- out_fd = dup(fd_);
+ out_fd = DupCloexec(fd_);
if (out_fd < 0) {
ThrowRuntimeException("Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno));
return false;
}
} else {
- out_fd = open(filename_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ out_fd = open(filename_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (out_fd < 0) {
ThrowRuntimeException("Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(),
strerror(errno));
diff --git a/runtime/image.cc b/runtime/image.cc
index a4351d021b..e7f44864b2 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -26,7 +26,7 @@
namespace art {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '6', '4', '\0' }; // Remove PIC flags.
+const uint8_t ImageHeader::kImageVersion[] = { '0', '6', '5', '\0' }; // Remove relocation section.
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_size,
diff --git a/runtime/image.h b/runtime/image.h
index bd8bc28e0c..0496650cc6 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -237,7 +237,6 @@ class PACKED(4) ImageHeader {
kSectionClassTable,
kSectionStringReferenceOffsets,
kSectionImageBitmap,
- kSectionImageRelocations,
kSectionCount, // Number of elements in enum.
};
@@ -294,10 +293,6 @@ class PACKED(4) ImageHeader {
return GetImageSection(kSectionImageBitmap);
}
- const ImageSection& GetImageRelocationsSection() const {
- return GetImageSection(kSectionImageRelocations);
- }
-
const ImageSection& GetImageStringReferenceOffsetsSection() const {
return GetImageSection(kSectionStringReferenceOffsets);
}
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc
index 74623dab31..19e1f3d2c4 100644
--- a/runtime/monitor_android.cc
+++ b/runtime/monitor_android.cc
@@ -43,7 +43,7 @@ void Monitor::LogContentionEvent(Thread* self,
// Emit the process name, <= 37 bytes.
{
- int fd = open("/proc/self/cmdline", O_RDONLY);
+ int fd = open("/proc/self/cmdline", O_RDONLY | O_CLOEXEC);
char procName[33];
memset(procName, 0, sizeof(procName));
read(fd, procName, sizeof(procName) - 1);
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 6f98a6d381..96f15ded2a 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -23,6 +23,7 @@
#include "nativehelper/jni_macros.h"
+#include "base/file_utils.h"
#include "base/histogram-inl.h"
#include "base/time_utils.h"
#include "class_linker.h"
@@ -113,7 +114,7 @@ static void VMDebug_startMethodTracingFd(JNIEnv* env,
return;
}
- int fd = dup(originalFd);
+ int fd = DupCloexec(originalFd);
if (fd < 0) {
ScopedObjectAccess soa(env);
soa.Self()->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 3a974df386..aba2eaeb69 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -338,9 +338,9 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithFd) {
CompilerFilter::kSpeed,
/* with_alternate_image */ false);
- android::base::unique_fd odex_fd(open(odex_location.c_str(), O_RDONLY));
- android::base::unique_fd vdex_fd(open(vdex_location.c_str(), O_RDONLY));
- android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY));
+ android::base::unique_fd odex_fd(open(odex_location.c_str(), O_RDONLY | O_CLOEXEC));
+ android::base::unique_fd vdex_fd(open(vdex_location.c_str(), O_RDONLY | O_CLOEXEC));
+ android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
OatFileAssistant oat_file_assistant(dex_location.c_str(),
kRuntimeISA,
@@ -377,8 +377,8 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexFd) {
CompilerFilter::kSpeed,
/* with_alternate_image */ false);
- android::base::unique_fd vdex_fd(open(vdex_location.c_str(), O_RDONLY));
- android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY));
+ android::base::unique_fd vdex_fd(open(vdex_location.c_str(), O_RDONLY | O_CLOEXEC));
+ android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
OatFileAssistant oat_file_assistant(dex_location.c_str(),
kRuntimeISA,
@@ -410,8 +410,8 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidVdexFd) {
CompilerFilter::kSpeed,
/* with_alternate_image */ false);
- android::base::unique_fd odex_fd(open(odex_location.c_str(), O_RDONLY));
- android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY));
+ android::base::unique_fd odex_fd(open(odex_location.c_str(), O_RDONLY | O_CLOEXEC));
+ android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
OatFileAssistant oat_file_assistant(dex_location.c_str(),
kRuntimeISA,
@@ -436,7 +436,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexVdexFd) {
Copy(GetDexSrc1(), dex_location);
- android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY));
+ android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
OatFileAssistant oat_file_assistant(dex_location.c_str(),
kRuntimeISA,
false,