image_test.cc revision e401d146407d61eeb99f8d6176b2ac13c4df1e33
1d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase/*
2d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Copyright (C) 2011 The Android Open Source Project
3d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase *
4d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Licensed under the Apache License, Version 2.0 (the "License");
5d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * you may not use this file except in compliance with the License.
6d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * You may obtain a copy of the License at
7d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase *
8d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase *      http://www.apache.org/licenses/LICENSE-2.0
9d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase *
10d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Unless required by applicable law or agreed to in writing, software
11d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * distributed under the License is distributed on an "AS IS" BASIS,
12d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * See the License for the specific language governing permissions and
14d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * limitations under the License.
15d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */
16d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase
17d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "image.h"
18d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase
192bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar#include <memory>
20c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar#include <string>
218ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar#include <vector>
22e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar
23d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "base/unix_file/fd_file.h"
24d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "class_linker-inl.h"
25d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "common_compiler_test.h"
26d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "elf_writer.h"
27310e95e1c6dfe4f26ef594233e65e1ff83e0f1ffYigit Boyar#include "gc/space/image_space.h"
28d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "image_writer.h"
29d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "lock_word.h"
302bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar#include "mirror/object-inl.h"
312bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar#include "oat_writer.h"
32d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "scoped_thread_state_change.h"
3390ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar#include "signal_catcher.h"
34d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase#include "utils.h"
3590ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar#include "vector_output_stream.h"
36d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase
37d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haasenamespace art {
3811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar
39da50fde358bd3ef2edb273b3bf0265cf5e84ec6bYigit Boyarclass ImageTest : public CommonCompilerTest {
40da50fde358bd3ef2edb273b3bf0265cf5e84ec6bYigit Boyar protected:
41d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase  virtual void SetUp() {
42d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase    ReserveImageSpace();
43d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase    CommonCompilerTest::SetUp();
44d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase  }
45d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase};
46d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase
47b5f8b4fecb531aee6b359b4968409410aba90817Yigit BoyarTEST_F(ImageTest, WriteRead) {
48b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  // Create a generic location tmp file, to be the base of the .art and .oat temporary files.
49b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  ScratchFile location;
50d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase  ScratchFile image_location(location, ".art");
518ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
528ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  std::string image_filename(GetSystemImageFilename(image_location.GetFilename().c_str(),
537e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar                                                    kRuntimeISA));
547e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  size_t pos = image_filename.rfind('/');
55d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase  CHECK_NE(pos, std::string::npos) << image_filename;
56b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  std::string image_dir(image_filename, 0, pos);
57b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  int mkdir_result = mkdir(image_dir.c_str(), 0700);
58b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  CHECK_EQ(0, mkdir_result) << image_dir;
59b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  ScratchFile image_file(OS::CreateEmptyFile(image_filename.c_str()));
608ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
61b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  std::string oat_filename(image_filename, 0, image_filename.size() - 3);
62b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  oat_filename += "oat";
63b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  ScratchFile oat_file(OS::CreateEmptyFile(oat_filename.c_str()));
647e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar
657e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  const uintptr_t requested_image_base = ART_BASE_ADDRESS;
667e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  std::unique_ptr<ImageWriter> writer(new ImageWriter(*compiler_driver_, requested_image_base,
677e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar                                                      /*compile_pic*/false));
687e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  // TODO: compile_pic should be a test argument.
697e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  {
70e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar    {
71e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      jobject class_loader = nullptr;
72e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
73e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      TimingLogger timings("ImageTest::WriteRead", false, false);
74e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      TimingLogger::ScopedTiming t("CompileAll", &timings);
75e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      for (const DexFile* dex_file : class_linker->GetBootClassPath()) {
76e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar        dex_file->EnableWrite();
77e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      }
78e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings);
79e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar
80e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      t.NewTiming("WriteElf");
81e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      SafeMap<std::string, std::string> key_value_store;
82e2437126f0225135891544315ff72e54c7de0f59Yigit Boyar      OatWriter oat_writer(class_linker->GetBootClassPath(), 0, 0, 0, compiler_driver_.get(),
832bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar                           writer.get(), &timings, &key_value_store);
842bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar      bool success = writer->PrepareImageAddressSpace() &&
852bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar          compiler_driver_->WriteElf(GetTestAndroidRoot(),
862bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar                                     !kIsTargetBuild,
872bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar                                     class_linker->GetBootClassPath(),
882bf89a9bae2b6110a77cf0b3754b567bb07d12a5Yigit Boyar                                     &oat_writer,
890b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar                                     oat_file.GetFile());
900b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar      ASSERT_TRUE(success);
910b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    }
920b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar  }
930b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar  // Workound bug that mcld::Linker::emit closes oat_file by reopening as dup_oat.
940b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar  std::unique_ptr<File> dup_oat(OS::OpenFileReadWrite(oat_file.GetFilename().c_str()));
950b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar  ASSERT_TRUE(dup_oat.get() != nullptr);
960b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar
970b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar  {
980b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    bool success_image =
990b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar        writer->Write(image_file.GetFilename(), dup_oat->GetPath(), dup_oat->GetPath());
1000b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    ASSERT_TRUE(success_image);
1010b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    bool success_fixup = ElfWriter::Fixup(dup_oat.get(), writer->GetOatDataBegin());
1020b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    ASSERT_TRUE(success_fixup);
103824a7db96feacf3b68f56993ed72712bc935153eYigit Boyar
104824a7db96feacf3b68f56993ed72712bc935153eYigit Boyar    ASSERT_EQ(dup_oat->FlushCloseOrErase(), 0) << "Could not flush and close oat file "
105824a7db96feacf3b68f56993ed72712bc935153eYigit Boyar                                               << oat_file.GetFilename();
106824a7db96feacf3b68f56993ed72712bc935153eYigit Boyar  }
107824a7db96feacf3b68f56993ed72712bc935153eYigit Boyar
1080b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar  {
1090b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    std::unique_ptr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str()));
110824a7db96feacf3b68f56993ed72712bc935153eYigit Boyar    ASSERT_TRUE(file.get() != nullptr);
1110b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    ImageHeader image_header;
1120b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    ASSERT_EQ(file->ReadFully(&image_header, sizeof(image_header)), true);
1137e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar    ASSERT_TRUE(image_header.IsValid());
1146e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar    const auto& bitmap_section = image_header.GetImageSection(ImageHeader::kSectionImageBitmap);
1156e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar    ASSERT_GE(bitmap_section.Offset(), sizeof(image_header));
1166e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar    ASSERT_NE(0U, bitmap_section.Size());
11790ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar
1186e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar    gc::Heap* heap = Runtime::Current()->GetHeap();
1196e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar    ASSERT_TRUE(!heap->GetContinuousSpaces().empty());
1206e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar    gc::space::ContinuousSpace* space = heap->GetNonMovingSpace();
1217e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar    ASSERT_FALSE(space->IsImageSpace());
1227e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar    ASSERT_TRUE(space != nullptr);
1237e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar    ASSERT_TRUE(space->IsMallocSpace());
1247e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar    ASSERT_LE(space->Size(), static_cast<size_t>(file->GetLength()));
1257e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  }
1267e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar
1277e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  ASSERT_TRUE(compiler_driver_->GetImageClasses() != nullptr);
1287e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  std::unordered_set<std::string> image_classes(*compiler_driver_->GetImageClasses());
1297e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar
1307e9da1a2629b657d56e2f54abd18c6249f3be037Yigit Boyar  // Need to delete the compiler since it has worker threads which are attached to runtime.
1318ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  compiler_driver_.reset();
1328ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1338ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  // Tear down old runtime before making a new one, clearing out misc state.
1348ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1358ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  // Remove the reservation of the memory for use to load the image.
1368ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  // Need to do this before we reset the runtime.
1378ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  UnreserveImageSpace();
1388ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  writer.reset(nullptr);
1398ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1408ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  runtime_.reset();
141ca9ce7ccdccf6b6a2a81da73dd1e6425d90e4b23Yigit Boyar  java_lang_dex_file_ = nullptr;
142ca9ce7ccdccf6b6a2a81da73dd1e6425d90e4b23Yigit Boyar
1436e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar  MemMap::Init();
1446e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar  std::unique_ptr<const DexFile> dex(LoadExpectSingleDexFile(GetLibCoreDexFileName().c_str()));
1456e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar
1466e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar  RuntimeOptions options;
1476e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar  std::string image("-Ximage:");
148ca9ce7ccdccf6b6a2a81da73dd1e6425d90e4b23Yigit Boyar  image.append(image_location.GetFilename());
1496e83751247c5be0211d7bffaf057431c03dfef38Yigit Boyar  options.push_back(std::make_pair(image.c_str(), static_cast<void*>(nullptr)));
1508ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  // By default the compiler this creates will not include patch information.
1518ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar  options.push_back(std::make_pair("-Xnorelocate", nullptr));
152c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar
153c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar  if (!Runtime::Create(options, false)) {
154c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar    LOG(FATAL) << "Failed to create runtime";
155c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar    return;
156c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar  }
157c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar  runtime_.reset(Runtime::Current());
158c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
159c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar  // give it away now and then switch to a more managable ScopedObjectAccess.
160c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
161b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  ScopedObjectAccess soa(Thread::Current());
162d7e2f2ab1d253133fa54f309e74a7ee384c33971Yigit Boyar  ASSERT_TRUE(runtime_.get() != nullptr);
163d7e2f2ab1d253133fa54f309e74a7ee384c33971Yigit Boyar  class_linker_ = runtime_->GetClassLinker();
164d7e2f2ab1d253133fa54f309e74a7ee384c33971Yigit Boyar
16590ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar  gc::Heap* heap = Runtime::Current()->GetHeap();
16690ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar  ASSERT_TRUE(heap->HasImageSpace());
16790ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar  ASSERT_TRUE(heap->GetNonMovingSpace()->IsMallocSpace());
168b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar
169b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  gc::space::ImageSpace* image_space = heap->GetImageSpace();
170b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar  image_space->VerifyImageAllocations();
171abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar  uint8_t* image_begin = image_space->Begin();
172abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar  uint8_t* image_end = image_space->End();
173abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar  CHECK_EQ(requested_image_base, reinterpret_cast<uintptr_t>(image_begin));
174abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar  for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
175abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar    const DexFile::ClassDef& class_def = dex->GetClassDef(i);
176abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar    const char* descriptor = dex->GetClassDescriptor(class_def);
177abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar    mirror::Class* klass = class_linker_->FindSystemClass(soa.Self(), descriptor);
178abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar    EXPECT_TRUE(klass != nullptr) << descriptor;
179abd0fbfcdd5b438909f126392eca5978b5939b6dYigit Boyar    if (image_classes.find(descriptor) != image_classes.end()) {
18090ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar      // Image classes should be located inside the image.
181b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar      EXPECT_LT(image_begin, reinterpret_cast<uint8_t*>(klass)) << descriptor;
182b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar      EXPECT_LT(reinterpret_cast<uint8_t*>(klass), image_end) << descriptor;
18390ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar    } else {
184b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar      EXPECT_TRUE(reinterpret_cast<uint8_t*>(klass) >= image_end ||
185b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar                  reinterpret_cast<uint8_t*>(klass) < image_begin) << descriptor;
186504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar    }
187504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar    EXPECT_TRUE(Monitor::IsValidLockWord(klass->GetLockWord(false)));
188504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar  }
189504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar
190504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar  image_file.Unlink();
191504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar  oat_file.Unlink();
192504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar  int rmdir_result = rmdir(image_dir.c_str());
193504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar  CHECK_EQ(0, rmdir_result);
194504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar}
195504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar
196504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit BoyarTEST_F(ImageTest, ImageHeaderIsValid) {
197504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar    uint32_t image_begin = ART_BASE_ADDRESS;
198504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar    uint32_t image_size_ = 16 * KB;
199504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar    uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB);
200542f1260934df280985294eaef1ec8469863281fYigit Boyar    uint32_t oat_checksum = 0;
201542f1260934df280985294eaef1ec8469863281fYigit Boyar    uint32_t oat_file_begin = ART_BASE_ADDRESS + (4 * KB);  // page aligned
202542f1260934df280985294eaef1ec8469863281fYigit Boyar    uint32_t oat_data_begin = ART_BASE_ADDRESS + (8 * KB);  // page aligned
203542f1260934df280985294eaef1ec8469863281fYigit Boyar    uint32_t oat_data_end = ART_BASE_ADDRESS + (9 * KB);
204542f1260934df280985294eaef1ec8469863281fYigit Boyar    uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB);
205542f1260934df280985294eaef1ec8469863281fYigit Boyar    ImageSection sections[ImageHeader::kSectionCount];
206542f1260934df280985294eaef1ec8469863281fYigit Boyar    ImageHeader image_header(image_begin,
207542f1260934df280985294eaef1ec8469863281fYigit Boyar                             image_size_,
208542f1260934df280985294eaef1ec8469863281fYigit Boyar                             sections,
209542f1260934df280985294eaef1ec8469863281fYigit Boyar                             image_roots,
210542f1260934df280985294eaef1ec8469863281fYigit Boyar                             oat_checksum,
211b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar                             oat_file_begin,
2120b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar                             oat_data_begin,
2130b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar                             oat_data_end,
2140b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar                             oat_file_end,
2150b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar                             sizeof(void*),
216e37d2e63f16bc5c2938e372238ba54679a9e578eYigit Boyar                             /*compile_pic*/false);
217e37d2e63f16bc5c2938e372238ba54679a9e578eYigit Boyar    ASSERT_TRUE(image_header.IsValid());
218e37d2e63f16bc5c2938e372238ba54679a9e578eYigit Boyar
219e37d2e63f16bc5c2938e372238ba54679a9e578eYigit Boyar    char* magic = const_cast<char*>(image_header.GetMagic());
220e37d2e63f16bc5c2938e372238ba54679a9e578eYigit Boyar    strcpy(magic, "");  // bad magic
221b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar    ASSERT_FALSE(image_header.IsValid());
2220b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    strcpy(magic, "art\n000");  // bad version
2230b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar    ASSERT_FALSE(image_header.IsValid());
2240b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar}
2250b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar
2260b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar}  // namespace art
2270b1059b711009601ff08354e2df6bfc45266e80aYigit Boyar