image_test.cc revision e401d146407d61eeb99f8d6176b2ac13c4df1e33
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
17a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "image.h"
18a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
19700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory>
200cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers#include <string>
210cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers#include <vector>
220cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
23e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/unix_file/fd_file.h"
243481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h"
25a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h"
2662d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen#include "elf_writer.h"
2751c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom#include "gc/space/image_space.h"
28e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "image_writer.h"
29d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word.h"
30d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "mirror/object-inl.h"
31e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "oat_writer.h"
32e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
3342ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes#include "signal_catcher.h"
34c143c55718342519db5398e41dda31422cf16c79buzbee#include "utils.h"
35700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "vector_output_stream.h"
36db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
37db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromnamespace art {
38db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
39a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass ImageTest : public CommonCompilerTest {
4010c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers protected:
4110c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers  virtual void SetUp() {
42700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    ReserveImageSpace();
43a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::SetUp();
4410c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers  }
4510c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers};
46db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
479cff8e13d41825c4f3f0127af061e94b06114fc8Brian CarlstromTEST_F(ImageTest, WriteRead) {
480e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  // Create a generic location tmp file, to be the base of the .art and .oat temporary files.
490e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  ScratchFile location;
500e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  ScratchFile image_location(location, ".art");
510e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom
520e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  std::string image_filename(GetSystemImageFilename(image_location.GetFilename().c_str(),
530e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom                                                    kRuntimeISA));
540e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  size_t pos = image_filename.rfind('/');
550e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  CHECK_NE(pos, std::string::npos) << image_filename;
560e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  std::string image_dir(image_filename, 0, pos);
570e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  int mkdir_result = mkdir(image_dir.c_str(), 0700);
580e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  CHECK_EQ(0, mkdir_result) << image_dir;
590e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  ScratchFile image_file(OS::CreateEmptyFile(image_filename.c_str()));
600e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom
610e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  std::string oat_filename(image_filename, 0, image_filename.size() - 3);
620e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  oat_filename += "oat";
630e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  ScratchFile oat_file(OS::CreateEmptyFile(oat_filename.c_str()));
640e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom
65f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko  const uintptr_t requested_image_base = ART_BASE_ADDRESS;
6646774767fcf7780d1455e755729198648d08742eIgor Murashkin  std::unique_ptr<ImageWriter> writer(new ImageWriter(*compiler_driver_, requested_image_base,
6746774767fcf7780d1455e755729198648d08742eIgor Murashkin                                                      /*compile_pic*/false));
6846774767fcf7780d1455e755729198648d08742eIgor Murashkin  // TODO: compile_pic should be a test argument.
6900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  {
70700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    {
712cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      jobject class_loader = nullptr;
7296391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
735fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers      TimingLogger timings("ImageTest::WriteRead", false, false);
74f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier      TimingLogger::ScopedTiming t("CompileAll", &timings);
755f67532efa0622ccfbbb4edf7d12098b26c19b35Brian Carlstrom      for (const DexFile* dex_file : class_linker->GetBootClassPath()) {
765f67532efa0622ccfbbb4edf7d12098b26c19b35Brian Carlstrom        dex_file->EnableWrite();
775f67532efa0622ccfbbb4edf7d12098b26c19b35Brian Carlstrom      }
783d504075f7c1204d581923460754bf6d3714b13fIan Rogers      compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings);
7996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom
80f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier      t.NewTiming("WriteElf");
8122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      SafeMap<std::string, std::string> key_value_store;
82f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko      OatWriter oat_writer(class_linker->GetBootClassPath(), 0, 0, 0, compiler_driver_.get(),
836e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier                           writer.get(), &timings, &key_value_store);
846e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier      bool success = writer->PrepareImageAddressSpace() &&
85f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko          compiler_driver_->WriteElf(GetTestAndroidRoot(),
86f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko                                     !kIsTargetBuild,
87f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko                                     class_linker->GetBootClassPath(),
88f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko                                     &oat_writer,
89f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko                                     oat_file.GetFile());
90c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom      ASSERT_TRUE(success);
9100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
930e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  // Workound bug that mcld::Linker::emit closes oat_file by reopening as dup_oat.
94700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<File> dup_oat(OS::OpenFileReadWrite(oat_file.GetFilename().c_str()));
952cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  ASSERT_TRUE(dup_oat.get() != nullptr);
96357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
978161c0336b97e11e02c000af357f8f40de2e23e4jeffhao  {
98f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko    bool success_image =
996e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier        writer->Write(image_file.GetFilename(), dup_oat->GetPath(), dup_oat->GetPath());
1008161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    ASSERT_TRUE(success_image);
1016e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier    bool success_fixup = ElfWriter::Fixup(dup_oat.get(), writer->GetOatDataBegin());
102700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    ASSERT_TRUE(success_fixup);
1034303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
1044303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    ASSERT_EQ(dup_oat->FlushCloseOrErase(), 0) << "Could not flush and close oat file "
1054303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe                                               << oat_file.GetFilename();
1068161c0336b97e11e02c000af357f8f40de2e23e4jeffhao  }
1074a289ed61242964b921434de7d375f46480472a1Brian Carlstrom
1084a289ed61242964b921434de7d375f46480472a1Brian Carlstrom  {
109700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str()));
1102cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(file.get() != nullptr);
1114a289ed61242964b921434de7d375f46480472a1Brian Carlstrom    ImageHeader image_header;
1124303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    ASSERT_EQ(file->ReadFully(&image_header, sizeof(image_header)), true);
1134a289ed61242964b921434de7d375f46480472a1Brian Carlstrom    ASSERT_TRUE(image_header.IsValid());
114e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    const auto& bitmap_section = image_header.GetImageSection(ImageHeader::kSectionImageBitmap);
115e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    ASSERT_GE(bitmap_section.Offset(), sizeof(image_header));
116e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    ASSERT_NE(0U, bitmap_section.Size());
11769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1181d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    gc::Heap* heap = Runtime::Current()->GetHeap();
119590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    ASSERT_TRUE(!heap->GetContinuousSpaces().empty());
120590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    gc::space::ContinuousSpace* space = heap->GetNonMovingSpace();
1213320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    ASSERT_FALSE(space->IsImageSpace());
1222cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(space != nullptr);
123cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    ASSERT_TRUE(space->IsMallocSpace());
124e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    ASSERT_LE(space->Size(), static_cast<size_t>(file->GetLength()));
1254a289ed61242964b921434de7d375f46480472a1Brian Carlstrom  }
1268a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom
1272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  ASSERT_TRUE(compiler_driver_->GetImageClasses() != nullptr);
128b1fceadbd42b3047a9c06a8af6239c737d67344eAndreas Gampe  std::unordered_set<std::string> image_classes(*compiler_driver_->GetImageClasses());
12996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom
1300e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  // Need to delete the compiler since it has worker threads which are attached to runtime.
1311212a022fa5f8ef9585d765b1809521812af882cIan Rogers  compiler_driver_.reset();
1320e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier
13310c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers  // Tear down old runtime before making a new one, clearing out misc state.
1346e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier
1356e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier  // Remove the reservation of the memory for use to load the image.
1366e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier  // Need to do this before we reset the runtime.
1376e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier  UnreserveImageSpace();
1386e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier  writer.reset(nullptr);
1396e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier
14010c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers  runtime_.reset();
1412cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  java_lang_dex_file_ = nullptr;
1429cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom
1436e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier  MemMap::Init();
144833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  std::unique_ptr<const DexFile> dex(LoadExpectSingleDexFile(GetLibCoreDexFileName().c_str()));
1458a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom
146e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions options;
14758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  std::string image("-Ximage:");
1480e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  image.append(image_location.GetFilename());
1492cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  options.push_back(std::make_pair(image.c_str(), static_cast<void*>(nullptr)));
1506e183f2e973a20f2eaca135c240908e1bf98c5d0Alex Light  // By default the compiler this creates will not include patch information.
1516e183f2e973a20f2eaca135c240908e1bf98c5d0Alex Light  options.push_back(std::make_pair("-Xnorelocate", nullptr));
1528a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom
15300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!Runtime::Create(options, false)) {
15400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(FATAL) << "Failed to create runtime";
15500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return;
15600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  runtime_.reset(Runtime::Current());
15800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
15900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // give it away now and then switch to a more managable ScopedObjectAccess.
16000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
16100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
1622cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  ASSERT_TRUE(runtime_.get() != nullptr);
1638a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom  class_linker_ = runtime_->GetClassLinker();
1649cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom
1651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  gc::Heap* heap = Runtime::Current()->GetHeap();
166590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  ASSERT_TRUE(heap->HasImageSpace());
167cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  ASSERT_TRUE(heap->GetNonMovingSpace()->IsMallocSpace());
168a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
1691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  gc::space::ImageSpace* image_space = heap->GetImageSpace();
17031e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  image_space->VerifyImageAllocations();
17113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* image_begin = image_space->Begin();
17213735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* image_end = image_space->End();
17330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers  CHECK_EQ(requested_image_base, reinterpret_cast<uintptr_t>(image_begin));
174b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
175d2fbb2bd2448f0872878258727aa1eb2558a0c3bBrian Carlstrom    const DexFile::ClassDef& class_def = dex->GetClassDef(i);
1769cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom    const char* descriptor = dex->GetClassDescriptor(class_def);
1779837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers    mirror::Class* klass = class_linker_->FindSystemClass(soa.Self(), descriptor);
178c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    EXPECT_TRUE(klass != nullptr) << descriptor;
17996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom    if (image_classes.find(descriptor) != image_classes.end()) {
180c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      // Image classes should be located inside the image.
18113735955f39b3b304c37d2b2840663c131262c18Ian Rogers      EXPECT_LT(image_begin, reinterpret_cast<uint8_t*>(klass)) << descriptor;
18213735955f39b3b304c37d2b2840663c131262c18Ian Rogers      EXPECT_LT(reinterpret_cast<uint8_t*>(klass), image_end) << descriptor;
18396391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom    } else {
18413735955f39b3b304c37d2b2840663c131262c18Ian Rogers      EXPECT_TRUE(reinterpret_cast<uint8_t*>(klass) >= image_end ||
18513735955f39b3b304c37d2b2840663c131262c18Ian Rogers                  reinterpret_cast<uint8_t*>(klass) < image_begin) << descriptor;
18696391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom    }
1874d7f61d44a732cfbc8573e5d93364983fd746888Mathieu Chartier    EXPECT_TRUE(Monitor::IsValidLockWord(klass->GetLockWord(false)));
1889cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  }
1890e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom
1900e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  image_file.Unlink();
1910e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  oat_file.Unlink();
1920e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  int rmdir_result = rmdir(image_dir.c_str());
1930e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom  CHECK_EQ(0, rmdir_result);
194db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom}
195db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
196179486aee731f734207873244542993ed4bcff21Brian CarlstromTEST_F(ImageTest, ImageHeaderIsValid) {
197179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t image_begin = ART_BASE_ADDRESS;
198179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t image_size_ = 16 * KB;
199179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB);
200179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t oat_checksum = 0;
201179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t oat_file_begin = ART_BASE_ADDRESS + (4 * KB);  // page aligned
202179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t oat_data_begin = ART_BASE_ADDRESS + (8 * KB);  // page aligned
203179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t oat_data_end = ART_BASE_ADDRESS + (9 * KB);
204179486aee731f734207873244542993ed4bcff21Brian Carlstrom    uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB);
205e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    ImageSection sections[ImageHeader::kSectionCount];
206179486aee731f734207873244542993ed4bcff21Brian Carlstrom    ImageHeader image_header(image_begin,
207179486aee731f734207873244542993ed4bcff21Brian Carlstrom                             image_size_,
208e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                             sections,
209179486aee731f734207873244542993ed4bcff21Brian Carlstrom                             image_roots,
210179486aee731f734207873244542993ed4bcff21Brian Carlstrom                             oat_checksum,
211179486aee731f734207873244542993ed4bcff21Brian Carlstrom                             oat_file_begin,
212179486aee731f734207873244542993ed4bcff21Brian Carlstrom                             oat_data_begin,
213179486aee731f734207873244542993ed4bcff21Brian Carlstrom                             oat_data_end,
21446774767fcf7780d1455e755729198648d08742eIgor Murashkin                             oat_file_end,
215e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                             sizeof(void*),
21646774767fcf7780d1455e755729198648d08742eIgor Murashkin                             /*compile_pic*/false);
217179486aee731f734207873244542993ed4bcff21Brian Carlstrom    ASSERT_TRUE(image_header.IsValid());
218179486aee731f734207873244542993ed4bcff21Brian Carlstrom
219179486aee731f734207873244542993ed4bcff21Brian Carlstrom    char* magic = const_cast<char*>(image_header.GetMagic());
220179486aee731f734207873244542993ed4bcff21Brian Carlstrom    strcpy(magic, "");  // bad magic
221179486aee731f734207873244542993ed4bcff21Brian Carlstrom    ASSERT_FALSE(image_header.IsValid());
222179486aee731f734207873244542993ed4bcff21Brian Carlstrom    strcpy(magic, "art\n000");  // bad version
223179486aee731f734207873244542993ed4bcff21Brian Carlstrom    ASSERT_FALSE(image_header.IsValid());
224179486aee731f734207873244542993ed4bcff21Brian Carlstrom}
225179486aee731f734207873244542993ed4bcff21Brian Carlstrom
226db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom}  // namespace art
227