Wasm: emit simple DW_TAG_subprogram DIEs (however, no success with debuggers).

This commit is contained in:
Alexey Andreev 2022-11-19 13:00:17 +01:00
parent f06ba832d7
commit 06bcaec1e5
5 changed files with 37 additions and 4 deletions

View File

@ -21,6 +21,7 @@ public final class DwarfConstants {
public static final int DW_UT_COMPILE = 0x01; public static final int DW_UT_COMPILE = 0x01;
public static final int DW_TAG_COMPILE_UNIT = 0x11; public static final int DW_TAG_COMPILE_UNIT = 0x11;
public static final int DW_TAG_SUBPROGRAM = 0x2E;
public static final int DW_AT_NAME = 0x03; public static final int DW_AT_NAME = 0x03;
public static final int DW_AT_STMT_LIST = 0x10; public static final int DW_AT_STMT_LIST = 0x10;

View File

@ -48,7 +48,7 @@ public class BlobReader {
var offsetInChunk = this.offsetInChunk; var offsetInChunk = this.offsetInChunk;
while (ptr < to) { while (ptr < to) {
var chunk = blob.chunkAt(currentChunk); var chunk = blob.chunkAt(currentChunk);
var limit = Math.min(ptr + chunk.length, to); var limit = Math.min(ptr + chunk.length - offsetInChunk, to);
var bytesToWrite = limit - ptr; var bytesToWrite = limit - ptr;
consumer.accept(chunk, offsetInChunk, offsetInChunk + bytesToWrite); consumer.accept(chunk, offsetInChunk, offsetInChunk + bytesToWrite);
offsetInChunk += bytesToWrite; offsetInChunk += bytesToWrite;

View File

@ -30,7 +30,7 @@ import org.teavm.backend.wasm.model.WasmCustomSection;
public class DwarfGenerator { public class DwarfGenerator {
private DwarfInfoWriter infoWriter = new DwarfInfoWriter(); private DwarfInfoWriter infoWriter = new DwarfInfoWriter();
private DwarfPlaceholder endOfSection; private DwarfPlaceholder endOfSection;
private DwarfStrings strings = new DwarfStrings(); public final DwarfStrings strings = new DwarfStrings();
private DwarfStrings lineStrings = new DwarfStrings(); private DwarfStrings lineStrings = new DwarfStrings();
private DwarfLinesGenerator lines = new DwarfLinesGenerator(lineStrings); private DwarfLinesGenerator lines = new DwarfLinesGenerator(lineStrings);
private Marker highPcMarker; private Marker highPcMarker;
@ -89,8 +89,10 @@ public class DwarfGenerator {
} }
public void setCodeSize(int codeSize) { public void setCodeSize(int codeSize) {
var backup = infoWriter.marker();
highPcMarker.rewind(); highPcMarker.rewind();
infoWriter.writeInt(codeSize); infoWriter.writeInt(codeSize);
backup.rewind();
} }
public Collection<? extends WasmCustomSection> createSections() { public Collection<? extends WasmCustomSection> createSections() {
@ -119,4 +121,8 @@ public class DwarfGenerator {
public void lineNumber(int address, String fileName, int lineNumber) { public void lineNumber(int address, String fileName, int lineNumber) {
lines.lineNumber(address, fileName, lineNumber); lines.lineNumber(address, fileName, lineNumber);
} }
public DwarfInfoWriter getInfoWriter() {
return infoWriter;
}
} }

View File

@ -20,11 +20,11 @@ import com.carrotsearch.hppc.ObjectIntMap;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.teavm.backend.wasm.dwarf.blob.Blob; import org.teavm.backend.wasm.dwarf.blob.Blob;
class DwarfStrings { public class DwarfStrings {
final Blob blob = new Blob(); final Blob blob = new Blob();
private ObjectIntMap<String> offsets = new ObjectIntHashMap<>(); private ObjectIntMap<String> offsets = new ObjectIntHashMap<>();
int stringRef(String s) { public int stringRef(String s) {
int ptr = offsets.getOrDefault(s, -1); int ptr = offsets.getOrDefault(s, -1);
if (ptr < 0) { if (ptr < 0) {
ptr = blob.size(); ptr = blob.size();

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.backend.wasm.render; package org.teavm.backend.wasm.render;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -23,6 +24,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
import org.teavm.backend.wasm.dwarf.DwarfConstants;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
import org.teavm.backend.wasm.generate.DwarfGenerator; import org.teavm.backend.wasm.generate.DwarfGenerator;
import org.teavm.backend.wasm.model.WasmCustomSection; import org.teavm.backend.wasm.model.WasmCustomSection;
import org.teavm.backend.wasm.model.WasmFunction; import org.teavm.backend.wasm.model.WasmFunction;
@ -55,6 +59,8 @@ public class WasmBinaryRenderer {
private Map<String, Integer> functionIndexes = new HashMap<>(); private Map<String, Integer> functionIndexes = new HashMap<>();
private boolean obfuscated; private boolean obfuscated;
private DwarfGenerator dwarfGenerator; private DwarfGenerator dwarfGenerator;
private DwarfInfoWriter infoWriter;
private DwarfAbbreviation methodAbbrev;
public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated, public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated,
DwarfGenerator dwarfGenerator) { DwarfGenerator dwarfGenerator) {
@ -62,6 +68,7 @@ public class WasmBinaryRenderer {
this.version = version; this.version = version;
this.obfuscated = obfuscated; this.obfuscated = obfuscated;
this.dwarfGenerator = dwarfGenerator; this.dwarfGenerator = dwarfGenerator;
infoWriter = dwarfGenerator != null ? dwarfGenerator.getInfoWriter() : null;
} }
public void render(WasmModule module) { public void render(WasmModule module) {
@ -317,9 +324,28 @@ public class WasmBinaryRenderer {
} }
code.writeByte(0x0B); code.writeByte(0x0B);
if (dwarfGenerator != null && function.getName() != null) {
infoWriter.tag(getMethodAbbrev());
infoWriter.writeInt(dwarfGenerator.strings.stringRef(function.getName()));
infoWriter.writeInt(offset);
infoWriter.writeInt(offset + code.getPosition());
infoWriter.emptyTag();
}
return code.getData(); return code.getData();
} }
private DwarfAbbreviation getMethodAbbrev() {
if (methodAbbrev == null) {
methodAbbrev = infoWriter.abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
data.writeLEB(DwarfConstants.DW_AT_NAME).writeLEB(DwarfConstants.DW_FORM_STRP);
data.writeLEB(DwarfConstants.DW_AT_LOW_PC).writeLEB(DwarfConstants.DW_FORM_ADDR);
data.writeLEB(DwarfConstants.DW_AT_HIGH_PC).writeLEB(DwarfConstants.DW_FORM_ADDR);
});
}
return methodAbbrev;
}
private void renderInitializer(WasmBinaryWriter output, int value) { private void renderInitializer(WasmBinaryWriter output, int value) {
output.writeByte(0x41); output.writeByte(0x41);
output.writeLEB(value); output.writeLEB(value);