Guest User

Untitled

a guest
Nov 15th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.86 KB | None | 0 0
  1. diff --git a/oatdump/Android.bp b/oatdump/Android.bp
  2. index 71e276d..3d50229 100644
  3. --- a/oatdump/Android.bp
  4. +++ b/oatdump/Android.bp
  5. @@ -35,6 +35,7 @@ art_cc_binary {
  6. shared_libs: [
  7. "libart",
  8. "libart-compiler",
  9. + "libart-dexlayout",
  10. "libart-disassembler",
  11. "libdexfile",
  12. "libbase",
  13. @@ -50,6 +51,7 @@ art_cc_binary {
  14. shared_libs: [
  15. "libartd",
  16. "libartd-compiler",
  17. + "libartd-dexlayout",
  18. "libartd-disassembler",
  19. "libdexfiled",
  20. "libbase",
  21. @@ -78,6 +80,7 @@ art_cc_binary {
  22. "libart",
  23. "libdexfile",
  24. "libart-compiler",
  25. + "libart-dexlayout",
  26. "libart-disassembler",
  27. "libvixl-arm",
  28. "libvixl-arm64",
  29. @@ -109,6 +112,7 @@ art_cc_binary {
  30. "libartd",
  31. "libdexfiled",
  32. "libartd-compiler",
  33. + "libartd-dexlayout",
  34. "libartd-disassembler",
  35. "libvixld-arm",
  36. "libvixld-arm64",
  37. diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
  38. index 547a24c..f34d3f3 100644
  39. --- a/oatdump/oatdump.cc
  40. +++ b/oatdump/oatdump.cc
  41. @@ -44,11 +44,13 @@
  42. #include "debug/debug_info.h"
  43. #include "debug/elf_debug_writer.h"
  44. #include "debug/method_debug_info.h"
  45. +#include "dex/art_dex_file_loader.h"
  46. #include "dex/code_item_accessors-inl.h"
  47. #include "dex/descriptors_names.h"
  48. #include "dex/dex_file-inl.h"
  49. #include "dex/dex_instruction-inl.h"
  50. #include "dex/string_reference.h"
  51. +#include "dexlayout.h"
  52. #include "disassembler.h"
  53. #include "gc/accounting/space_bitmap-inl.h"
  54. #include "gc/space/image_space.h"
  55. @@ -626,8 +628,60 @@ class OatDumper {
  56. const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
  57. CHECK(oat_dex_file != nullptr);
  58. CHECK(vdex_dex_file != nullptr);
  59. - if (!ExportDexFile(os, *oat_dex_file, vdex_dex_file.get())) {
  60. - success = false;
  61. +
  62. + // If a CompactDex file is detected within a Vdex container, DexLayout is used to convert
  63. + // back to a StandardDex file. Since the converted DexFile will most likely not reproduce
  64. + // original input Dex file, ExportDexFile should know if DexLayout was used to adjust the
  65. + // checksum logic before writing the file on disk.
  66. + if (vdex_dex_file->IsCompactDexFile()) {
  67. + Options options;
  68. + options.compact_dex_level_ = CompactDexLevel::kCompactDexLevelNone;
  69. + options.update_checksum_ = true;
  70. + DexLayout dex_layout(options, /*info*/ nullptr, /*out_file*/ nullptr, /*header*/ nullptr);
  71. + std::unique_ptr<art::DexContainer> dex_container;
  72. + bool result = dex_layout.ProcessDexFile(vdex_dex_file->GetLocation().c_str(),
  73. + vdex_dex_file.get(),
  74. + i,
  75. + &dex_container,
  76. + &error_msg);
  77. + if (!result) {
  78. + os << "DexLayout failed to process Dex file: " + error_msg;
  79. + success = false;
  80. + break;
  81. + }
  82. + DexContainer::Section* main_section = dex_container->GetMainSection();
  83. + CHECK_EQ(dex_container->GetDataSection()->Size(), 0u);
  84. +
  85. + const ArtDexFileLoader dex_file_loader;
  86. + std::unique_ptr<const DexFile> dex(dex_file_loader.Open(
  87. + main_section->Begin(),
  88. + main_section->Size(),
  89. + vdex_dex_file->GetLocation(),
  90. + vdex_file->GetLocationChecksum(i),
  91. + nullptr /*oat_dex_file*/,
  92. + false /*verify*/,
  93. + true /*verify_checksum*/,
  94. + &error_msg));
  95. + if (dex == nullptr) {
  96. + os << "Failed to load DexFile from layout container: " + error_msg;
  97. + success = false;
  98. + break;
  99. + }
  100. + if (dex->IsCompactDexFile()) {
  101. + os <<"CompactDex conversion to StandardDex failed";
  102. + success = false;
  103. + break;
  104. + }
  105. +
  106. + if (!ExportDexFile(os, *oat_dex_file, dex.get(), true /*used_dexlayout*/)) {
  107. + success = false;
  108. + break;
  109. + }
  110. + } else {
  111. + if (!ExportDexFile(os, *oat_dex_file, vdex_dex_file.get(), false /*used_dexlayout*/)) {
  112. + success = false;
  113. + break;
  114. + }
  115. }
  116. i++;
  117. }
  118. @@ -1131,13 +1185,15 @@ class OatDumper {
  119. // Backwards compatible Dex file export. If dex_file is nullptr (valid Vdex file not present) the
  120. // Dex resource is extracted from the oat_dex_file and its checksum is repaired since it's not
  121. // unquickened. Otherwise the dex_file has been fully unquickened and is expected to verify the
  122. - // original checksum.
  123. + // original checksum. If used_dexlayout is set, it means that the dex_file has been converted from
  124. + // a CompactDex file via dexlayout and requires to recompute checksum.
  125. bool ExportDexFile(std::ostream& os,
  126. const OatFile::OatDexFile& oat_dex_file,
  127. - const DexFile* dex_file) {
  128. + const DexFile* dex_file,
  129. + bool used_dexlayout) {
  130. std::string error_msg;
  131. std::string dex_file_location = oat_dex_file.GetDexFileLocation();
  132. - size_t fsize = oat_dex_file.FileSize();
  133. + size_t fsize = dex_file == nullptr ? oat_dex_file.FileSize() : dex_file->Size();
  134.  
  135. // Some quick checks just in case
  136. if (fsize == 0 || fsize < sizeof(DexFile::Header)) {
  137. @@ -1157,27 +1213,22 @@ class OatDumper {
  138. reinterpret_cast<DexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()))->checksum_ =
  139. dex_file->CalculateChecksum();
  140. } else {
  141. - // Vdex unquicken output should match original input bytecode
  142. - uint32_t orig_checksum =
  143. - reinterpret_cast<DexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()))->checksum_;
  144. - CHECK_EQ(orig_checksum, dex_file->CalculateChecksum());
  145. - if (orig_checksum != dex_file->CalculateChecksum()) {
  146. - os << "Unexpected checksum from unquicken dex file '" << dex_file_location << "'\n";
  147. - return false;
  148. + // When dexlayout is used to convert CompactDex back to StandardDex, checksum is not
  149. + // reproducible
  150. + if (used_dexlayout) {
  151. + reinterpret_cast<DexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()))->checksum_ =
  152. + dex_file->CalculateChecksum();
  153. + } else {
  154. + // Vdex unquicken output should match original input bytecode
  155. + uint32_t orig_checksum =
  156. + reinterpret_cast<DexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()))->checksum_;
  157. + if (orig_checksum != dex_file->CalculateChecksum()) {
  158. + os << "Unexpected checksum from unquicken dex file '" << dex_file_location << "'\n";
  159. + return false;
  160. + }
  161. }
  162. }
  163.  
  164. - // Update header for shared section.
  165. - uint32_t shared_section_offset = 0u;
  166. - uint32_t shared_section_size = 0u;
  167. - if (dex_file->IsCompactDexFile()) {
  168. - CompactDexFile::Header* const header =
  169. - reinterpret_cast<CompactDexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()));
  170. - shared_section_offset = header->data_off_;
  171. - shared_section_size = header->data_size_;
  172. - // The shared section will be serialized right after the dex file.
  173. - header->data_off_ = header->file_size_;
  174. - }
  175. // Verify output directory exists
  176. if (!OS::DirectoryExists(options_.export_dex_location_)) {
  177. // TODO: Extend OS::DirectoryExists if symlink support is required
  178. @@ -1231,15 +1282,6 @@ class OatDumper {
  179. return false;
  180. }
  181.  
  182. - if (shared_section_size != 0) {
  183. - success = file->WriteFully(dex_file->Begin() + shared_section_offset, shared_section_size);
  184. - if (!success) {
  185. - os << "Failed to write shared data section";
  186. - file->Erase();
  187. - return false;
  188. - }
  189. - }
  190. -
  191. if (file->FlushCloseOrErase() != 0) {
  192. os << "Flush and close failed";
  193. return false;
Add Comment
Please, Sign In to add comment