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