mirror of
https://github.com/revanced/Apktool.git
synced 2025-02-22 16:31:08 +01:00
Add ability to list methods/fields/types when assembling with smali
This can be useful in analyzing why you are going over the 64k method/field/type limit
This commit is contained in:
parent
52fd17a436
commit
7a3d09cc47
@ -58,6 +58,7 @@ import org.jf.dexlib2.iface.reference.StringReference;
|
||||
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||
import org.jf.dexlib2.util.InstructionUtil;
|
||||
import org.jf.dexlib2.util.MethodUtil;
|
||||
import org.jf.dexlib2.util.ReferenceUtil;
|
||||
import org.jf.dexlib2.writer.io.DeferredOutputStream;
|
||||
import org.jf.dexlib2.writer.io.DeferredOutputStreamFactory;
|
||||
import org.jf.dexlib2.writer.io.DexDataStore;
|
||||
@ -196,6 +197,33 @@ public abstract class DexWriter<
|
||||
classSection.getItems().size() * ClassDefItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<String> getMethodReferences() {
|
||||
List<String> methodReferences = Lists.newArrayList();
|
||||
for (Entry<? extends MethodRefKey, Integer> methodReference: methodSection.getItems()) {
|
||||
methodReferences.add(ReferenceUtil.getMethodDescriptor(methodReference.getKey()));
|
||||
}
|
||||
return methodReferences;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<String> getFieldReferences() {
|
||||
List<String> fieldReferences = Lists.newArrayList();
|
||||
for (Entry<? extends FieldRefKey, Integer> fieldReference: fieldSection.getItems()) {
|
||||
fieldReferences.add(ReferenceUtil.getFieldDescriptor(fieldReference.getKey()));
|
||||
}
|
||||
return fieldReferences;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<String> getTypeReferences() {
|
||||
List<String> classReferences = Lists.newArrayList();
|
||||
for (Entry<? extends TypeKey, Integer> typeReference: typeSection.getItems()) {
|
||||
classReferences.add(typeReference.getKey().toString());
|
||||
}
|
||||
return classReferences;
|
||||
}
|
||||
|
||||
public void writeTo(@Nonnull DexDataStore dest) throws IOException {
|
||||
this.writeTo(dest, MemoryDeferredOutputStream.getFactory());
|
||||
}
|
||||
|
@ -28,7 +28,9 @@
|
||||
|
||||
package org.jf.smali;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Ordering;
|
||||
import org.antlr.runtime.CommonTokenStream;
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.runtime.TokenSource;
|
||||
@ -113,6 +115,15 @@ public class main {
|
||||
boolean printTokens = false;
|
||||
boolean experimental = false;
|
||||
|
||||
boolean listMethods = false;
|
||||
String methodListFilename = null;
|
||||
|
||||
boolean listFields = false;
|
||||
String fieldListFilename = null;
|
||||
|
||||
boolean listTypes = false;
|
||||
String typeListFilename = null;
|
||||
|
||||
int apiLevel = 15;
|
||||
|
||||
String outputDexFile = "out.dex";
|
||||
@ -153,6 +164,18 @@ public class main {
|
||||
case 'j':
|
||||
jobs = Integer.parseInt(commandLine.getOptionValue("j"));
|
||||
break;
|
||||
case 'm':
|
||||
listMethods = true;
|
||||
methodListFilename = commandLine.getOptionValue("m");
|
||||
break;
|
||||
case 'f':
|
||||
listFields = true;
|
||||
fieldListFilename = commandLine.getOptionValue("f");
|
||||
break;
|
||||
case 't':
|
||||
listTypes = true;
|
||||
typeListFilename = commandLine.getOptionValue("t");
|
||||
break;
|
||||
case 'V':
|
||||
verboseErrors = true;
|
||||
break;
|
||||
@ -232,6 +255,27 @@ public class main {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (listMethods) {
|
||||
if (Strings.isNullOrEmpty(methodListFilename)) {
|
||||
methodListFilename = outputDexFile + ".methods";
|
||||
}
|
||||
writeReferences(dexBuilder.getMethodReferences(), methodListFilename);
|
||||
}
|
||||
|
||||
if (listFields) {
|
||||
if (Strings.isNullOrEmpty(fieldListFilename)) {
|
||||
fieldListFilename = outputDexFile + ".fields";
|
||||
}
|
||||
writeReferences(dexBuilder.getFieldReferences(), fieldListFilename);
|
||||
}
|
||||
|
||||
if (listTypes) {
|
||||
if (Strings.isNullOrEmpty(typeListFilename)) {
|
||||
typeListFilename = outputDexFile + ".types";
|
||||
}
|
||||
writeReferences(dexBuilder.getTypeReferences(), typeListFilename);
|
||||
}
|
||||
|
||||
dexBuilder.writeTo(new FileDataStore(new File(outputDexFile)));
|
||||
} catch (RuntimeException ex) {
|
||||
System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
|
||||
@ -244,6 +288,23 @@ public class main {
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeReferences(List<String> references, String filename) {
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
|
||||
|
||||
for (String reference: Ordering.natural().sortedCopy(references)) {
|
||||
writer.println(reference);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void getSmaliFilesInDir(@Nonnull File dir, @Nonnull Set<File> smaliFiles) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
@ -378,6 +439,27 @@ public class main {
|
||||
.withArgName("API_LEVEL")
|
||||
.create("a");
|
||||
|
||||
Option listMethodsOption = OptionBuilder.withLongOpt("list-methods")
|
||||
.withDescription("Lists all the method references to FILE" +
|
||||
" (<output_dex_filename>.methods by default)")
|
||||
.hasOptionalArg()
|
||||
.withArgName("FILE")
|
||||
.create("m");
|
||||
|
||||
Option listFieldsOption = OptionBuilder.withLongOpt("list-fields")
|
||||
.withDescription("Lists all the field references to FILE" +
|
||||
" (<output_dex_filename>.fields by default)")
|
||||
.hasOptionalArg()
|
||||
.withArgName("FILE")
|
||||
.create("f");
|
||||
|
||||
Option listClassesOption = OptionBuilder.withLongOpt("list-types")
|
||||
.withDescription("Lists all the type references to FILE" +
|
||||
" (<output_dex_filename>.types by default)")
|
||||
.hasOptionalArg()
|
||||
.withArgName("FILE")
|
||||
.create("t");
|
||||
|
||||
Option experimentalOption = OptionBuilder.withLongOpt("experimental")
|
||||
.withDescription("enable experimental opcodes to be assembled, even if they " +
|
||||
" aren't necessarily supported by the Android runtime yet")
|
||||
@ -405,6 +487,9 @@ public class main {
|
||||
basicOptions.addOption(apiLevelOption);
|
||||
basicOptions.addOption(experimentalOption);
|
||||
basicOptions.addOption(jobsOption);
|
||||
basicOptions.addOption(listMethodsOption);
|
||||
basicOptions.addOption(listFieldsOption);
|
||||
basicOptions.addOption(listClassesOption);
|
||||
|
||||
debugOptions.addOption(verboseErrorsOption);
|
||||
debugOptions.addOption(printTokensOption);
|
||||
|
Loading…
x
Reference in New Issue
Block a user