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