private ObjectNode.ObjectData EncodeEHInfo() { var builder = new ObjectDataBuilder(); builder.Alignment = 1; // TODO: Filter out duplicate clauses builder.EmitCompressedUInt((uint)_ehClauses.Length); for (int i = 0; i < _ehClauses.Length; i++) { var clause = _ehClauses[i]; RhEHClauseKind clauseKind; if (((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FAULT) != 0) || ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FINALLY) != 0)) { clauseKind = RhEHClauseKind.RH_EH_CLAUSE_FAULT; } else if ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FILTER) != 0) { clauseKind = RhEHClauseKind.RH_EH_CLAUSE_FILTER; } else { clauseKind = RhEHClauseKind.RH_EH_CLAUSE_TYPED; } builder.EmitCompressedUInt((uint)clause.TryOffset); // clause.TryLength returned by the JIT is actually end offset... // https://github.com/dotnet/coreclr/issues/3585 int tryLength = (int)clause.TryLength - (int)clause.TryOffset; builder.EmitCompressedUInt((uint)((tryLength << 2) | (int)clauseKind)); switch (clauseKind) { case RhEHClauseKind.RH_EH_CLAUSE_TYPED: { builder.EmitCompressedUInt(clause.HandlerOffset); var methodIL = (MethodIL)HandleToObject((IntPtr)_methodScope); var type = (TypeDesc)methodIL.GetObject((int)clause.ClassTokenOrOffset); var typeSymbol = _compilation.NodeFactory.NecessaryTypeSymbol(type); RelocType rel = (_compilation.NodeFactory.Target.IsWindows) ? RelocType.IMAGE_REL_BASED_ABSOLUTE : RelocType.IMAGE_REL_BASED_REL32; builder.EmitReloc(typeSymbol, rel); } break; case RhEHClauseKind.RH_EH_CLAUSE_FAULT: builder.EmitCompressedUInt(clause.HandlerOffset); break; case RhEHClauseKind.RH_EH_CLAUSE_FILTER: builder.EmitCompressedUInt(clause.HandlerOffset); builder.EmitCompressedUInt(clause.ClassTokenOrOffset); break; } } return builder.ToObjectData(); }