• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_IMAGE_H_
18 #define ART_RUNTIME_IMAGE_H_
19 
20 #include <string.h>
21 
22 #include "base/enums.h"
23 #include "globals.h"
24 #include "mirror/object.h"
25 
26 namespace art {
27 
28 class ArtField;
29 class ArtMethod;
30 
31 class ObjectVisitor {
32  public:
~ObjectVisitor()33   virtual ~ObjectVisitor() {}
34 
35   virtual void Visit(mirror::Object* object) = 0;
36 };
37 
38 class ArtMethodVisitor {
39  public:
~ArtMethodVisitor()40   virtual ~ArtMethodVisitor() {}
41 
42   virtual void Visit(ArtMethod* method) = 0;
43 };
44 
45 class ArtFieldVisitor {
46  public:
~ArtFieldVisitor()47   virtual ~ArtFieldVisitor() {}
48 
49   virtual void Visit(ArtField* method) = 0;
50 };
51 
52 class PACKED(4) ImageSection {
53  public:
ImageSection()54   ImageSection() : offset_(0), size_(0) { }
ImageSection(uint32_t offset,uint32_t size)55   ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
56   ImageSection(const ImageSection& section) = default;
57   ImageSection& operator=(const ImageSection& section) = default;
58 
Offset()59   uint32_t Offset() const {
60     return offset_;
61   }
62 
Size()63   uint32_t Size() const {
64     return size_;
65   }
66 
End()67   uint32_t End() const {
68     return Offset() + Size();
69   }
70 
Contains(uint64_t offset)71   bool Contains(uint64_t offset) const {
72     return offset - offset_ < size_;
73   }
74 
75  private:
76   uint32_t offset_;
77   uint32_t size_;
78 };
79 
80 // header of image files written by ImageWriter, read and validated by Space.
81 class PACKED(4) ImageHeader {
82  public:
83   enum StorageMode : uint32_t {
84     kStorageModeUncompressed,
85     kStorageModeLZ4,
86     kStorageModeLZ4HC,
87     kStorageModeCount,  // Number of elements in enum.
88   };
89   static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
90 
ImageHeader()91   ImageHeader()
92       : image_begin_(0U),
93         image_size_(0U),
94         oat_checksum_(0U),
95         oat_file_begin_(0U),
96         oat_data_begin_(0U),
97         oat_data_end_(0U),
98         oat_file_end_(0U),
99         boot_image_begin_(0U),
100         boot_image_size_(0U),
101         boot_oat_begin_(0U),
102         boot_oat_size_(0U),
103         patch_delta_(0),
104         image_roots_(0U),
105         pointer_size_(0U),
106         compile_pic_(0),
107         is_pic_(0),
108         storage_mode_(kDefaultStorageMode),
109         data_size_(0) {}
110 
111   ImageHeader(uint32_t image_begin,
112               uint32_t image_size,
113               ImageSection* sections,
114               uint32_t image_roots,
115               uint32_t oat_checksum,
116               uint32_t oat_file_begin,
117               uint32_t oat_data_begin,
118               uint32_t oat_data_end,
119               uint32_t oat_file_end,
120               uint32_t boot_image_begin,
121               uint32_t boot_image_size,
122               uint32_t boot_oat_begin,
123               uint32_t boot_oat_size,
124               uint32_t pointer_size,
125               bool compile_pic,
126               bool is_pic,
127               StorageMode storage_mode,
128               size_t data_size);
129 
130   bool IsValid() const;
131   const char* GetMagic() const;
132 
GetImageBegin()133   uint8_t* GetImageBegin() const {
134     return reinterpret_cast<uint8_t*>(image_begin_);
135   }
136 
GetImageSize()137   size_t GetImageSize() const {
138     return static_cast<uint32_t>(image_size_);
139   }
140 
GetOatChecksum()141   uint32_t GetOatChecksum() const {
142     return oat_checksum_;
143   }
144 
SetOatChecksum(uint32_t oat_checksum)145   void SetOatChecksum(uint32_t oat_checksum) {
146     oat_checksum_ = oat_checksum;
147   }
148 
149   // The location that the oat file was expected to be when the image was created. The actual
150   // oat file may be at a different location for application images.
GetOatFileBegin()151   uint8_t* GetOatFileBegin() const {
152     return reinterpret_cast<uint8_t*>(oat_file_begin_);
153   }
154 
GetOatDataBegin()155   uint8_t* GetOatDataBegin() const {
156     return reinterpret_cast<uint8_t*>(oat_data_begin_);
157   }
158 
GetOatDataEnd()159   uint8_t* GetOatDataEnd() const {
160     return reinterpret_cast<uint8_t*>(oat_data_end_);
161   }
162 
GetOatFileEnd()163   uint8_t* GetOatFileEnd() const {
164     return reinterpret_cast<uint8_t*>(oat_file_end_);
165   }
166 
167   PointerSize GetPointerSize() const;
168 
GetPointerSizeUnchecked()169   uint32_t GetPointerSizeUnchecked() const {
170     return pointer_size_;
171   }
172 
GetPatchDelta()173   off_t GetPatchDelta() const {
174     return patch_delta_;
175   }
176 
GetOatLocationFromImageLocation(const std::string & image)177   static std::string GetOatLocationFromImageLocation(const std::string& image) {
178     return GetLocationFromImageLocation(image, "oat");
179   }
180 
GetVdexLocationFromImageLocation(const std::string & image)181   static std::string GetVdexLocationFromImageLocation(const std::string& image) {
182     return GetLocationFromImageLocation(image, "vdex");
183   }
184 
185   enum ImageMethod {
186     kResolutionMethod,
187     kImtConflictMethod,
188     kImtUnimplementedMethod,
189     kSaveAllCalleeSavesMethod,
190     kSaveRefsOnlyMethod,
191     kSaveRefsAndArgsMethod,
192     kSaveEverythingMethod,
193     kImageMethodsCount,  // Number of elements in enum.
194   };
195 
196   enum ImageRoot {
197     kDexCaches,
198     kClassRoots,
199     kClassLoader,  // App image only.
200     kImageRootsMax,
201   };
202 
203   enum ImageSections {
204     kSectionObjects,
205     kSectionArtFields,
206     kSectionArtMethods,
207     kSectionRuntimeMethods,
208     kSectionImTables,
209     kSectionIMTConflictTables,
210     kSectionDexCacheArrays,
211     kSectionInternedStrings,
212     kSectionClassTable,
213     kSectionImageBitmap,
214     kSectionCount,  // Number of elements in enum.
215   };
216 
NumberOfImageRoots(bool app_image)217   static size_t NumberOfImageRoots(bool app_image) {
218     return app_image ? kImageRootsMax : kImageRootsMax - 1u;
219   }
220 
221   ArtMethod* GetImageMethod(ImageMethod index) const;
222   void SetImageMethod(ImageMethod index, ArtMethod* method);
223 
224   const ImageSection& GetImageSection(ImageSections index) const;
225 
GetObjectsSection()226   const ImageSection& GetObjectsSection() const {
227     return GetImageSection(kSectionObjects);
228   }
229 
GetMethodsSection()230   const ImageSection& GetMethodsSection() const {
231     return GetImageSection(kSectionArtMethods);
232   }
233 
GetRuntimeMethodsSection()234   const ImageSection& GetRuntimeMethodsSection() const {
235     return GetImageSection(kSectionRuntimeMethods);
236   }
237 
GetFieldsSection()238   const ImageSection& GetFieldsSection() const {
239     return GetImageSection(ImageHeader::kSectionArtFields);
240   }
241 
242   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
243   mirror::Object* GetImageRoot(ImageRoot image_root) const
244       REQUIRES_SHARED(Locks::mutator_lock_);
245 
246   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
247   mirror::ObjectArray<mirror::Object>* GetImageRoots() const
248       REQUIRES_SHARED(Locks::mutator_lock_);
249 
250   void RelocateImage(off_t delta);
251   void RelocateImageMethods(off_t delta);
252   void RelocateImageObjects(off_t delta);
253 
CompilePic()254   bool CompilePic() const {
255     return compile_pic_ != 0;
256   }
257 
IsPic()258   bool IsPic() const {
259     return is_pic_ != 0;
260   }
261 
GetBootImageBegin()262   uint32_t GetBootImageBegin() const {
263     return boot_image_begin_;
264   }
265 
GetBootImageSize()266   uint32_t GetBootImageSize() const {
267     return boot_image_size_;
268   }
269 
GetBootOatBegin()270   uint32_t GetBootOatBegin() const {
271     return boot_oat_begin_;
272   }
273 
GetBootOatSize()274   uint32_t GetBootOatSize() const {
275     return boot_oat_size_;
276   }
277 
GetStorageMode()278   StorageMode GetStorageMode() const {
279     return storage_mode_;
280   }
281 
GetDataSize()282   uint64_t GetDataSize() const {
283     return data_size_;
284   }
285 
IsAppImage()286   bool IsAppImage() const {
287     // App images currently require a boot image, if the size is non zero then it is an app image
288     // header.
289     return boot_image_size_ != 0u;
290   }
291 
292   // Visit mirror::Objects in the section starting at base.
293   // TODO: Delete base parameter if it is always equal to GetImageBegin.
294   void VisitObjects(ObjectVisitor* visitor,
295                     uint8_t* base,
296                     PointerSize pointer_size) const
297       REQUIRES_SHARED(Locks::mutator_lock_);
298 
299   // Visit ArtMethods in the section starting at base. Includes runtime methods.
300   // TODO: Delete base parameter if it is always equal to GetImageBegin.
301   void VisitPackedArtMethods(ArtMethodVisitor* visitor,
302                              uint8_t* base,
303                              PointerSize pointer_size) const;
304 
305   // Visit ArtMethods in the section starting at base.
306   // TODO: Delete base parameter if it is always equal to GetImageBegin.
307   void VisitPackedArtFields(ArtFieldVisitor* visitor, uint8_t* base) const;
308 
309   template <typename Visitor>
310   void VisitPackedImTables(const Visitor& visitor,
311                            uint8_t* base,
312                            PointerSize pointer_size) const;
313 
314   template <typename Visitor>
315   void VisitPackedImtConflictTables(const Visitor& visitor,
316                                     uint8_t* base,
317                                     PointerSize pointer_size) const;
318 
319  private:
320   static const uint8_t kImageMagic[4];
321   static const uint8_t kImageVersion[4];
322 
GetLocationFromImageLocation(const std::string & image,const std::string & extension)323   static std::string GetLocationFromImageLocation(const std::string& image,
324                                                   const std::string& extension) {
325     std::string filename = image;
326     if (filename.length() <= 3) {
327       filename += "." + extension;
328     } else {
329       filename.replace(filename.length() - 3, 3, extension);
330     }
331     return filename;
332   }
333 
334   uint8_t magic_[4];
335   uint8_t version_[4];
336 
337   // Required base address for mapping the image.
338   uint32_t image_begin_;
339 
340   // Image size, not page aligned.
341   uint32_t image_size_;
342 
343   // Checksum of the oat file we link to for load time sanity check.
344   uint32_t oat_checksum_;
345 
346   // Start address for oat file. Will be before oat_data_begin_ for .so files.
347   uint32_t oat_file_begin_;
348 
349   // Required oat address expected by image Method::GetCode() pointers.
350   uint32_t oat_data_begin_;
351 
352   // End of oat data address range for this image file.
353   uint32_t oat_data_end_;
354 
355   // End of oat file address range. will be after oat_data_end_ for
356   // .so files. Used for positioning a following alloc spaces.
357   uint32_t oat_file_end_;
358 
359   // Boot image begin and end (app image headers only).
360   uint32_t boot_image_begin_;
361   uint32_t boot_image_size_;
362 
363   // Boot oat begin and end (app image headers only).
364   uint32_t boot_oat_begin_;
365   uint32_t boot_oat_size_;
366 
367   // TODO: We should probably insert a boot image checksum for app images.
368 
369   // The total delta that this image has been patched.
370   int32_t patch_delta_;
371 
372   // Absolute address of an Object[] of objects needed to reinitialize from an image.
373   uint32_t image_roots_;
374 
375   // Pointer size, this affects the size of the ArtMethods.
376   uint32_t pointer_size_;
377 
378   // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
379   const uint32_t compile_pic_;
380 
381   // Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to
382   // the .art file. Currently, app oat files do not depend on their app image. There are no pointers
383   // from the app oat code to the app image.
384   const uint32_t is_pic_;
385 
386   // Image section sizes/offsets correspond to the uncompressed form.
387   ImageSection sections_[kSectionCount];
388 
389   // Image methods, may be inside of the boot image for app images.
390   uint64_t image_methods_[kImageMethodsCount];
391 
392   // Storage method for the image, the image may be compressed.
393   StorageMode storage_mode_;
394 
395   // Data size for the image data excluding the bitmap and the header. For compressed images, this
396   // is the compressed size in the file.
397   uint32_t data_size_;
398 
399   friend class ImageWriter;
400 };
401 
402 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageMethod& policy);
403 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageRoot& policy);
404 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageSections& section);
405 std::ostream& operator<<(std::ostream& os, const ImageSection& section);
406 std::ostream& operator<<(std::ostream& os, const ImageHeader::StorageMode& mode);
407 
408 }  // namespace art
409 
410 #endif  // ART_RUNTIME_IMAGE_H_
411