1 /*
2  * Copyright (C) 2016 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  * Header file of the dexlayout utility.
17  *
18  * This is a tool to read dex files into an internal representation,
19  * reorganize the representation, and emit dex files with a better
20  * file layout.
21  */
22 
23 #ifndef ART_DEXLAYOUT_DEXLAYOUT_H_
24 #define ART_DEXLAYOUT_DEXLAYOUT_H_
25 
26 #include <stdint.h>
27 #include <stdio.h>
28 
29 #include "dex_ir.h"
30 #include "mem_map.h"
31 
32 namespace art {
33 
34 class DexFile;
35 class Instruction;
36 class ProfileCompilationInfo;
37 
38 /* Supported output formats. */
39 enum OutputFormat {
40   kOutputPlain = 0,  // default
41   kOutputXml,        // XML-style
42 };
43 
44 /* Command-line options. */
45 class Options {
46  public:
47   Options() = default;
48 
49   bool dump_ = false;
50   bool build_dex_ir_ = false;
51   bool checksum_only_ = false;
52   bool disassemble_ = false;
53   bool exports_only_ = false;
54   bool ignore_bad_checksum_ = false;
55   bool output_to_memmap_ = false;
56   bool show_annotations_ = false;
57   bool show_file_headers_ = false;
58   bool show_section_headers_ = false;
59   bool show_section_statistics_ = false;
60   bool verbose_ = false;
61   bool verify_output_ = false;
62   bool visualize_pattern_ = false;
63   OutputFormat output_format_ = kOutputPlain;
64   const char* output_dex_directory_ = nullptr;
65   const char* output_file_name_ = nullptr;
66   const char* profile_file_name_ = nullptr;
67 };
68 
69 class DexLayout {
70  public:
71   DexLayout(Options& options,
72             ProfileCompilationInfo* info,
73             FILE* out_file,
74             dex_ir::Header*
75             header = nullptr)
options_(options)76       : options_(options), info_(info), out_file_(out_file), header_(header) { }
77 
78   int ProcessFile(const char* file_name);
79   void ProcessDexFile(const char* file_name, const DexFile* dex_file, size_t dex_file_index);
80 
GetHeader()81   dex_ir::Header* GetHeader() const { return header_; }
SetHeader(dex_ir::Header * header)82   void SetHeader(dex_ir::Header* header) { header_ = header; }
83 
GetAndReleaseMemMap()84   MemMap* GetAndReleaseMemMap() { return mem_map_.release(); }
85 
86  private:
87   void DumpAnnotationSetItem(dex_ir::AnnotationSetItem* set_item);
88   void DumpBytecodes(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset);
89   void DumpCatches(const dex_ir::CodeItem* code);
90   void DumpClass(int idx, char** last_package);
91   void DumpClassAnnotations(int idx);
92   void DumpClassDef(int idx);
93   void DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset);
94   void DumpEncodedAnnotation(dex_ir::EncodedAnnotation* annotation);
95   void DumpEncodedValue(const dex_ir::EncodedValue* data);
96   void DumpFileHeader();
97   void DumpIField(uint32_t idx, uint32_t flags, int i);
98   void DumpInstruction(const dex_ir::CodeItem* code,
99                        uint32_t code_offset,
100                        uint32_t insn_idx,
101                        uint32_t insn_width,
102                        const Instruction* dec_insn);
103   void DumpInterface(const dex_ir::TypeId* type_item, int i);
104   void DumpLocalInfo(const dex_ir::CodeItem* code);
105   void DumpMethod(uint32_t idx, uint32_t flags, const dex_ir::CodeItem* code, int i);
106   void DumpPositionInfo(const dex_ir::CodeItem* code);
107   void DumpSField(uint32_t idx, uint32_t flags, int i, dex_ir::EncodedValue* init);
108   void DumpDexFile();
109 
110   std::vector<dex_ir::ClassData*> LayoutClassDefsAndClassData(const DexFile* dex_file);
111   int32_t LayoutCodeItems(const DexFile* dex_file,
112                           std::vector<dex_ir::ClassData*> new_class_data_order);
113   void LayoutStringData(const DexFile* dex_file);
114   bool IsNextSectionCodeItemAligned(uint32_t offset);
115   template<class T> void FixupSection(std::map<uint32_t, std::unique_ptr<T>>& map, uint32_t diff);
116   void FixupSections(uint32_t offset, uint32_t diff);
117 
118   // Creates a new layout for the dex file based on profile info.
119   // Currently reorders ClassDefs, ClassDataItems, and CodeItems.
120   void LayoutOutputFile(const DexFile* dex_file);
121   void OutputDexFile(const DexFile* dex_file);
122 
123   void DumpCFG(const DexFile* dex_file, int idx);
124   void DumpCFG(const DexFile* dex_file, uint32_t dex_method_idx, const DexFile::CodeItem* code);
125 
126   Options& options_;
127   ProfileCompilationInfo* info_;
128   FILE* out_file_;
129   dex_ir::Header* header_;
130   std::unique_ptr<MemMap> mem_map_;
131 
132   DISALLOW_COPY_AND_ASSIGN(DexLayout);
133 };
134 
135 }  // namespace art
136 
137 #endif  // ART_DEXLAYOUT_DEXLAYOUT_H_
138