diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index d49ec0a1de4b06..b31344e0b62621 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -916,6 +916,17 @@ enum class CorInfoReloc RISCV64_CALL_PLT, // RiscV64: auipc + jalr RISCV64_PCREL_I, // RiscV64: auipc + I-type RISCV64_PCREL_S, // RiscV64: auipc + S-type + + // Wasm relocs + WASM_FUNCTION_INDEX_LEB, // Wasm: a function index encoded as a 5-byte varuint32. Used for the immediate argument of a call instruction. + WASM_TABLE_INDEX_SLEB, // Wasm: a function table index encoded as a 5-byte varint32. Used to refer to the immediate argument of a + // i32.const instruction, e.g. taking the address of a function. + WASM_MEMORY_ADDR_LEB, // Wasm: a linear memory index encoded as a 5-byte varuint32. Used for the immediate argument of a load or store instruction, + // e.g. directly loading from or storing to a C++ global. + WASM_MEMORY_ADDR_SLEB, // Wasm: a linear memory index encoded as a 5-byte varint32. Used for the immediate argument of a i32.const instruction, + // e.g. taking the address of a C++ global. + WASM_TYPE_INDEX_LEB, // Wasm: a type index encoded as a 5-byte varuint32, e.g. the type immediate in a call_indirect. + WASM_GLOBAL_INDEX_LEB, // Wasm: a global index encoded as a 5-byte varuint32, e.g. the index immediate in a get_global. }; enum CorInfoGCType diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 35ca59ebd8a8e2..c6965ed3a7d9b1 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -1580,7 +1580,7 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize, void* pAddr = helperFunction.addr; // Push indirection cell address onto stack for genEmitCall to dereference - GetEmitter()->emitIns_I(INS_i32_const, emitActualTypeSize(TYP_I_IMPL), (cnsval_ssize_t)pAddr); + GetEmitter()->emitIns_I(INS_i32_const_address, EA_HANDLE_CNS_RELOC, (cnsval_ssize_t)pAddr); params.callType = EC_INDIR_R; } diff --git a/src/coreclr/jit/emitfmtswasm.h b/src/coreclr/jit/emitfmtswasm.h index 226895e975c14a..e10b45828ba996 100644 --- a/src/coreclr/jit/emitfmtswasm.h +++ b/src/coreclr/jit/emitfmtswasm.h @@ -31,7 +31,10 @@ IF_DEF(OPCODE, IS_NONE, NONE) // IF_DEF(BLOCK, IS_NONE, NONE) // <0x40> IF_DEF(RAW_ULEB128, IS_NONE, NONE) // IF_DEF(ULEB128, IS_NONE, NONE) // +IF_DEF(FUNCIDX, IS_NONE, NONE) // IF_DEF(SLEB128, IS_NONE, NONE) // +IF_DEF(MEMADDR, IS_NONE, NONE) // +IF_DEF(FUNCPTR, IS_NONE, NONE) // IF_DEF(F32, IS_NONE, NONE) // IF_DEF(F64, IS_NONE, NONE) // IF_DEF(MEMARG, IS_NONE, NONE) // ( ) diff --git a/src/coreclr/jit/emitwasm.cpp b/src/coreclr/jit/emitwasm.cpp index 907b49b8b972ac..d214c03f2755ed 100644 --- a/src/coreclr/jit/emitwasm.cpp +++ b/src/coreclr/jit/emitwasm.cpp @@ -154,9 +154,9 @@ void emitter::emitIns_Call(const EmitCallParams& params) { case EC_FUNC_TOKEN: ins = params.isJump ? INS_return_call : INS_call; - id = emitNewInstrSC(EA_8BYTE, 0 /* FIXME-WASM: function index reloc */); + id = emitNewInstrSC(EA_HANDLE_CNS_RELOC, 0 /* FIXME-WASM: function index reloc */); id->idIns(ins); - id->idInsFmt(IF_ULEB128); + id->idInsFmt(IF_FUNCIDX); break; case EC_INDIR_R: { @@ -167,10 +167,11 @@ void emitter::emitIns_Call(const EmitCallParams& params) // TODO-WASM: Generate actual list of types and generate reloc // This is here to exercise the new JIT-EE API - CorInfoWasmType types[] = {CORINFO_WASM_TYPE_VOID}; - codeGen->GetCompiler()->info.compCompHnd->getWasmTypeSymbol(types, 1); + CorInfoWasmType types[] = {CORINFO_WASM_TYPE_VOID}; + CORINFO_WASM_TYPE_SYMBOL_HANDLE typeHandle = + codeGen->GetCompiler()->info.compCompHnd->getWasmTypeSymbol(types, 1); - id = emitNewInstrSC(EA_8BYTE, 0 /* FIXME-WASM: type index reloc */); + id = emitNewInstrSC(EA_HANDLE_CNS_RELOC, (cnsval_ssize_t)(void*)typeHandle); id->idIns(ins); id->idInsFmt(IF_CALL_INDIRECT); break; @@ -368,14 +369,15 @@ static uint8_t GetWasmValueTypeCode(WasmValueType type) return typecode_mapping[static_cast(type)]; } -unsigned emitter::instrDesc::idCodeSize() const -{ #ifdef TARGET_WASM32 - static const unsigned PADDED_RELOC_SIZE = 5; +// NOTE: Keep in sync with Relocation.cs +static const unsigned PADDED_RELOC_SIZE = 5; #else #error WASM64 #endif +unsigned emitter::instrDesc::idCodeSize() const +{ unsigned int opcode = GetInsOpcode(idIns()); // Currently, all our instructions have 1 or 2 byte opcodes. @@ -399,15 +401,18 @@ unsigned emitter::instrDesc::idCodeSize() const size = SizeOfULEB128(emitGetLclVarDeclCount(this)) + sizeof(typeCode); break; } + case IF_FUNCIDX: case IF_ULEB128: size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); break; + case IF_MEMADDR: + case IF_FUNCPTR: case IF_SLEB128: size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfSLEB128(emitGetInsSC(this)); break; case IF_CALL_INDIRECT: { - size += SizeOfULEB128(emitGetInsSC(this)); + size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); size += SizeOfULEB128(0); break; } @@ -506,8 +511,42 @@ size_t emitter::emitOutputOpcode(BYTE* dst, instruction ins) return sz; } +size_t emitter::emitOutputPaddedReloc(uint8_t* destination) +{ + static_assert(PADDED_RELOC_SIZE > 1); + // Write zeroes with the bit set that indicates another byte is coming + for (unsigned i = 0; i < PADDED_RELOC_SIZE - 1; i++) + { + destination += emitOutputByte(destination, 0x80); + } + + emitOutputByte(destination, 0x0); + return PADDED_RELOC_SIZE; +} + +size_t emitter::emitOutputConstant(uint8_t* destination, const instrDesc* id, bool isSigned, CorInfoReloc relocType) +{ + if (id->idIsCnsReloc()) + { + emitRecordRelocation(destination, (void*)emitGetInsSC(id), relocType); + return emitOutputPaddedReloc(destination); + } + + if (isSigned) + { + return emitOutputSLEB128(destination, (int64_t)emitGetInsSC(id)); + } + else + { + return emitOutputULEB128(destination, (uint64_t)emitGetInsSC(id)); + } +} + size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { + const bool SIGNED = true; + const bool UNSIGNED = false; + BYTE* dst = *dp; size_t sz = emitSizeOfInsDsc(id); instruction ins = id->idIns(); @@ -527,22 +566,40 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) break; case IF_ULEB128: { + assert(!id->idIsCnsReloc()); dst += emitOutputOpcode(dst, ins); - cnsval_ssize_t constant = emitGetInsSC(id); - dst += emitOutputULEB128(dst, (uint64_t)constant); + dst += emitOutputULEB128(dst, (uint64_t)emitGetInsSC(id)); break; } case IF_SLEB128: { + assert(!id->idIsCnsReloc()); dst += emitOutputOpcode(dst, ins); - cnsval_ssize_t constant = emitGetInsSC(id); - dst += emitOutputSLEB128(dst, (int64_t)constant); + dst += emitOutputSLEB128(dst, (int64_t)emitGetInsSC(id)); + break; + } + case IF_MEMADDR: + { + dst += emitOutputOpcode(dst, ins); + dst += emitOutputConstant(dst, id, SIGNED, CorInfoReloc::WASM_MEMORY_ADDR_SLEB); + break; + } + case IF_FUNCPTR: + { + dst += emitOutputOpcode(dst, ins); + dst += emitOutputConstant(dst, id, SIGNED, CorInfoReloc::WASM_TABLE_INDEX_SLEB); + break; + } + case IF_FUNCIDX: + { + dst += emitOutputOpcode(dst, ins); + dst += emitOutputConstant(dst, id, UNSIGNED, CorInfoReloc::WASM_FUNCTION_INDEX_LEB); break; } case IF_CALL_INDIRECT: { dst += emitOutputByte(dst, opcode); - dst += emitOutputULEB128(dst, (uint64_t)emitGetInsSC(id)); + dst += emitOutputConstant(dst, id, UNSIGNED, CorInfoReloc::WASM_TYPE_INDEX_LEB); dst += emitOutputULEB128(dst, 0); break; } @@ -719,6 +776,7 @@ void emitter::emitDispIns( case IF_RAW_ULEB128: case IF_ULEB128: + case IF_FUNCIDX: { cnsval_ssize_t imm = emitGetInsSC(id); printf(" %llu", (uint64_t)imm); @@ -762,6 +820,8 @@ void emitter::emitDispIns( } break; + case IF_MEMADDR: + case IF_FUNCPTR: case IF_SLEB128: { cnsval_ssize_t imm = emitGetInsSC(id); diff --git a/src/coreclr/jit/emitwasm.h b/src/coreclr/jit/emitwasm.h index 3028635894fd89..8f9b3f535ea737 100644 --- a/src/coreclr/jit/emitwasm.h +++ b/src/coreclr/jit/emitwasm.h @@ -55,3 +55,5 @@ size_t emitOutputULEB128(uint8_t* destination, uint64_t value); size_t emitOutputSLEB128(uint8_t* destination, int64_t value); size_t emitRawBytes(uint8_t* destination, const void* source, size_t count); size_t emitOutputOpcode(BYTE* dst, instruction ins); +size_t emitOutputPaddedReloc(uint8_t* destination); +size_t emitOutputConstant(uint8_t* destination, const instrDesc* id, bool isSigned, CorInfoReloc relocType); diff --git a/src/coreclr/jit/instrswasm.h b/src/coreclr/jit/instrswasm.h index 6cf96023a85e9f..72b8c8d5750522 100644 --- a/src/coreclr/jit/instrswasm.h +++ b/src/coreclr/jit/instrswasm.h @@ -39,9 +39,9 @@ INST(br, "br", 0, IF_ULEB128, 0x0C) INST(br_if, "br_if", 0, IF_ULEB128, 0x0D) INST(br_table, "br_table", 0, IF_ULEB128, 0x0E) INST(return, "return", 0, IF_OPCODE, 0x0F) -INST(call, "call", 0, IF_ULEB128, 0x10) +INST(call, "call", 0, IF_FUNCIDX, 0x10) INST(call_indirect, "call_indirect", 0, IF_CALL_INDIRECT, 0x11) -INST(return_call, "return_call", 0, IF_ULEB128, 0x12) +INST(return_call, "return_call", 0, IF_FUNCIDX, 0x12) INST(return_call_indirect, "return_call_indirect", 0, IF_CALL_INDIRECT, 0x13) INST(drop, "drop", 0, IF_OPCODE, 0x1A) @@ -72,10 +72,14 @@ INST(i32_store16, "i32.store16", 0, IF_MEMARG, 0x3B) // 5.4.7 Numeric Instructions // Constants -INST(i32_const, "i32.const", 0, IF_SLEB128, 0x41) -INST(i64_const, "i64.const", 0, IF_SLEB128, 0x42) -INST(f32_const, "f32.const", 0, IF_F32, 0x43) -INST(f64_const, "f64.const", 0, IF_F64, 0x44) +INST(i32_const, "i32.const", 0, IF_SLEB128, 0x41) +// Pseudo-instructions for relocations +INST(i32_const_address, "i32.const_address", 0, IF_MEMADDR, 0x41) +INST(i32_const_funcptr, "i32.const_funcptr", 0, IF_FUNCPTR, 0x41) +// Constants, continued +INST(i64_const, "i64.const", 0, IF_SLEB128, 0x42) +INST(f32_const, "f32.const", 0, IF_F32, 0x43) +INST(f64_const, "f64.const", 0, IF_F64, 0x44) // Integer comparisons INST(i32_eqz, "i32.eqz", 0, IF_OPCODE, 0x45) INST(i32_eq, "i32.eq", 0, IF_OPCODE, 0x46) diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 66ae7f7264e28d..95a2ffef04ab21 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using ILCompiler.ObjectWriter; namespace ILCompiler.DependencyAnalysis { @@ -38,6 +39,17 @@ public enum RelocType IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A = 0x82, // ADD/ADDS (immediate) with zero shift, for page offset IMAGE_REL_BASED_ARM64_PAGEOFFSET_12L = 0x83, // LDR (indexed, unsigned immediate), for page offset + // Wasm relocs + WASM_FUNCTION_INDEX_LEB = 0x200, // Wasm: a function index encoded as a 5-byte varuint32. Used for the immediate argument of a call instruction. + WASM_TABLE_INDEX_SLEB = 0x201, // Wasm: a function table index encoded as a 5-byte varint32. Used to refer to the immediate argument of a + // i32.const instruction, e.g. taking the address of a function. + WASM_MEMORY_ADDR_LEB = 0x202, // Wasm: a linear memory index encoded as a 5-byte varuint32. Used for the immediate argument of a load or store instruction, + // e.g. directly loading from or storing to a C++ global. + WASM_MEMORY_ADDR_SLEB = 0x203, // Wasm: a linear memory index encoded as a 5-byte varint32. Used for the immediate argument of a i32.const instruction, + // e.g. taking the address of a C++ global. + WASM_TYPE_INDEX_LEB = 0x204, // Wasm: a type index encoded as a 5-byte varuint32, e.g. the type immediate in a call_indirect. + WASM_GLOBAL_INDEX_LEB = 0x205, // Wasm: a global index encoded as a 5-byte varuint32, e.g. the index immediate in a get_global. + // // Relocation operators related to TLS access // @@ -81,6 +93,9 @@ public enum RelocType public struct Relocation { + // NOTE: Keep in sync with emitwasm.cpp + private const int WASM_PADDED_RELOC_SIZE_32 = 5; + public readonly RelocType RelocType; public readonly int Offset; public readonly ISymbolNode Target; @@ -621,6 +636,22 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v bool isStype = (relocType is RelocType.IMAGE_REL_BASED_RISCV64_PCREL_S); PutRiscV64AuipcCombo((uint*)location, value, isStype); break; + + case RelocType.WASM_FUNCTION_INDEX_LEB: + case RelocType.WASM_TABLE_INDEX_SLEB: + case RelocType.WASM_TYPE_INDEX_LEB: + case RelocType.WASM_GLOBAL_INDEX_LEB: + // These wasm relocs do not have offsets, just targets + return; + + case RelocType.WASM_MEMORY_ADDR_LEB: + DwarfHelper.WritePaddedULEB128(new Span((byte*)location, WASM_PADDED_RELOC_SIZE_32), checked((ulong)value)); + return; + + case RelocType.WASM_MEMORY_ADDR_SLEB: + DwarfHelper.WritePaddedSLEB128(new Span((byte*)location, WASM_PADDED_RELOC_SIZE_32), value); + return; + default: Debug.Fail("Invalid RelocType: " + relocType); break; @@ -709,6 +740,19 @@ public static unsafe long ReadValue(RelocType relocType, void* location) case RelocType.IMAGE_REL_BASED_RISCV64_PCREL_S: bool isStype = (relocType is RelocType.IMAGE_REL_BASED_RISCV64_PCREL_S); return GetRiscV64AuipcCombo((uint*)location, isStype); + case RelocType.WASM_FUNCTION_INDEX_LEB: + case RelocType.WASM_TABLE_INDEX_SLEB: + case RelocType.WASM_TYPE_INDEX_LEB: + case RelocType.WASM_GLOBAL_INDEX_LEB: + // These wasm relocs do not have offsets, just targets + return 0; + + case RelocType.WASM_MEMORY_ADDR_LEB: + return checked((long)DwarfHelper.ReadULEB128(new ReadOnlySpan(location, WASM_PADDED_RELOC_SIZE_32))); + + case RelocType.WASM_MEMORY_ADDR_SLEB: + return DwarfHelper.ReadSLEB128(new ReadOnlySpan(location, WASM_PADDED_RELOC_SIZE_32)); + default: Debug.Fail("Invalid RelocType: " + relocType); return 0; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs index 8e79cd667ae98c..4bf06bfb6bb9f2 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs @@ -12,7 +12,7 @@ namespace ILCompiler.DependencyAnalysis.Wasm // Represents a WASM type signature, e.g. "(i32, i32) -> (i64)". Used as a relocation target for things like 'call_indirect'. // Does not currently support multiple return values; the return type is always the first type in the array and may be Void. // - public class WasmTypeNode : ObjectNode + public class WasmTypeNode : ObjectNode, ISymbolNode { private readonly CorInfoWasmType[] _types; @@ -49,5 +49,24 @@ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer result = MemoryExtensions.SequenceCompareTo(lhs, rhs); return result; } + + public void AppendMangledName(NameMangler nameMangler, Internal.Text.Utf8StringBuilder sb) + { + sb.Append(nameMangler.CompilationUnitPrefix); + sb.Append("__wasmtype_"u8); + + foreach (var type in _types) + sb.Append(type switch { + CorInfoWasmType.CORINFO_WASM_TYPE_VOID => 'v', + CorInfoWasmType.CORINFO_WASM_TYPE_V128 => 'V', + CorInfoWasmType.CORINFO_WASM_TYPE_F64 => 'd', + CorInfoWasmType.CORINFO_WASM_TYPE_F32 => 'f', + CorInfoWasmType.CORINFO_WASM_TYPE_I64 => 'j', + CorInfoWasmType.CORINFO_WASM_TYPE_I32 => 'i', + _ => throw new NotImplementedException($"Unknown CorInfoWasmType: {type}"), + }); + } + + public int Offset => 0; } } diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/Dwarf/DwarfHelper.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/Dwarf/DwarfHelper.cs index c595781222bfb5..68be8c292aac51 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/Dwarf/DwarfHelper.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/Dwarf/DwarfHelper.cs @@ -79,5 +79,63 @@ public static void WriteSLEB128(IBufferWriter writer, long value) Span buffer = writer.GetSpan((int)SizeOfSLEB128(value)); writer.Advance(WriteSLEB128(buffer, value)); } + + public static void WritePaddedULEB128(Span bytes, ulong value) + { + int actualSize = WriteULEB128(bytes, value); + if (actualSize < bytes.Length) + { + bytes[actualSize - 1] |= 0x80; + bytes.Slice(actualSize, bytes.Length - actualSize - 1).Fill(0x80); + bytes[bytes.Length - 1] = 0x00; + } + } + + public static void WritePaddedSLEB128(Span bytes, long value) + { + int actualSize = WriteSLEB128(bytes, value); + if (actualSize < bytes.Length) + { + byte padValue = value < 0 ? (byte)0x7f : (byte)0x00; + bytes[actualSize - 1] |= 0x80; + bytes.Slice(actualSize, bytes.Length - actualSize - 1).Fill((byte)(padValue | 0x80)); + bytes[bytes.Length - 1] = padValue; + } + } + + public static ulong ReadULEB128(ReadOnlySpan buffer) + { + ulong value = 0; + byte @byte; + int shift = 0, pos = 0; + + do + { + @byte = buffer[pos++]; + value |= ((ulong)@byte & 0x7f) << shift; + shift += 7; + } while ((@byte & 0x80) != 0); + + return value; + } + + public static long ReadSLEB128(ReadOnlySpan buffer) + { + ulong value = 0; + byte @byte; + int shift = 0, pos = 0; + + do + { + @byte = buffer[pos++]; + value |= ((ulong)@byte & 0x7f) << shift; + shift += 7; + } while ((@byte & 0x80) != 0); + + if (((ulong)shift < (8 * sizeof(ulong))) && ((@byte & 0x40) != 0)) + value |= unchecked((ulong)(long)-1) << shift; + + return unchecked((long)value); + } } } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index c532ddb8564778..e67cb80a232fdd 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -4185,6 +4185,12 @@ private RelocType GetRelocType(CorInfoReloc reloc) CorInfoReloc.RISCV64_CALL_PLT => RelocType.IMAGE_REL_BASED_RISCV64_CALL_PLT, CorInfoReloc.RISCV64_PCREL_I => RelocType.IMAGE_REL_BASED_RISCV64_PCREL_I, CorInfoReloc.RISCV64_PCREL_S => RelocType.IMAGE_REL_BASED_RISCV64_PCREL_S, + CorInfoReloc.WASM_FUNCTION_INDEX_LEB => RelocType.WASM_FUNCTION_INDEX_LEB, + CorInfoReloc.WASM_TABLE_INDEX_SLEB => RelocType.WASM_TABLE_INDEX_SLEB, + CorInfoReloc.WASM_MEMORY_ADDR_LEB => RelocType.WASM_MEMORY_ADDR_LEB, + CorInfoReloc.WASM_MEMORY_ADDR_SLEB => RelocType.WASM_MEMORY_ADDR_SLEB, + CorInfoReloc.WASM_TYPE_INDEX_LEB => RelocType.WASM_TYPE_INDEX_LEB, + CorInfoReloc.WASM_GLOBAL_INDEX_LEB => RelocType.WASM_GLOBAL_INDEX_LEB, _ => throw new ArgumentException("Unsupported relocation type: " + reloc), }; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index e72852d5a14ce0..9342151cdf5d11 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -509,6 +509,17 @@ public enum CorInfoReloc RISCV64_CALL_PLT, // RiscV64: auipc + jalr RISCV64_PCREL_I, // RiscV64: auipc + I-type RISCV64_PCREL_S, // RiscV64: auipc + S-type + + // Wasm relocs + WASM_FUNCTION_INDEX_LEB, // Wasm: a function index encoded as a 5-byte varuint32. Used for the immediate argument of a call instruction. + WASM_TABLE_INDEX_SLEB, // Wasm: a function table index encoded as a 5-byte varint32. Used to refer to the immediate argument of a + // i32.const instruction, e.g. taking the address of a function. + WASM_MEMORY_ADDR_LEB, // Wasm: a linear memory index encoded as a 5-byte varuint32. Used for the immediate argument of a load or store instruction, + // e.g. directly loading from or storing to a C++ global. + WASM_MEMORY_ADDR_SLEB, // Wasm: a linear memory index encoded as a 5-byte varint32. Used for the immediate argument of a i32.const instruction, + // e.g. taking the address of a C++ global. + WASM_TYPE_INDEX_LEB, // Wasm: a type index encoded as a 5-byte varuint32, e.g. the type immediate in a call_indirect. + WASM_GLOBAL_INDEX_LEB, // Wasm: a global index encoded as a 5-byte varuint32, e.g. the index immediate in a get_global. } public enum CorInfoGCType