You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.5 KiB
176 lines
6.5 KiB
/* |
|
* Copyright (C) 2016 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
* Implementation file of the dexlayout utility. |
|
* |
|
* This is a tool to read dex files into an internal representation, |
|
* reorganize the representation, and emit dex files with a better |
|
* file layout. |
|
*/ |
|
|
|
#include "dex_ir.h" |
|
|
|
#include "dex/code_item_accessors-inl.h" |
|
#include "dex/dex_file_exception_helpers.h" |
|
#include "dex/dex_instruction-inl.h" |
|
#include "dex_ir_builder.h" |
|
|
|
namespace art { |
|
namespace dex_ir { |
|
|
|
static uint32_t HeaderOffset(const dex_ir::Header* header ATTRIBUTE_UNUSED) { |
|
return 0; |
|
} |
|
|
|
static uint32_t HeaderSize(const dex_ir::Header* header ATTRIBUTE_UNUSED) { |
|
// Size is in elements, so there is only one header. |
|
return 1; |
|
} |
|
|
|
// The description of each dex file section type. |
|
struct FileSectionDescriptor { |
|
public: |
|
std::string name; |
|
uint16_t type; |
|
// A function that when applied to a collection object, gives the size of the section. |
|
std::function<uint32_t(dex_ir::Header*)> size_fn; |
|
// A function that when applied to a collection object, gives the offset of the section. |
|
std::function<uint32_t(dex_ir::Header*)> offset_fn; |
|
}; |
|
|
|
static const FileSectionDescriptor kFileSectionDescriptors[] = { |
|
{ |
|
"Header", |
|
DexFile::kDexTypeHeaderItem, |
|
&HeaderSize, |
|
&HeaderOffset, |
|
}, { |
|
"StringId", |
|
DexFile::kDexTypeStringIdItem, |
|
[](const dex_ir::Header* h) { return h->StringIds().Size(); }, |
|
[](const dex_ir::Header* h) { return h->StringIds().GetOffset(); } |
|
}, { |
|
"TypeId", |
|
DexFile::kDexTypeTypeIdItem, |
|
[](const dex_ir::Header* h) { return h->TypeIds().Size(); }, |
|
[](const dex_ir::Header* h) { return h->TypeIds().GetOffset(); } |
|
}, { |
|
"ProtoId", |
|
DexFile::kDexTypeProtoIdItem, |
|
[](const dex_ir::Header* h) { return h->ProtoIds().Size(); }, |
|
[](const dex_ir::Header* h) { return h->ProtoIds().GetOffset(); } |
|
}, { |
|
"FieldId", |
|
DexFile::kDexTypeFieldIdItem, |
|
[](const dex_ir::Header* h) { return h->FieldIds().Size(); }, |
|
[](const dex_ir::Header* h) { return h->FieldIds().GetOffset(); } |
|
}, { |
|
"MethodId", |
|
DexFile::kDexTypeMethodIdItem, |
|
[](const dex_ir::Header* h) { return h->MethodIds().Size(); }, |
|
[](const dex_ir::Header* h) { return h->MethodIds().GetOffset(); } |
|
}, { |
|
"ClassDef", |
|
DexFile::kDexTypeClassDefItem, |
|
[](const dex_ir::Header* h) { return h->ClassDefs().Size(); }, |
|
[](const dex_ir::Header* h) { return h->ClassDefs().GetOffset(); } |
|
}, { |
|
"CallSiteId", |
|
DexFile::kDexTypeCallSiteIdItem, |
|
[](const dex_ir::Header* h) { return h->CallSiteIds().Size(); }, |
|
[](const dex_ir::Header* h) { return h->CallSiteIds().GetOffset(); } |
|
}, { |
|
"MethodHandle", |
|
DexFile::kDexTypeMethodHandleItem, |
|
[](const dex_ir::Header* h) { return h->MethodHandleItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->MethodHandleItems().GetOffset(); } |
|
}, { |
|
"StringData", |
|
DexFile::kDexTypeStringDataItem, |
|
[](const dex_ir::Header* h) { return h->StringDatas().Size(); }, |
|
[](const dex_ir::Header* h) { return h->StringDatas().GetOffset(); } |
|
}, { |
|
"TypeList", |
|
DexFile::kDexTypeTypeList, |
|
[](const dex_ir::Header* h) { return h->TypeLists().Size(); }, |
|
[](const dex_ir::Header* h) { return h->TypeLists().GetOffset(); } |
|
}, { |
|
"EncArr", |
|
DexFile::kDexTypeEncodedArrayItem, |
|
[](const dex_ir::Header* h) { return h->EncodedArrayItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->EncodedArrayItems().GetOffset(); } |
|
}, { |
|
"Annotation", |
|
DexFile::kDexTypeAnnotationItem, |
|
[](const dex_ir::Header* h) { return h->AnnotationItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->AnnotationItems().GetOffset(); } |
|
}, { |
|
"AnnoSet", |
|
DexFile::kDexTypeAnnotationSetItem, |
|
[](const dex_ir::Header* h) { return h->AnnotationSetItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->AnnotationSetItems().GetOffset(); } |
|
}, { |
|
"AnnoSetRL", |
|
DexFile::kDexTypeAnnotationSetRefList, |
|
[](const dex_ir::Header* h) { return h->AnnotationSetRefLists().Size(); }, |
|
[](const dex_ir::Header* h) { return h->AnnotationSetRefLists().GetOffset(); } |
|
}, { |
|
"AnnoDir", |
|
DexFile::kDexTypeAnnotationsDirectoryItem, |
|
[](const dex_ir::Header* h) { return h->AnnotationsDirectoryItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->AnnotationsDirectoryItems().GetOffset(); } |
|
}, { |
|
"DebugInfo", |
|
DexFile::kDexTypeDebugInfoItem, |
|
[](const dex_ir::Header* h) { return h->DebugInfoItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->DebugInfoItems().GetOffset(); } |
|
}, { |
|
"CodeItem", |
|
DexFile::kDexTypeCodeItem, |
|
[](const dex_ir::Header* h) { return h->CodeItems().Size(); }, |
|
[](const dex_ir::Header* h) { return h->CodeItems().GetOffset(); } |
|
}, { |
|
"ClassData", |
|
DexFile::kDexTypeClassDataItem, |
|
[](const dex_ir::Header* h) { return h->ClassDatas().Size(); }, |
|
[](const dex_ir::Header* h) { return h->ClassDatas().GetOffset(); } |
|
} |
|
}; |
|
|
|
std::vector<dex_ir::DexFileSection> GetSortedDexFileSections(dex_ir::Header* header, |
|
dex_ir::SortDirection direction) { |
|
std::vector<dex_ir::DexFileSection> sorted_sections; |
|
// Build the table that will map from offset to color |
|
for (const FileSectionDescriptor& s : kFileSectionDescriptors) { |
|
sorted_sections.push_back(dex_ir::DexFileSection(s.name, |
|
s.type, |
|
s.size_fn(header), |
|
s.offset_fn(header))); |
|
} |
|
// Sort by offset. |
|
std::sort(sorted_sections.begin(), |
|
sorted_sections.end(), |
|
[=](dex_ir::DexFileSection& a, dex_ir::DexFileSection& b) { |
|
if (direction == SortDirection::kSortDescending) { |
|
return a.offset > b.offset; |
|
} else { |
|
return a.offset < b.offset; |
|
} |
|
}); |
|
return sorted_sections; |
|
} |
|
|
|
} // namespace dex_ir |
|
} // namespace art
|
|
|