mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: more configuration options to set up stack trace deobfuscation
This commit is contained in:
parent
40d2ab97ec
commit
4f9208c4d4
|
@ -16,7 +16,6 @@
|
||||||
package org.teavm.backend.wasm;
|
package org.teavm.backend.wasm;
|
||||||
|
|
||||||
public enum WasmDebugInfoLevel {
|
public enum WasmDebugInfoLevel {
|
||||||
NONE,
|
|
||||||
DEOBFUSCATION,
|
DEOBFUSCATION,
|
||||||
FULL
|
FULL
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,8 +76,9 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
|
||||||
private BoundCheckInsertion boundCheckInsertion = new BoundCheckInsertion();
|
private BoundCheckInsertion boundCheckInsertion = new BoundCheckInsertion();
|
||||||
private boolean strict;
|
private boolean strict;
|
||||||
private boolean obfuscated;
|
private boolean obfuscated;
|
||||||
private WasmDebugInfoLocation debugLocation;
|
private boolean debugInfo;
|
||||||
private WasmDebugInfoLevel debugLevel;
|
private WasmDebugInfoLocation debugLocation = WasmDebugInfoLocation.EXTERNAL;
|
||||||
|
private WasmDebugInfoLevel debugLevel = WasmDebugInfoLevel.FULL;
|
||||||
private List<WasmGCIntrinsicFactory> intrinsicFactories = new ArrayList<>();
|
private List<WasmGCIntrinsicFactory> intrinsicFactories = new ArrayList<>();
|
||||||
private Map<MethodReference, WasmGCIntrinsic> customIntrinsics = new HashMap<>();
|
private Map<MethodReference, WasmGCIntrinsic> customIntrinsics = new HashMap<>();
|
||||||
private List<WasmGCCustomTypeMapperFactory> customTypeMapperFactories = new ArrayList<>();
|
private List<WasmGCCustomTypeMapperFactory> customTypeMapperFactories = new ArrayList<>();
|
||||||
|
@ -94,11 +95,15 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
|
||||||
this.strict = strict;
|
this.strict = strict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDebugLevel(WasmDebugInfoLevel debugLevel) {
|
public void setDebugInfo(boolean debug) {
|
||||||
|
this.debugInfo = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDebugInfoLevel(WasmDebugInfoLevel debugLevel) {
|
||||||
this.debugLevel = debugLevel;
|
this.debugLevel = debugLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDebugLocation(WasmDebugInfoLocation debugLocation) {
|
public void setDebugInfoLocation(WasmDebugInfoLocation debugLocation) {
|
||||||
this.debugLocation = debugLocation;
|
this.debugLocation = debugLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +336,7 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
|
||||||
GCDebugInfoBuilder debugInfoBuilder) throws IOException {
|
GCDebugInfoBuilder debugInfoBuilder) throws IOException {
|
||||||
var binaryWriter = new WasmBinaryWriter();
|
var binaryWriter = new WasmBinaryWriter();
|
||||||
DebugLines debugLines = null;
|
DebugLines debugLines = null;
|
||||||
if (debugLevel != WasmDebugInfoLevel.NONE) {
|
if (debugInfo) {
|
||||||
debugLines = debugInfoBuilder.lines();
|
debugLines = debugInfoBuilder.lines();
|
||||||
}
|
}
|
||||||
var binaryRenderer = new WasmBinaryRenderer(binaryWriter, WasmBinaryVersion.V_0x1, obfuscated,
|
var binaryRenderer = new WasmBinaryRenderer(binaryWriter, WasmBinaryVersion.V_0x1, obfuscated,
|
||||||
|
@ -353,7 +358,7 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
|
||||||
if (debugLocation == WasmDebugInfoLocation.EXTERNAL) {
|
if (debugLocation == WasmDebugInfoLocation.EXTERNAL) {
|
||||||
var debugInfoData = ExternalDebugFile.write(debugInfoBuilder.build());
|
var debugInfoData = ExternalDebugFile.write(debugInfoBuilder.build());
|
||||||
if (debugInfoData != null) {
|
if (debugInfoData != null) {
|
||||||
try (var output = buildTarget.createResource(outputName + ".tdbg")) {
|
try (var output = buildTarget.createResource(outputName + ".teadbg")) {
|
||||||
output.write(debugInfoData);
|
output.write(debugInfoData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,15 @@
|
||||||
package org.teavm.backend.wasm.debug;
|
package org.teavm.backend.wasm.debug;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
import org.teavm.backend.wasm.model.WasmCustomSection;
|
import org.teavm.backend.wasm.model.WasmCustomSection;
|
||||||
|
import org.teavm.backend.wasm.parser.AddressListener;
|
||||||
|
import org.teavm.backend.wasm.parser.WasmBinaryReader;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryWriter;
|
import org.teavm.backend.wasm.render.WasmBinaryWriter;
|
||||||
|
|
||||||
public final class ExternalDebugFile {
|
public final class ExternalDebugFile {
|
||||||
|
private static final int SIGNATURE = 0x67626474;
|
||||||
|
|
||||||
private ExternalDebugFile() {
|
private ExternalDebugFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +33,8 @@ public final class ExternalDebugFile {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var writer = new WasmBinaryWriter();
|
var writer = new WasmBinaryWriter();
|
||||||
writer.writeInt32(0x67626474);
|
writer.writeInt32(SIGNATURE);
|
||||||
writer.writeInt32(1);
|
writer.writeLEB(1);
|
||||||
for (var section : sections) {
|
for (var section : sections) {
|
||||||
var data = section.getData();
|
var data = section.getData();
|
||||||
writer.writeAsciiString(section.getName());
|
writer.writeAsciiString(section.getName());
|
||||||
|
@ -38,4 +43,29 @@ public final class ExternalDebugFile {
|
||||||
}
|
}
|
||||||
return writer.getData();
|
return writer.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean read(byte[] data, Function<String, SectionDataConsumer> consumer) {
|
||||||
|
if (data.length < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var reader = new WasmBinaryReader(AddressListener.EMPTY, data);
|
||||||
|
var header = reader.readInt32();
|
||||||
|
if (header != SIGNATURE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var version = reader.readLEB();
|
||||||
|
if (version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (reader.ptr < data.length) {
|
||||||
|
var name = reader.readString();
|
||||||
|
var length = reader.readLEB();
|
||||||
|
var sectionConsumer = consumer.apply(name);
|
||||||
|
if (sectionConsumer != null) {
|
||||||
|
sectionConsumer.accept(data, reader.ptr, reader.ptr + length);
|
||||||
|
}
|
||||||
|
reader.ptr += length;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.teavm.backend.wasm.debug;
|
||||||
|
|
||||||
|
public interface SectionDataConsumer {
|
||||||
|
void accept(byte[] data, int start, int end);
|
||||||
|
}
|
|
@ -173,6 +173,13 @@ public class WasmBinaryReader {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int readInt32() {
|
||||||
|
return (data[ptr++] & 0xFF)
|
||||||
|
| ((data[ptr++] & 0xFF) << 8)
|
||||||
|
| ((data[ptr++] & 0xFF) << 16)
|
||||||
|
| ((data[ptr++] & 0xFF) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
public int readFixedInt() {
|
public int readFixedInt() {
|
||||||
return ((data[ptr++] & 0xFF) << 24)
|
return ((data[ptr++] & 0xFF) << 24)
|
||||||
| ((data[ptr++] & 0xFF) << 16)
|
| ((data[ptr++] & 0xFF) << 16)
|
||||||
|
|
|
@ -425,6 +425,9 @@ function jsoImports(imports, context) {
|
||||||
Object.defineProperty(cls, name, descriptor);
|
Object.defineProperty(cls, name, descriptor);
|
||||||
},
|
},
|
||||||
javaObjectToJS(instance, cls) {
|
javaObjectToJS(instance, cls) {
|
||||||
|
if (instance === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
let existing = jsWrappers.get(instance);
|
let existing = jsWrappers.get(instance);
|
||||||
if (typeof existing != "undefined") {
|
if (typeof existing != "undefined") {
|
||||||
let result = existing.deref();
|
let result = existing.deref();
|
||||||
|
@ -604,14 +607,18 @@ async function load(path, options) {
|
||||||
options.installImports(importObj);
|
options.installImports(importObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
let [deobfuscatorFactory, { module, instance }] = await Promise.all([
|
let deobfuscatorOptions = options.stackDeobfuscator || {};
|
||||||
options.attachStackDeobfuscator ? getDeobfuscator(path, options) : Promise.resolve(null),
|
let debugInfoLocation = deobfuscatorOptions.infoLocation || "auto";
|
||||||
WebAssembly.instantiateStreaming(fetch(path), importObj)
|
let [deobfuscatorFactory, { module, instance }, debugInfo] = await Promise.all([
|
||||||
|
deobfuscatorOptions.enabled ? getDeobfuscator(path, deobfuscatorOptions) : Promise.resolve(null),
|
||||||
|
WebAssembly.instantiateStreaming(fetch(path), importObj),
|
||||||
|
fetchExternalDebugInfo(path, debugInfoLocation, deobfuscatorOptions)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
defaultsResult.supplyExports(instance.exports);
|
defaultsResult.supplyExports(instance.exports);
|
||||||
if (deobfuscatorFactory) {
|
if (deobfuscatorFactory) {
|
||||||
let deobfuscator = createDeobfuscator(module, deobfuscatorFactory);
|
let moduleToPass = debugInfoLocation === "auto" || debugInfoLocation === "embedded" ? module : null;
|
||||||
|
let deobfuscator = createDeobfuscator(moduleToPass, debugInfo, deobfuscatorFactory);
|
||||||
if (deobfuscator !== null) {
|
if (deobfuscator !== null) {
|
||||||
defaultsResult.supplyStackDeobfuscator(deobfuscator);
|
defaultsResult.supplyStackDeobfuscator(deobfuscator);
|
||||||
}
|
}
|
||||||
|
@ -637,7 +644,8 @@ async function getDeobfuscator(path, options) {
|
||||||
try {
|
try {
|
||||||
const importObj = {};
|
const importObj = {};
|
||||||
const defaultsResult = defaults(importObj, {});
|
const defaultsResult = defaults(importObj, {});
|
||||||
const { instance } = await WebAssembly.instantiateStreaming(fetch(path + "-deobfuscator.wasm"), importObj);
|
const deobfuscatorPath = options.path || path + "-deobfuscator.wasm";
|
||||||
|
const { instance } = await WebAssembly.instantiateStreaming(fetch(deobfuscatorPath), importObj);
|
||||||
defaultsResult.supplyExports(instance.exports)
|
defaultsResult.supplyExports(instance.exports)
|
||||||
return instance;
|
return instance;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -646,16 +654,25 @@ async function getDeobfuscator(path, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDeobfuscator(module, deobfuscatorFactory) {
|
function createDeobfuscator(module, externalData, deobfuscatorFactory) {
|
||||||
let deobfuscator = null;
|
let deobfuscator = null;
|
||||||
let deobfuscatorInitialized = false;
|
let deobfuscatorInitialized = false;
|
||||||
function ensureDeobfuscator() {
|
function ensureDeobfuscator() {
|
||||||
if (!deobfuscatorInitialized) {
|
if (!deobfuscatorInitialized) {
|
||||||
deobfuscatorInitialized = true;
|
deobfuscatorInitialized = true;
|
||||||
try {
|
if (externalData !== null) {
|
||||||
deobfuscator = deobfuscatorFactory.exports.createForModule.value(module);
|
try {
|
||||||
} catch (e) {
|
deobfuscator = deobfuscatorFactory.exports.createFromExternalFile.value(externalData);
|
||||||
console.warn("Could not load create deobfuscator", e);
|
} catch (e) {
|
||||||
|
console.warn("Could not load create deobfuscator", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deobfuscator == null && module !== null) {
|
||||||
|
try {
|
||||||
|
deobfuscator = deobfuscatorFactory.exports.createForModule.value(module);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Could not create deobfuscator from module data", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -663,4 +680,19 @@ function createDeobfuscator(module, deobfuscatorFactory) {
|
||||||
ensureDeobfuscator();
|
ensureDeobfuscator();
|
||||||
return deobfuscator !== null ? deobfuscator.deobfuscate(addresses) : [];
|
return deobfuscator !== null ? deobfuscator.deobfuscate(addresses) : [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchExternalDebugInfo(path, debugInfoLocation, options) {
|
||||||
|
if (!options.enabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (debugInfoLocation !== "auto" && debugInfoLocation !== "external") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let location = options.externalInfoPath || path + ".teadbg";
|
||||||
|
let response = await fetch(location);
|
||||||
|
if (!response.ok) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new Int8Array(await response.arrayBuffer());
|
||||||
}
|
}
|
|
@ -171,8 +171,8 @@ public class ExportTest {
|
||||||
try {
|
try {
|
||||||
var wasmGCTarget = new WasmGCTarget();
|
var wasmGCTarget = new WasmGCTarget();
|
||||||
wasmGCTarget.setObfuscated(false);
|
wasmGCTarget.setObfuscated(false);
|
||||||
wasmGCTarget.setDebugLocation(WasmDebugInfoLocation.EMBEDDED);
|
wasmGCTarget.setDebugInfoLocation(WasmDebugInfoLocation.EMBEDDED);
|
||||||
wasmGCTarget.setDebugLevel(WasmDebugInfoLevel.DEOBFUSCATION);
|
wasmGCTarget.setDebugInfoLevel(WasmDebugInfoLevel.DEOBFUSCATION);
|
||||||
var teavm = new TeaVMBuilder(wasmGCTarget).build();
|
var teavm = new TeaVMBuilder(wasmGCTarget).build();
|
||||||
var outputDir = new File(wasmGCTargetFile, name);
|
var outputDir = new File(wasmGCTargetFile, name);
|
||||||
teavm.installPlugins();
|
teavm.installPlugins();
|
||||||
|
|
|
@ -211,7 +211,9 @@ function launchWasmGCTest(file, argument, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TeaVM.wasmGC.load(file.path, {
|
TeaVM.wasmGC.load(file.path, {
|
||||||
attachStackDeobfuscator: true,
|
stackDeobfuscator: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
installImports: function(o) {
|
installImports: function(o) {
|
||||||
o.teavmConsole.putcharStdout = putchar;
|
o.teavmConsole.putcharStdout = putchar;
|
||||||
o.teavmConsole.putcharStderr = putcharStderr;
|
o.teavmConsole.putcharStderr = putcharStderr;
|
||||||
|
|
|
@ -38,6 +38,8 @@ import org.teavm.backend.c.generate.ShorteningFileNameProvider;
|
||||||
import org.teavm.backend.c.generate.SimpleFileNameProvider;
|
import org.teavm.backend.c.generate.SimpleFileNameProvider;
|
||||||
import org.teavm.backend.javascript.JSModuleType;
|
import org.teavm.backend.javascript.JSModuleType;
|
||||||
import org.teavm.backend.javascript.JavaScriptTarget;
|
import org.teavm.backend.javascript.JavaScriptTarget;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLocation;
|
||||||
import org.teavm.backend.wasm.WasmGCTarget;
|
import org.teavm.backend.wasm.WasmGCTarget;
|
||||||
import org.teavm.backend.wasm.WasmRuntimeType;
|
import org.teavm.backend.wasm.WasmRuntimeType;
|
||||||
import org.teavm.backend.wasm.WasmTarget;
|
import org.teavm.backend.wasm.WasmTarget;
|
||||||
|
@ -108,6 +110,8 @@ public class TeaVMTool {
|
||||||
private JavaScriptTarget javaScriptTarget;
|
private JavaScriptTarget javaScriptTarget;
|
||||||
private WasmTarget webAssemblyTarget;
|
private WasmTarget webAssemblyTarget;
|
||||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
||||||
|
private WasmDebugInfoLocation wasmDebugInfoLocation = WasmDebugInfoLocation.EXTERNAL;
|
||||||
|
private WasmDebugInfoLevel wasmDebugInfoLevel = WasmDebugInfoLevel.DEOBFUSCATION;
|
||||||
private boolean wasmExceptionsUsed;
|
private boolean wasmExceptionsUsed;
|
||||||
private CTarget cTarget;
|
private CTarget cTarget;
|
||||||
private Set<File> generatedFiles = new HashSet<>();
|
private Set<File> generatedFiles = new HashSet<>();
|
||||||
|
@ -281,6 +285,14 @@ public class TeaVMTool {
|
||||||
this.wasmExceptionsUsed = wasmExceptionsUsed;
|
this.wasmExceptionsUsed = wasmExceptionsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setWasmDebugInfoLocation(WasmDebugInfoLocation wasmDebugInfoLocation) {
|
||||||
|
this.wasmDebugInfoLocation = wasmDebugInfoLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWasmDebugInfoLevel(WasmDebugInfoLevel wasmDebugInfoLevel) {
|
||||||
|
this.wasmDebugInfoLevel = wasmDebugInfoLevel;
|
||||||
|
}
|
||||||
|
|
||||||
public void setHeapDump(boolean heapDump) {
|
public void setHeapDump(boolean heapDump) {
|
||||||
this.heapDump = heapDump;
|
this.heapDump = heapDump;
|
||||||
}
|
}
|
||||||
|
@ -388,6 +400,9 @@ public class TeaVMTool {
|
||||||
var target = new WasmGCTarget();
|
var target = new WasmGCTarget();
|
||||||
target.setObfuscated(obfuscated);
|
target.setObfuscated(obfuscated);
|
||||||
target.setStrict(strict);
|
target.setStrict(strict);
|
||||||
|
target.setDebugInfo(debugInformationGenerated);
|
||||||
|
target.setDebugInfoLevel(debugInformationGenerated ? WasmDebugInfoLevel.FULL : wasmDebugInfoLevel);
|
||||||
|
target.setDebugInfoLocation(wasmDebugInfoLocation);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.tooling.builder;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.backend.javascript.JSModuleType;
|
import org.teavm.backend.javascript.JSModuleType;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLocation;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.tooling.TeaVMSourceFilePolicy;
|
import org.teavm.tooling.TeaVMSourceFilePolicy;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
|
@ -83,6 +85,10 @@ public interface BuildStrategy {
|
||||||
|
|
||||||
void setWasmExceptionsUsed(boolean wasmExceptionsUsed);
|
void setWasmExceptionsUsed(boolean wasmExceptionsUsed);
|
||||||
|
|
||||||
|
void setWasmDebugInfoLevel(WasmDebugInfoLevel wasmDebugInfoLevel);
|
||||||
|
|
||||||
|
void setWasmDebugInfoLocation(WasmDebugInfoLocation wasmDebugInfoLocation);
|
||||||
|
|
||||||
void setMinHeapSize(int minHeapSize);
|
void setMinHeapSize(int minHeapSize);
|
||||||
|
|
||||||
void setMaxHeapSize(int maxHeapSize);
|
void setMaxHeapSize(int maxHeapSize);
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.backend.javascript.JSModuleType;
|
import org.teavm.backend.javascript.JSModuleType;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLocation;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
|
@ -62,6 +64,8 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
private String[] classesToPreserve = new String[0];
|
private String[] classesToPreserve = new String[0];
|
||||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
||||||
private boolean wasmExceptionsUsed;
|
private boolean wasmExceptionsUsed;
|
||||||
|
private WasmDebugInfoLevel wasmDebugInfoLevel;
|
||||||
|
private WasmDebugInfoLocation wasmDebugInfoLocation;
|
||||||
private int minHeapSize = 4 * 1024 * 1024;
|
private int minHeapSize = 4 * 1024 * 1024;
|
||||||
private int maxHeapSize = 128 * 1024 * 1024;
|
private int maxHeapSize = 128 * 1024 * 1024;
|
||||||
private final List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
private final List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||||
|
@ -219,6 +223,16 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
this.wasmExceptionsUsed = wasmExceptionsUsed;
|
this.wasmExceptionsUsed = wasmExceptionsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWasmDebugInfoLevel(WasmDebugInfoLevel wasmDebugInfoLevel) {
|
||||||
|
this.wasmDebugInfoLevel = wasmDebugInfoLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWasmDebugInfoLocation(WasmDebugInfoLocation wasmDebugInfoLocation) {
|
||||||
|
this.wasmDebugInfoLocation = wasmDebugInfoLocation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMinHeapSize(int minHeapSize) {
|
public void setMinHeapSize(int minHeapSize) {
|
||||||
this.minHeapSize = minHeapSize;
|
this.minHeapSize = minHeapSize;
|
||||||
|
@ -273,6 +287,8 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
tool.setCacheDirectory(cacheDirectory != null ? new File(cacheDirectory) : null);
|
tool.setCacheDirectory(cacheDirectory != null ? new File(cacheDirectory) : null);
|
||||||
tool.setWasmVersion(wasmVersion);
|
tool.setWasmVersion(wasmVersion);
|
||||||
tool.setWasmExceptionsUsed(wasmExceptionsUsed);
|
tool.setWasmExceptionsUsed(wasmExceptionsUsed);
|
||||||
|
tool.setWasmDebugInfoLevel(wasmDebugInfoLevel);
|
||||||
|
tool.setWasmDebugInfoLocation(wasmDebugInfoLocation);
|
||||||
tool.setMinHeapSize(minHeapSize);
|
tool.setMinHeapSize(minHeapSize);
|
||||||
tool.setMaxHeapSize(maxHeapSize);
|
tool.setMaxHeapSize(maxHeapSize);
|
||||||
tool.setHeapDump(heapDump);
|
tool.setHeapDump(heapDump);
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.rmi.server.UnicastRemoteObject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.backend.javascript.JSModuleType;
|
import org.teavm.backend.javascript.JSModuleType;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLocation;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
|
@ -192,6 +194,16 @@ public class RemoteBuildStrategy implements BuildStrategy {
|
||||||
request.wasmExceptionsUsed = wasmExceptionsUsed;
|
request.wasmExceptionsUsed = wasmExceptionsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWasmDebugInfoLevel(WasmDebugInfoLevel wasmDebugInfoLevel) {
|
||||||
|
request.wasmDebugInfoLevel = wasmDebugInfoLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWasmDebugInfoLocation(WasmDebugInfoLocation wasmDebugInfoLocation) {
|
||||||
|
request.wasmDebugInfoLocation = wasmDebugInfoLocation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMinHeapSize(int minHeapSize) {
|
public void setMinHeapSize(int minHeapSize) {
|
||||||
request.minHeapSize = minHeapSize;
|
request.minHeapSize = minHeapSize;
|
||||||
|
|
|
@ -162,6 +162,8 @@ public class BuildDaemon extends UnicastRemoteObject implements RemoteBuildServi
|
||||||
tool.setStrict(request.strict);
|
tool.setStrict(request.strict);
|
||||||
tool.setWasmVersion(request.wasmVersion);
|
tool.setWasmVersion(request.wasmVersion);
|
||||||
tool.setWasmExceptionsUsed(request.wasmExceptionsUsed);
|
tool.setWasmExceptionsUsed(request.wasmExceptionsUsed);
|
||||||
|
tool.setWasmDebugInfoLocation(request.wasmDebugInfoLocation);
|
||||||
|
tool.setWasmDebugInfoLevel(request.wasmDebugInfoLevel);
|
||||||
tool.setMinHeapSize(request.minHeapSize);
|
tool.setMinHeapSize(request.minHeapSize);
|
||||||
tool.setMaxHeapSize(request.maxHeapSize);
|
tool.setMaxHeapSize(request.maxHeapSize);
|
||||||
tool.setHeapDump(request.heapDump);
|
tool.setHeapDump(request.heapDump);
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.backend.javascript.JSModuleType;
|
import org.teavm.backend.javascript.JSModuleType;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.backend.wasm.WasmDebugInfoLocation;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.tooling.TeaVMSourceFilePolicy;
|
import org.teavm.tooling.TeaVMSourceFilePolicy;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
|
@ -50,6 +52,8 @@ public class RemoteBuildRequest implements Serializable {
|
||||||
public boolean fastDependencyAnalysis;
|
public boolean fastDependencyAnalysis;
|
||||||
public WasmBinaryVersion wasmVersion;
|
public WasmBinaryVersion wasmVersion;
|
||||||
public boolean wasmExceptionsUsed;
|
public boolean wasmExceptionsUsed;
|
||||||
|
public WasmDebugInfoLocation wasmDebugInfoLocation;
|
||||||
|
public WasmDebugInfoLevel wasmDebugInfoLevel;
|
||||||
public int minHeapSize;
|
public int minHeapSize;
|
||||||
public int maxHeapSize;
|
public int maxHeapSize;
|
||||||
public boolean heapDump;
|
public boolean heapDump;
|
||||||
|
|
|
@ -43,6 +43,7 @@ public final class Compiler {
|
||||||
tool.setTargetFileName(args[2]);
|
tool.setTargetFileName(args[2]);
|
||||||
tool.setObfuscated(true);
|
tool.setObfuscated(true);
|
||||||
tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
||||||
|
tool.setStrict(false);
|
||||||
|
|
||||||
tool.generate();
|
tool.generate();
|
||||||
TeaVMProblemRenderer.describeProblems(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider(), log);
|
TeaVMProblemRenderer.describeProblems(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider(), log);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling.deobfuscate.wasmgc;
|
package org.teavm.tooling.deobfuscate.wasmgc;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import org.teavm.backend.wasm.debug.ExternalDebugFile;
|
||||||
import org.teavm.backend.wasm.debug.parser.LinesDeobfuscationParser;
|
import org.teavm.backend.wasm.debug.parser.LinesDeobfuscationParser;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.jso.JSExport;
|
import org.teavm.jso.JSExport;
|
||||||
|
@ -42,9 +44,29 @@ public final class DeobfuscatorFactory {
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
});
|
});
|
||||||
return new Deobfuscator(parser.getLineInfo());
|
var lineInfo = parser.getLineInfo();
|
||||||
|
return lineInfo != null ? new Deobfuscator(parser.getLineInfo()) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(params = { "module", "name"}, script = "return WebAssembly.Module.customSections(module, name);")
|
@JSBody(params = { "module", "name"}, script = "return WebAssembly.Module.customSections(module, name);")
|
||||||
private static native JSArrayReader<ArrayBuffer> getSection(JSObject module, String name);
|
private static native JSArrayReader<ArrayBuffer> getSection(JSObject module, String name);
|
||||||
|
|
||||||
|
@JSExport
|
||||||
|
public static Deobfuscator createFromExternalFile(byte[] data) {
|
||||||
|
var parser = new LinesDeobfuscationParser();
|
||||||
|
var success = ExternalDebugFile.read(data, sectionName -> {
|
||||||
|
if (!parser.canHandleSection(sectionName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (bytes, start, end) -> parser.applySection(sectionName, Arrays.copyOfRange(bytes, start, end));
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var lineInfo = parser.getLineInfo();
|
||||||
|
if (lineInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new Deobfuscator(lineInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ import org.teavm.gradle.api.TeaVMJSConfiguration;
|
||||||
import org.teavm.gradle.api.TeaVMWasiConfiguration;
|
import org.teavm.gradle.api.TeaVMWasiConfiguration;
|
||||||
import org.teavm.gradle.api.TeaVMWasmConfiguration;
|
import org.teavm.gradle.api.TeaVMWasmConfiguration;
|
||||||
import org.teavm.gradle.api.TeaVMWasmGCConfiguration;
|
import org.teavm.gradle.api.TeaVMWasmGCConfiguration;
|
||||||
|
import org.teavm.gradle.api.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.gradle.api.WasmDebugInfoLocation;
|
||||||
|
|
||||||
class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtension {
|
class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtension {
|
||||||
private TeaVMJSConfiguration js;
|
private TeaVMJSConfiguration js;
|
||||||
|
@ -111,6 +113,12 @@ class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtensio
|
||||||
wasmGC.getCopyRuntime().convention(property("wasm-gc.copyRuntime").map(Boolean::parseBoolean).orElse(true));
|
wasmGC.getCopyRuntime().convention(property("wasm-gc.copyRuntime").map(Boolean::parseBoolean).orElse(true));
|
||||||
wasmGC.getObfuscated().convention(property("wasm-gc.obfuscated").map(Boolean::parseBoolean).orElse(true));
|
wasmGC.getObfuscated().convention(property("wasm-gc.obfuscated").map(Boolean::parseBoolean).orElse(true));
|
||||||
wasmGC.getDisassembly().convention(property("wasm-gc.disassembly").map(Boolean::parseBoolean).orElse(false));
|
wasmGC.getDisassembly().convention(property("wasm-gc.disassembly").map(Boolean::parseBoolean).orElse(false));
|
||||||
|
wasmGC.getDebugInformation().convention(property("wasm-gc.debugInformation").map(Boolean::parseBoolean)
|
||||||
|
.orElse(false));
|
||||||
|
wasmGC.getDebugInfoLocation().convention(property("wasm-gc.debugInformation.location")
|
||||||
|
.map(v -> WasmDebugInfoLocation.valueOf(v.toUpperCase())).orElse(WasmDebugInfoLocation.EXTERNAL));
|
||||||
|
wasmGC.getDebugInfoLevel().convention(property("wasm-gc.debugInformation.level")
|
||||||
|
.map(v -> WasmDebugInfoLevel.valueOf(v.toUpperCase())).orElse(WasmDebugInfoLevel.DEOBFUSCATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWasiDefaults() {
|
private void setupWasiDefaults() {
|
||||||
|
|
|
@ -27,4 +27,8 @@ public interface TeaVMWasmGCConfiguration extends TeaVMCommonConfiguration, TeaV
|
||||||
Property<Boolean> getDisassembly();
|
Property<Boolean> getDisassembly();
|
||||||
|
|
||||||
Property<String> getTargetFileName();
|
Property<String> getTargetFileName();
|
||||||
|
|
||||||
|
Property<WasmDebugInfoLocation> getDebugInfoLocation();
|
||||||
|
|
||||||
|
Property<WasmDebugInfoLevel> getDebugInfoLevel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.teavm.gradle.api;
|
||||||
|
|
||||||
|
public enum WasmDebugInfoLevel {
|
||||||
|
DEOBFUSCATION,
|
||||||
|
FULL
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.teavm.gradle.api;
|
||||||
|
|
||||||
|
public enum WasmDebugInfoLocation {
|
||||||
|
EMBEDDED,
|
||||||
|
EXTERNAL
|
||||||
|
}
|
|
@ -17,6 +17,8 @@ package org.teavm.gradle.tasks;
|
||||||
|
|
||||||
import org.gradle.api.provider.Property;
|
import org.gradle.api.provider.Property;
|
||||||
import org.gradle.api.tasks.Input;
|
import org.gradle.api.tasks.Input;
|
||||||
|
import org.teavm.gradle.api.WasmDebugInfoLevel;
|
||||||
|
import org.teavm.gradle.api.WasmDebugInfoLocation;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
import org.teavm.tooling.builder.BuildStrategy;
|
import org.teavm.tooling.builder.BuildStrategy;
|
||||||
|
|
||||||
|
@ -24,6 +26,9 @@ public abstract class GenerateWasmGCTask extends TeaVMTask {
|
||||||
public GenerateWasmGCTask() {
|
public GenerateWasmGCTask() {
|
||||||
getStrict().convention(true);
|
getStrict().convention(true);
|
||||||
getObfuscated().convention(true);
|
getObfuscated().convention(true);
|
||||||
|
getDebugInfo().convention(true);
|
||||||
|
getDebugInfoLevel().convention(WasmDebugInfoLevel.DEOBFUSCATION);
|
||||||
|
getDebugInfoLocation().convention(WasmDebugInfoLocation.EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
|
@ -32,10 +37,36 @@ public abstract class GenerateWasmGCTask extends TeaVMTask {
|
||||||
@Input
|
@Input
|
||||||
public abstract Property<Boolean> getObfuscated();
|
public abstract Property<Boolean> getObfuscated();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
public abstract Property<Boolean> getDebugInfo();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
public abstract Property<WasmDebugInfoLevel> getDebugInfoLevel();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
public abstract Property<WasmDebugInfoLocation> getDebugInfoLocation();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupBuilder(BuildStrategy builder) {
|
protected void setupBuilder(BuildStrategy builder) {
|
||||||
builder.setStrict(getStrict().get());
|
builder.setStrict(getStrict().get());
|
||||||
builder.setObfuscated(getObfuscated().get());
|
builder.setObfuscated(getObfuscated().get());
|
||||||
|
builder.setDebugInformationGenerated(getDebugInfo().get());
|
||||||
|
switch (getDebugInfoLevel().get()) {
|
||||||
|
case FULL:
|
||||||
|
builder.setWasmDebugInfoLevel(org.teavm.backend.wasm.WasmDebugInfoLevel.FULL);
|
||||||
|
break;
|
||||||
|
case DEOBFUSCATION:
|
||||||
|
builder.setWasmDebugInfoLevel(org.teavm.backend.wasm.WasmDebugInfoLevel.DEOBFUSCATION);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (getDebugInfoLocation().get()) {
|
||||||
|
case EMBEDDED:
|
||||||
|
builder.setWasmDebugInfoLocation(org.teavm.backend.wasm.WasmDebugInfoLocation.EMBEDDED);
|
||||||
|
break;
|
||||||
|
case EXTERNAL:
|
||||||
|
builder.setWasmDebugInfoLocation(org.teavm.backend.wasm.WasmDebugInfoLocation.EXTERNAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
builder.setTargetType(TeaVMTargetType.WEBASSEMBLY_GC);
|
builder.setTargetType(TeaVMTargetType.WEBASSEMBLY_GC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,9 @@ class WebAssemblyGCPlatformSupport extends TestPlatformSupport<WasmGCTarget> {
|
||||||
var target = new WasmGCTarget();
|
var target = new WasmGCTarget();
|
||||||
target.setObfuscated(false);
|
target.setObfuscated(false);
|
||||||
target.setStrict(true);
|
target.setStrict(true);
|
||||||
target.setDebugLevel(WasmDebugInfoLevel.DEOBFUSCATION);
|
target.setDebugInfo(true);
|
||||||
target.setDebugLocation(WasmDebugInfoLocation.EMBEDDED);
|
target.setDebugInfoLevel(WasmDebugInfoLevel.DEOBFUSCATION);
|
||||||
|
target.setDebugInfoLocation(WasmDebugInfoLocation.EMBEDDED);
|
||||||
var sourceDirs = System.getProperty(SOURCE_DIRS);
|
var sourceDirs = System.getProperty(SOURCE_DIRS);
|
||||||
if (sourceDirs != null) {
|
if (sourceDirs != null) {
|
||||||
var dirs = new ArrayList<File>();
|
var dirs = new ArrayList<File>();
|
||||||
|
|
|
@ -25,7 +25,9 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
let instance;
|
let instance;
|
||||||
TeaVM.wasmGC.load("${SCRIPT}", {
|
TeaVM.wasmGC.load("${SCRIPT}", {
|
||||||
attachStackDeobfuscator: true,
|
stackDeobfuscator: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
installImports(o) {
|
installImports(o) {
|
||||||
o.teavmTest = {
|
o.teavmTest = {
|
||||||
success() {
|
success() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user