diff options
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 = §ions[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, ¤t_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, |