aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/java/proguard/proguard5.3.3/src/proguard/obfuscate/MappingPrinter.java
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/src/proguard/obfuscate/MappingPrinter.java')
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/obfuscate/MappingPrinter.java365
1 files changed, 365 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/obfuscate/MappingPrinter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/obfuscate/MappingPrinter.java
new file mode 100644
index 0000000000..50f6e49bc0
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/obfuscate/MappingPrinter.java
@@ -0,0 +1,365 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.obfuscate;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+import proguard.optimize.peephole.LineNumberLinearizer;
+
+import java.io.PrintStream;
+import java.util.Stack;
+
+
+/**
+ * This ClassVisitor prints out the renamed classes and class members with
+ * their old names and new names.
+ *
+ * @see ClassRenamer
+ *
+ * @author Eric Lafortune
+ */
+public class MappingPrinter
+extends SimplifiedVisitor
+implements ClassVisitor,
+ MemberVisitor,
+ AttributeVisitor
+{
+ private final PrintStream ps;
+
+ // A field serving as a return value for the visitor methods.
+ private boolean printed;
+
+
+ /**
+ * Creates a new MappingPrinter that prints to <code>System.out</code>.
+ */
+ public MappingPrinter()
+ {
+ this(System.out);
+ }
+
+
+ /**
+ * Creates a new MappingPrinter that prints to the given stream.
+ * @param printStream the stream to which to print
+ */
+ public MappingPrinter(PrintStream printStream)
+ {
+ this.ps = printStream;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ String name = programClass.getName();
+ String newName = ClassObfuscator.newClassName(programClass);
+
+ // Print out the class mapping.
+ ps.println(ClassUtil.externalClassName(name) +
+ " -> " +
+ ClassUtil.externalClassName(newName) +
+ ":");
+
+ // Print out the class members.
+ programClass.fieldsAccept(this);
+ programClass.methodsAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ String fieldName = programField.getName(programClass);
+ String obfuscatedFieldName = MemberObfuscator.newMemberName(programField);
+ if (obfuscatedFieldName == null)
+ {
+ obfuscatedFieldName = fieldName;
+ }
+
+ // Print out the field mapping.
+ ps.println(" " +
+ ClassUtil.externalType(programField.getDescriptor(programClass)) + " " +
+ fieldName +
+ " -> " +
+ obfuscatedFieldName);
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ String methodName = programMethod.getName(programClass);
+ String obfuscatedMethodName = MemberObfuscator.newMemberName(programMethod);
+ if (obfuscatedMethodName == null)
+ {
+ obfuscatedMethodName = methodName;
+ }
+
+ // Print out the method mapping, if it has line numbers.
+ printed = false;
+ programMethod.attributesAccept(programClass, this);
+
+ // Otherwise print out the method mapping without line numbers.
+ if (!printed)
+ {
+ ps.println(" " +
+ ClassUtil.externalMethodReturnType(programMethod.getDescriptor(programClass)) + " " +
+ methodName + JavaConstants.METHOD_ARGUMENTS_OPEN +
+ ClassUtil.externalMethodArguments(programMethod.getDescriptor(programClass)) + JavaConstants.METHOD_ARGUMENTS_CLOSE +
+ " -> " +
+ obfuscatedMethodName);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
+
+
+ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
+ {
+ LineNumberInfo[] lineNumberTable = lineNumberTableAttribute.lineNumberTable;
+ int lineNumberTableLength = lineNumberTableAttribute.u2lineNumberTableLength;
+
+ String methodName = method.getName(clazz);
+ String methodDescriptor = method.getDescriptor(clazz);
+ String obfuscatedMethodName = MemberObfuscator.newMemberName(method);
+ if (obfuscatedMethodName == null)
+ {
+ obfuscatedMethodName = methodName;
+ }
+
+ int lowestLineNumber = lineNumberTableAttribute.getLowestLineNumber();
+ int highestLineNumber = lineNumberTableAttribute.getHighestLineNumber();
+
+ // Does the method have any local line numbers at all?
+ if (lineNumberTableAttribute.getSource(codeAttribute.u4codeLength) == null)
+ {
+ if (lowestLineNumber > 0)
+ {
+ // Print out the line number range of the method,
+ // ignoring line numbers of any inlined methods.
+ ps.println(" " +
+ lowestLineNumber + ":" +
+ highestLineNumber + ":" +
+ ClassUtil.externalMethodReturnType(method.getDescriptor(clazz)) + " " +
+ methodName + JavaConstants.METHOD_ARGUMENTS_OPEN +
+ ClassUtil.externalMethodArguments(method.getDescriptor(clazz)) + JavaConstants.METHOD_ARGUMENTS_CLOSE +
+ " -> " +
+ obfuscatedMethodName);
+ }
+ else
+ {
+ // Print out the method mapping without line numbers.
+ ps.println(" " +
+ ClassUtil.externalMethodReturnType(method.getDescriptor(clazz)) + " " +
+ methodName + JavaConstants.METHOD_ARGUMENTS_OPEN +
+ ClassUtil.externalMethodArguments(method.getDescriptor(clazz)) + JavaConstants.METHOD_ARGUMENTS_CLOSE +
+ " -> " +
+ obfuscatedMethodName);
+ }
+ }
+
+ // Print out the line numbers of any inlined methods and their
+ // enclosing methods.
+ Stack enclosingLineNumbers = new Stack();
+
+ LineNumberInfo previousInfo = new LineNumberInfo(0, 0);
+
+ for (int index = 0; index < lineNumberTableLength; index++)
+ {
+ LineNumberInfo info = lineNumberTable[index];
+
+ // Are we entering or exiting an inlined block (or a merged block)?
+ // We're testing on the identities out of convenience.
+ String previousSource = previousInfo.getSource();
+ String source = info.getSource();
+ if (source != previousSource)
+ {
+ // Are we entering or exiting the block?
+ int previousLineNumber = previousInfo.u2lineNumber;
+ int lineNumber = info.u2lineNumber;
+ if (lineNumber > previousLineNumber)
+ {
+ // We're entering an inlined block.
+ // Accumulate its enclosing line numbers, so they can be
+ // printed out for each inlined block.
+ if (index > 0)
+ {
+ enclosingLineNumbers.push(previousInfo);
+ }
+
+ printInlinedMethodMapping(clazz.getName(),
+ methodName,
+ methodDescriptor,
+ info,
+ enclosingLineNumbers,
+ obfuscatedMethodName);
+ }
+ // TODO: There appear to be cases where the stack is empty at this point, so we've added a check.
+ else if (!enclosingLineNumbers.isEmpty())
+ {
+ // We're exiting an inlined block.
+ // Pop its enclosing line number.
+ enclosingLineNumbers.pop();
+ }
+ }
+
+ previousInfo = info;
+ }
+
+ printed = true;
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Prints out the mapping of the specified inlined methods and its
+ * enclosing methods.
+ */
+ private void printInlinedMethodMapping(String className,
+ String methodName,
+ String methodDescriptor,
+ LineNumberInfo inlinedInfo,
+ Stack enclosingLineNumbers,
+ String obfuscatedMethodName)
+ {
+ String source = inlinedInfo.getSource();
+
+ // Parse the information from the source string of the
+ // inlined method.
+ int separatorIndex1 = source.indexOf('.');
+ int separatorIndex2 = source.indexOf('(', separatorIndex1 + 1);
+ int separatorIndex3 = source.indexOf(':', separatorIndex2 + 1);
+ int separatorIndex4 = source.indexOf(':', separatorIndex3 + 1);
+
+ String inlinedClassName = source.substring(0, separatorIndex1);
+ String inlinedMethodName = source.substring(separatorIndex1 + 1, separatorIndex2);
+ String inlinedMethodDescriptor = source.substring(separatorIndex2, separatorIndex3);
+ String inlinedRange = source.substring(separatorIndex3);
+
+ int startLineNumber = Integer.parseInt(source.substring(separatorIndex3 + 1, separatorIndex4));
+ int endLineNumber = Integer.parseInt(source.substring(separatorIndex4 + 1));
+
+ // Compute the shifted line number range.
+ int shiftedStartLineNumber = inlinedInfo.u2lineNumber;
+ int shiftedEndLineNumber = shiftedStartLineNumber + endLineNumber - startLineNumber;
+
+ // Print out the line number range of the inlined method.
+ ps.println(" " +
+ shiftedStartLineNumber + ":" +
+ shiftedEndLineNumber + ":" +
+ ClassUtil.externalMethodReturnType(inlinedMethodDescriptor) + " " +
+ (inlinedClassName.equals(className) ? "" :
+ ClassUtil.externalClassName(inlinedClassName) + JavaConstants.PACKAGE_SEPARATOR) +
+ inlinedMethodName + JavaConstants.METHOD_ARGUMENTS_OPEN +
+ ClassUtil.externalMethodArguments(inlinedMethodDescriptor) + JavaConstants.METHOD_ARGUMENTS_CLOSE +
+ inlinedRange + " -> " +
+ obfuscatedMethodName);
+
+ // Print out the line numbers of the accumulated enclosing
+ // methods.
+ for (int enclosingIndex = enclosingLineNumbers.size()-1; enclosingIndex >= 0; enclosingIndex--)
+ {
+ LineNumberInfo enclosingInfo =
+ (LineNumberInfo)enclosingLineNumbers.get(enclosingIndex);
+
+ printEnclosingMethodMapping(className,
+ methodName,
+ methodDescriptor,
+ shiftedStartLineNumber + ":" +
+ shiftedEndLineNumber,
+ enclosingInfo,
+ obfuscatedMethodName);
+
+
+ }
+ }
+
+
+ /**
+ * Prints out the mapping of the specified enclosing method.
+ */
+ private void printEnclosingMethodMapping(String className,
+ String methodName,
+ String methodDescriptor,
+ String shiftedRange,
+ LineNumberInfo enclosingInfo,
+ String obfuscatedMethodName)
+ {
+ // Parse the information from the source string of the enclosing
+ // method.
+ String enclosingSource = enclosingInfo.getSource();
+
+ String enclosingClassName;
+ String enclosingMethodName;
+ String enclosingMethodDescriptor;
+ int enclosingLineNumber;
+
+ if (enclosingSource == null)
+ {
+ enclosingClassName = className;
+ enclosingMethodName = methodName;
+ enclosingMethodDescriptor = methodDescriptor;
+ enclosingLineNumber = enclosingInfo.u2lineNumber;
+ }
+ else
+ {
+ int enclosingSeparatorIndex1 = enclosingSource.indexOf('.');
+ int enclosingSeparatorIndex2 = enclosingSource.indexOf('(', enclosingSeparatorIndex1 + 1);
+ int enclosingSeparatorIndex3 = enclosingSource.indexOf(':', enclosingSeparatorIndex2 + 1);
+ int enclosingSeparatorIndex4 = enclosingSource.indexOf(':', enclosingSeparatorIndex3 + 1);
+
+ // We need the first line number to correct the shifted enclosing
+ // line number back to its original range.
+ int firstLineNumber = Integer.parseInt(enclosingSource.substring(enclosingSeparatorIndex3 + 1, enclosingSeparatorIndex4));
+
+ enclosingClassName = enclosingSource.substring(0, enclosingSeparatorIndex1);
+ enclosingMethodName = enclosingSource.substring(enclosingSeparatorIndex1 + 1, enclosingSeparatorIndex2);
+ enclosingMethodDescriptor = enclosingSource.substring(enclosingSeparatorIndex2, enclosingSeparatorIndex3);
+ enclosingLineNumber = (enclosingInfo.u2lineNumber - firstLineNumber) % LineNumberLinearizer.SHIFT_ROUNDING + firstLineNumber;
+ }
+
+ // Print out the line number of the enclosing method.
+ ps.println(" " +
+ shiftedRange + ":" +
+ ClassUtil.externalMethodReturnType(enclosingMethodDescriptor) + " " +
+ (enclosingClassName.equals(className) ? "" :
+ ClassUtil.externalClassName(enclosingClassName) + JavaConstants.PACKAGE_SEPARATOR) +
+ enclosingMethodName + JavaConstants.METHOD_ARGUMENTS_OPEN +
+ ClassUtil.externalMethodArguments(enclosingMethodDescriptor) + JavaConstants.METHOD_ARGUMENTS_CLOSE + ":" +
+ enclosingLineNumber + " -> " +
+ obfuscatedMethodName);
+ }
+}