summaryrefslogtreecommitdiff
path: root/compiler/oat_writer.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/oat_writer.h')
-rw-r--r--compiler/oat_writer.h142
1 files changed, 115 insertions, 27 deletions
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 5feb5fc516..d681998774 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -27,7 +27,9 @@
#include "method_reference.h"
#include "mirror/class.h"
#include "oat.h"
+#include "os.h"
#include "safe_map.h"
+#include "ScopedFd.h"
#include "utils/array_ref.h"
namespace art {
@@ -39,6 +41,7 @@ class ImageWriter;
class OutputStream;
class TimingLogger;
class TypeLookupTable;
+class ZipEntry;
namespace dwarf {
struct MethodDebugInfo;
@@ -61,6 +64,11 @@ struct MethodDebugInfo;
// ...
// TypeLookupTable[D]
//
+// ClassOffsets[0] one table of OatClass offsets for each class def for each OatDexFile.
+// ClassOffsets[1]
+// ...
+// ClassOffsets[D]
+//
// OatClass[0] one variable sized OatClass for each of C DexFile::ClassDefs
// OatClass[1] contains OatClass entries with class status, offsets to code, etc.
// ...
@@ -93,15 +101,65 @@ struct MethodDebugInfo;
//
class OatWriter {
public:
- OatWriter(const std::vector<const DexFile*>& dex_files,
- uint32_t image_file_location_oat_checksum,
- uintptr_t image_file_location_oat_begin,
- int32_t image_patch_delta,
- const CompilerDriver* compiler,
- ImageWriter* image_writer,
- bool compiling_boot_image,
- TimingLogger* timings,
- SafeMap<std::string, std::string>* key_value_store);
+ enum class CreateTypeLookupTable {
+ kCreate,
+ kDontCreate,
+ kDefault = kCreate
+ };
+
+ OatWriter(bool compiling_boot_image, TimingLogger* timings);
+
+ // To produce a valid oat file, the user must first add sources with any combination of
+ // - AddDexFileSource(),
+ // - AddZippedDexFilesSource(),
+ // - AddRawDexFileSource().
+ // Then the user must call in order
+ // - WriteAndOpenDexFiles()
+ // - PrepareLayout(),
+ // - WriteRodata(),
+ // - WriteCode(),
+ // - WriteHeader().
+
+ // Add dex file source(s) from a file, either a plain dex file or
+ // a zip file with one or more dex files.
+ bool AddDexFileSource(
+ const char* filename,
+ const char* location,
+ CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
+ // Add dex file source(s) from a zip file specified by a file handle.
+ bool AddZippedDexFilesSource(
+ ScopedFd&& zip_fd,
+ const char* location,
+ CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
+ // Add dex file source from raw memory.
+ bool AddRawDexFileSource(
+ const ArrayRef<const uint8_t>& data,
+ const char* location,
+ uint32_t location_checksum,
+ CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
+ dchecked_vector<const char*> GetSourceLocations() const;
+
+ // Write raw dex files to the .rodata section and open them from the oat file.
+ bool WriteAndOpenDexFiles(OutputStream* rodata,
+ File* file,
+ InstructionSet instruction_set,
+ const InstructionSetFeatures* instruction_set_features,
+ SafeMap<std::string, std::string>* key_value_store,
+ /*out*/ std::unique_ptr<MemMap>* opened_dex_files_map,
+ /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
+ // Prepare layout of remaining data.
+ void PrepareLayout(const CompilerDriver* compiler,
+ ImageWriter* image_writer,
+ const std::vector<const DexFile*>& dex_files);
+ // Write the rest of .rodata section (ClassOffsets[], OatClass[], maps).
+ bool WriteRodata(OutputStream* out);
+ // Write the code to the .text section.
+ bool WriteCode(OutputStream* out);
+ // Write the oat header. This finalizes the oat file.
+ bool WriteHeader(OutputStream* out,
+ uint32_t image_file_location_oat_checksum,
+ uintptr_t image_file_location_oat_begin,
+ int32_t image_patch_delta);
// Returns whether the oat file has an associated image.
bool HasImage() const {
@@ -130,9 +188,6 @@ class OatWriter {
return ArrayRef<const uintptr_t>(absolute_patch_locations_);
}
- bool WriteRodata(OutputStream* out);
- bool WriteCode(OutputStream* out);
-
~OatWriter();
ArrayRef<const dwarf::MethodDebugInfo> GetMethodDebugInfo() const {
@@ -144,6 +199,7 @@ class OatWriter {
}
private:
+ class DexFileSource;
class OatClass;
class OatDexFile;
@@ -174,29 +230,65 @@ class OatWriter {
// with a given DexMethodVisitor.
bool VisitDexMethods(DexMethodVisitor* visitor);
- size_t InitOatHeader();
+ size_t InitOatHeader(InstructionSet instruction_set,
+ const InstructionSetFeatures* instruction_set_features,
+ uint32_t num_dex_files,
+ SafeMap<std::string, std::string>* key_value_store);
size_t InitOatDexFiles(size_t offset);
- size_t InitLookupTables(size_t offset);
- size_t InitDexFiles(size_t offset);
size_t InitOatClasses(size_t offset);
size_t InitOatMaps(size_t offset);
size_t InitOatCode(size_t offset);
size_t InitOatCodeDexFiles(size_t offset);
- bool WriteTables(OutputStream* out, const size_t file_offset);
- bool WriteLookupTables(OutputStream* out, const size_t file_offset);
+ bool WriteClassOffsets(OutputStream* out);
+ bool WriteClasses(OutputStream* out);
size_t WriteMaps(OutputStream* out, const size_t file_offset, size_t relative_offset);
size_t WriteCode(OutputStream* out, const size_t file_offset, size_t relative_offset);
size_t WriteCodeDexFiles(OutputStream* out, const size_t file_offset, size_t relative_offset);
bool GetOatDataOffset(OutputStream* out);
+ bool ReadDexFileHeader(File* file, OatDexFile* oat_dex_file);
+ bool ValidateDexFileHeader(const uint8_t* raw_header, const char* location);
+ bool WriteDexFiles(OutputStream* rodata, File* file);
+ bool WriteDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file);
+ bool SeekToDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file);
+ bool WriteDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file, ZipEntry* dex_file);
+ bool WriteDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file, File* dex_file);
+ bool WriteDexFile(OutputStream* rodata, OatDexFile* oat_dex_file, const uint8_t* dex_file);
+ bool WriteOatDexFiles(OutputStream* rodata);
+ bool ExtendForTypeLookupTables(OutputStream* rodata, File* file, size_t offset);
+ bool OpenDexFiles(File* file,
+ /*out*/ std::unique_ptr<MemMap>* opened_dex_files_map,
+ /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
+ bool WriteTypeLookupTables(MemMap* opened_dex_files_map,
+ const std::vector<std::unique_ptr<const DexFile>>& opened_dex_files);
bool WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta);
bool WriteData(OutputStream* out, const void* data, size_t size);
+ enum class WriteState {
+ kAddingDexFileSources,
+ kPrepareLayout,
+ kWriteRoData,
+ kWriteText,
+ kWriteHeader,
+ kDone
+ };
+
+ WriteState write_state_;
+ TimingLogger* timings_;
+
+ std::vector<std::unique_ptr<File>> raw_dex_files_;
+ std::vector<std::unique_ptr<ZipArchive>> zip_archives_;
+ std::vector<std::unique_ptr<ZipEntry>> zipped_dex_files_;
+
+ // Using std::list<> which doesn't move elements around on push/emplace_back().
+ // We need this because we keep plain pointers to the strings' c_str().
+ std::list<std::string> zipped_dex_file_locations_;
+
dchecked_vector<dwarf::MethodDebugInfo> method_info_;
- const CompilerDriver* const compiler_driver_;
- ImageWriter* const image_writer_;
+ const CompilerDriver* compiler_driver_;
+ ImageWriter* image_writer_;
const bool compiling_boot_image_;
// note OatFile does not take ownership of the DexFiles
@@ -215,13 +307,7 @@ class OatWriter {
// Offset of the oat data from the start of the mmapped region of the elf file.
size_t oat_data_offset_;
- // dependencies on the image.
- uint32_t image_file_location_oat_checksum_;
- uintptr_t image_file_location_oat_begin_;
- int32_t image_patch_delta_;
-
// data to write
- SafeMap<std::string, std::string>* key_value_store_;
std::unique_ptr<OatHeader> oat_header_;
dchecked_vector<OatDexFile> oat_dex_files_;
dchecked_vector<OatClass> oat_classes_;
@@ -257,10 +343,12 @@ class OatWriter {
uint32_t size_oat_dex_file_location_data_;
uint32_t size_oat_dex_file_location_checksum_;
uint32_t size_oat_dex_file_offset_;
+ uint32_t size_oat_dex_file_class_offsets_offset_;
uint32_t size_oat_dex_file_lookup_table_offset_;
- uint32_t size_oat_dex_file_class_offsets_;
uint32_t size_oat_lookup_table_alignment_;
uint32_t size_oat_lookup_table_;
+ uint32_t size_oat_class_offsets_alignment_;
+ uint32_t size_oat_class_offsets_;
uint32_t size_oat_class_type_;
uint32_t size_oat_class_status_;
uint32_t size_oat_class_method_bitmaps_;
@@ -269,7 +357,7 @@ class OatWriter {
std::unique_ptr<linker::RelativePatcher> relative_patcher_;
// The locations of absolute patches relative to the start of the executable section.
- std::vector<uintptr_t> absolute_patch_locations_;
+ dchecked_vector<uintptr_t> absolute_patch_locations_;
// Map method reference to assigned offset.
// Wrap the map in a class implementing linker::RelativePatcherTargetProvider.