Revert "Revert "Add dex file writer to dexlayout tool.""
This reverts commit fd1a6c2a08ca3e2476b7424b9b0fa58e73b29e87.
Fixed output being clobbered during DexLayoutTest.DexFileOutput.
Option added to put dex output file in scratch directory.
Bug: 29921113
Test: mm test-art-host-gtest-dexlayout_test
Change-Id: I9e6b139cf06aaa39c83ad1e74329db266464a8e4
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index f3d2c90..5e686d3 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -24,6 +24,7 @@
#include "dex_file-inl.h"
#include "leb128.h"
+#include "utf.h"
namespace art {
namespace dex_ir {
@@ -137,10 +138,22 @@
std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
-
+ std::vector<std::unique_ptr<StringData>>& StringDatas() { return string_datas_.Collection(); }
std::vector<std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); }
std::vector<std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems()
{ return encoded_array_items_.Collection(); }
+ std::vector<std::unique_ptr<AnnotationItem>>& AnnotationItems()
+ { return annotation_items_.Collection(); }
+ std::vector<std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems()
+ { return annotation_set_items_.Collection(); }
+ std::vector<std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists()
+ { return annotation_set_ref_lists_.Collection(); }
+ std::vector<std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems()
+ { return annotations_directory_items_.Collection(); }
+ std::vector<std::unique_ptr<DebugInfoItem>>& DebugInfoItems()
+ { return debug_info_items_.Collection(); }
+ std::vector<std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); }
+ std::vector<std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); }
void CreateStringId(const DexFile& dex_file, uint32_t i);
void CreateTypeId(const DexFile& dex_file, uint32_t i);
@@ -149,7 +162,7 @@
void CreateMethodId(const DexFile& dex_file, uint32_t i);
void CreateClassDef(const DexFile& dex_file, uint32_t i);
- TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset, bool allow_empty);
+ TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset);
AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset);
AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
@@ -182,14 +195,16 @@
uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
- uint32_t EncodedArrayOffset() const { return encoded_array_items_.GetOffset(); }
- uint32_t AnnotationOffset() const { return annotation_items_.GetOffset(); }
- uint32_t AnnotationSetOffset() const { return annotation_set_items_.GetOffset(); }
+ uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
+ uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
+ uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
- uint32_t AnnotationsDirectoryOffset() const { return annotations_directory_items_.GetOffset(); }
- uint32_t DebugInfoOffset() const { return debug_info_items_.GetOffset(); }
+ uint32_t AnnotationsDirectoryItemsOffset() const
+ { return annotations_directory_items_.GetOffset(); }
+ uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
+ uint32_t MapItemOffset() const { return map_item_offset_; }
void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
@@ -199,16 +214,19 @@
void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
- void SetEncodedArrayOffset(uint32_t new_offset) { encoded_array_items_.SetOffset(new_offset); }
- void SetAnnotationOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
- void SetAnnotationSetOffset(uint32_t new_offset) { annotation_set_items_.SetOffset(new_offset); }
+ void SetEncodedArrayItemsOffset(uint32_t new_offset)
+ { encoded_array_items_.SetOffset(new_offset); }
+ void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
+ void SetAnnotationSetItemsOffset(uint32_t new_offset)
+ { annotation_set_items_.SetOffset(new_offset); }
void SetAnnotationSetRefListsOffset(uint32_t new_offset)
{ annotation_set_ref_lists_.SetOffset(new_offset); }
- void SetAnnotationsDirectoryOffset(uint32_t new_offset)
+ void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
{ annotations_directory_items_.SetOffset(new_offset); }
- void SetDebugInfoOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
+ void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
+ void SetMapItemOffset(uint32_t new_offset) { map_item_offset_ = new_offset; }
uint32_t StringIdsSize() const { return string_ids_.Size(); }
uint32_t TypeIdsSize() const { return type_ids_.Size(); }
@@ -216,15 +234,14 @@
uint32_t FieldIdsSize() const { return field_ids_.Size(); }
uint32_t MethodIdsSize() const { return method_ids_.Size(); }
uint32_t ClassDefsSize() const { return class_defs_.Size(); }
-
uint32_t StringDatasSize() const { return string_datas_.Size(); }
uint32_t TypeListsSize() const { return type_lists_.Size(); }
- uint32_t EncodedArraySize() const { return encoded_array_items_.Size(); }
- uint32_t AnnotationSize() const { return annotation_items_.Size(); }
- uint32_t AnnotationSetSize() const { return annotation_set_items_.Size(); }
+ uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
+ uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
+ uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
- uint32_t AnnotationsDirectorySize() const { return annotations_directory_items_.Size(); }
- uint32_t DebugInfoSize() const { return debug_info_items_.Size(); }
+ uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
+ uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
uint32_t CodeItemsSize() const { return code_items_.Size(); }
uint32_t ClassDatasSize() const { return class_datas_.Size(); }
@@ -255,6 +272,8 @@
CollectionWithOffset<CodeItem> code_items_;
CollectionWithOffset<ClassData> class_datas_;
+ uint32_t map_item_offset_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(Collections);
};
@@ -364,7 +383,7 @@
class StringData : public Item {
public:
explicit StringData(const char* data) : data_(strdup(data)) {
- size_ = UnsignedLeb128Size(strlen(data)) + strlen(data);
+ size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
}
const char* Data() const { return data_.get(); }
@@ -372,7 +391,7 @@
void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
private:
- std::unique_ptr<const char> data_;
+ UniqueCPtr<const char> data_;
DISALLOW_COPY_AND_ASSIGN(StringData);
};
@@ -442,14 +461,14 @@
const StringId* Shorty() const { return shorty_; }
const TypeId* ReturnType() const { return return_type_; }
- const TypeIdVector& Parameters() const { return *parameters_->GetTypeList(); }
+ const TypeList* Parameters() const { return parameters_; }
void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
private:
const StringId* shorty_;
const TypeId* return_type_;
- TypeList* parameters_;
+ TypeList* parameters_; // This can be nullptr.
DISALLOW_COPY_AND_ASSIGN(ProtoId);
};
@@ -533,7 +552,7 @@
private:
uint32_t access_flags_;
const MethodId* method_id_;
- const CodeItem* code_;
+ const CodeItem* code_; // This can be nullptr.
DISALLOW_COPY_AND_ASSIGN(MethodItem);
};
@@ -691,8 +710,8 @@
interfaces_(interfaces),
source_file_(source_file),
annotations_(annotations),
- static_values_(static_values),
- class_data_(class_data) { size_ = kClassDefItemSize; }
+ class_data_(class_data),
+ static_values_(static_values) { size_ = kClassDefItemSize; }
~ClassDef() OVERRIDE { }
@@ -706,8 +725,8 @@
uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
const StringId* SourceFile() const { return source_file_; }
AnnotationsDirectoryItem* Annotations() const { return annotations_; }
- EncodedArrayItem* StaticValues() { return static_values_; }
ClassData* GetClassData() { return class_data_; }
+ EncodedArrayItem* StaticValues() { return static_values_; }
MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
@@ -716,19 +735,19 @@
private:
const TypeId* class_type_;
uint32_t access_flags_;
- const TypeId* superclass_;
- TypeList* interfaces_;
- const StringId* source_file_;
- AnnotationsDirectoryItem* annotations_;
- EncodedArrayItem* static_values_;
- ClassData* class_data_;
+ const TypeId* superclass_; // This can be nullptr.
+ TypeList* interfaces_; // This can be nullptr.
+ const StringId* source_file_; // This can be nullptr.
+ AnnotationsDirectoryItem* annotations_; // This can be nullptr.
+ ClassData* class_data_; // This can be nullptr.
+ EncodedArrayItem* static_values_; // This can be nullptr.
DISALLOW_COPY_AND_ASSIGN(ClassDef);
};
-class CatchHandler {
+class TypeAddrPair {
public:
- CatchHandler(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
+ TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
const TypeId* GetTypeId() const { return type_id_; }
uint32_t GetAddress() const { return address_; }
@@ -737,6 +756,25 @@
const TypeId* type_id_;
uint32_t address_;
+ DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
+};
+
+using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
+
+class CatchHandler {
+ public:
+ explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
+ : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
+
+ bool HasCatchAll() const { return catch_all_; }
+ uint16_t GetListOffset() const { return list_offset_; }
+ TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
+
+ private:
+ bool catch_all_;
+ uint16_t list_offset_;
+ std::unique_ptr<TypeAddrPairVector> handlers_;
+
DISALLOW_COPY_AND_ASSIGN(CatchHandler);
};
@@ -744,20 +782,20 @@
class TryItem : public Item {
public:
- TryItem(uint32_t start_addr, uint16_t insn_count, CatchHandlerVector* handlers)
+ TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
: start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
~TryItem() OVERRIDE { }
uint32_t StartAddr() const { return start_addr_; }
uint16_t InsnCount() const { return insn_count_; }
- const CatchHandlerVector& GetHandlers() const { return *handlers_.get(); }
+ const CatchHandler* GetHandlers() const { return handlers_; }
void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
private:
uint32_t start_addr_;
uint16_t insn_count_;
- std::unique_ptr<CatchHandlerVector> handlers_;
+ const CatchHandler* handlers_;
DISALLOW_COPY_AND_ASSIGN(TryItem);
};
@@ -772,14 +810,16 @@
DebugInfoItem* debug_info,
uint32_t insns_size,
uint16_t* insns,
- TryItemVector* tries)
+ TryItemVector* tries,
+ CatchHandlerVector* handlers)
: registers_size_(registers_size),
ins_size_(ins_size),
outs_size_(outs_size),
debug_info_(debug_info),
insns_size_(insns_size),
insns_(insns),
- tries_(tries) { }
+ tries_(tries),
+ handlers_(handlers) { }
~CodeItem() OVERRIDE { }
@@ -791,6 +831,7 @@
uint32_t InsnsSize() const { return insns_size_; }
uint16_t* Insns() const { return insns_.get(); }
TryItemVector* Tries() const { return tries_.get(); }
+ CatchHandlerVector* Handlers() const { return handlers_.get(); }
void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
@@ -798,10 +839,11 @@
uint16_t registers_size_;
uint16_t ins_size_;
uint16_t outs_size_;
- DebugInfoItem* debug_info_;
+ DebugInfoItem* debug_info_; // This can be nullptr.
uint32_t insns_size_;
std::unique_ptr<uint16_t[]> insns_;
- std::unique_ptr<TryItemVector> tries_;
+ std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
+ std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
@@ -841,12 +883,19 @@
class DebugInfoItem : public Item {
public:
- DebugInfoItem() = default;
+ DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
+ : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
+
+ uint32_t GetDebugInfoSize() const { return debug_info_size_; }
+ uint8_t* GetDebugInfo() const { return debug_info_.get(); }
PositionInfoVector& GetPositionInfo() { return positions_; }
LocalInfoVector& GetLocalInfo() { return locals_; }
private:
+ uint32_t debug_info_size_;
+ std::unique_ptr<uint8_t[]> debug_info_;
+
PositionInfoVector positions_;
LocalInfoVector locals_;
@@ -899,7 +948,7 @@
void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
private:
- std::unique_ptr<std::vector<AnnotationSetItem*>> items_;
+ std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
};
@@ -974,10 +1023,10 @@
void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
private:
- AnnotationSetItem* class_annotation_;
- std::unique_ptr<FieldAnnotationVector> field_annotations_;
- std::unique_ptr<MethodAnnotationVector> method_annotations_;
- std::unique_ptr<ParameterAnnotationVector> parameter_annotations_;
+ AnnotationSetItem* class_annotation_; // This can be nullptr.
+ std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
+ std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
+ std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
};