use of com.tencent.tinker.commons.dexpatcher.algorithms.patch.MethodIdSectionPatchAlgorithm in project tinker by Tencent.
the class DexPatchApplier method executeAndSaveTo.
public void executeAndSaveTo(OutputStream out) throws IOException {
// Before executing, we should check if this patch can be applied to
// old dex we passed in.
byte[] oldDexSign = this.oldDex.computeSignature(false);
if (oldDexSign == null) {
throw new IOException("failed to compute old dex's signature.");
}
if (this.patchFile == null) {
throw new IllegalArgumentException("patch file is null.");
}
byte[] oldDexSignInPatchFile = this.patchFile.getOldDexSignature();
if (CompareUtils.uArrCompare(oldDexSign, oldDexSignInPatchFile) != 0) {
throw new IOException(String.format("old dex signature mismatch! expected: %s, actual: %s", Arrays.toString(oldDexSign), Arrays.toString(oldDexSignInPatchFile)));
}
// Firstly, set sections' offset after patched, sort according to their offset so that
// the dex lib of aosp can calculate section size.
TableOfContents patchedToc = this.patchedDex.getTableOfContents();
patchedToc.header.off = 0;
patchedToc.header.size = 1;
patchedToc.mapList.size = 1;
patchedToc.stringIds.off = this.patchFile.getPatchedStringIdSectionOffset();
patchedToc.typeIds.off = this.patchFile.getPatchedTypeIdSectionOffset();
patchedToc.typeLists.off = this.patchFile.getPatchedTypeListSectionOffset();
patchedToc.protoIds.off = this.patchFile.getPatchedProtoIdSectionOffset();
patchedToc.fieldIds.off = this.patchFile.getPatchedFieldIdSectionOffset();
patchedToc.methodIds.off = this.patchFile.getPatchedMethodIdSectionOffset();
patchedToc.classDefs.off = this.patchFile.getPatchedClassDefSectionOffset();
patchedToc.mapList.off = this.patchFile.getPatchedMapListSectionOffset();
patchedToc.stringDatas.off = this.patchFile.getPatchedStringDataSectionOffset();
patchedToc.annotations.off = this.patchFile.getPatchedAnnotationSectionOffset();
patchedToc.annotationSets.off = this.patchFile.getPatchedAnnotationSetSectionOffset();
patchedToc.annotationSetRefLists.off = this.patchFile.getPatchedAnnotationSetRefListSectionOffset();
patchedToc.annotationsDirectories.off = this.patchFile.getPatchedAnnotationsDirectorySectionOffset();
patchedToc.encodedArrays.off = this.patchFile.getPatchedEncodedArraySectionOffset();
patchedToc.debugInfos.off = this.patchFile.getPatchedDebugInfoSectionOffset();
patchedToc.codes.off = this.patchFile.getPatchedCodeSectionOffset();
patchedToc.classDatas.off = this.patchFile.getPatchedClassDataSectionOffset();
patchedToc.fileSize = this.patchFile.getPatchedDexSize();
Arrays.sort(patchedToc.sections);
patchedToc.computeSizesFromOffsets();
// Secondly, run patch algorithms according to sections' dependencies.
this.stringDataSectionPatchAlg = new StringDataSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.typeIdSectionPatchAlg = new TypeIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.protoIdSectionPatchAlg = new ProtoIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.fieldIdSectionPatchAlg = new FieldIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.methodIdSectionPatchAlg = new MethodIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.classDefSectionPatchAlg = new ClassDefSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.typeListSectionPatchAlg = new TypeListSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.annotationSetRefListSectionPatchAlg = new AnnotationSetRefListSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.annotationSetSectionPatchAlg = new AnnotationSetSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.classDataSectionPatchAlg = new ClassDataSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.codeSectionPatchAlg = new CodeSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.debugInfoSectionPatchAlg = new DebugInfoItemSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.annotationSectionPatchAlg = new AnnotationSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.encodedArraySectionPatchAlg = new StaticValueSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.annotationsDirectorySectionPatchAlg = new AnnotationsDirectorySectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
this.stringDataSectionPatchAlg.execute();
this.typeIdSectionPatchAlg.execute();
this.typeListSectionPatchAlg.execute();
this.protoIdSectionPatchAlg.execute();
this.fieldIdSectionPatchAlg.execute();
this.methodIdSectionPatchAlg.execute();
this.annotationSectionPatchAlg.execute();
this.annotationSetSectionPatchAlg.execute();
this.annotationSetRefListSectionPatchAlg.execute();
this.annotationsDirectorySectionPatchAlg.execute();
this.debugInfoSectionPatchAlg.execute();
this.codeSectionPatchAlg.execute();
this.classDataSectionPatchAlg.execute();
this.encodedArraySectionPatchAlg.execute();
this.classDefSectionPatchAlg.execute();
// Thirdly, write header, mapList. Calculate and write patched dex's sign and checksum.
Dex.Section headerOut = this.patchedDex.openSection(patchedToc.header.off);
patchedToc.writeHeader(headerOut);
Dex.Section mapListOut = this.patchedDex.openSection(patchedToc.mapList.off);
patchedToc.writeMap(mapListOut);
this.patchedDex.writeHashes();
// Finally, write patched dex to file.
this.patchedDex.writeTo(out);
}
Aggregations