static void emitDwarfSetLineAddr(MCObjectStreamer &OS, int64_t LineDelta, const MCSymbol *Label, int PointerSize) { // emit the sequence to set the address OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1); OS.EmitULEB128IntValue(PointerSize + 1); OS.EmitIntValue(dwarf::DW_LNE_set_address, 1); OS.EmitSymbolValue(Label, PointerSize); // emit the sequence for the LineDelta (from 1) and a zero address delta. MCDwarfLineAddr::Emit(&OS, LineDelta, 0); }
static void EmitVarDefRange(MCObjectStreamer &OST, const MCSymbol *Fn, LocalVariableAddrRange &Range) { const MCSymbolRefExpr *BaseSym = MCSymbolRefExpr::create(Fn, OST.getContext()); const MCExpr *Offset = MCConstantExpr::create(Range.OffsetStart, OST.getContext()); const MCExpr *Expr = MCBinaryExpr::createAdd(BaseSym, Offset, OST.getContext()); OST.EmitCOFFSecRel32Value(Expr); OST.EmitCOFFSectionIndex(Fn); OST.EmitIntValue(Range.Range, 2); }
static void EmitCVDebugVarInfo(MCObjectStreamer &OST, const MCSymbol *Fn, DebugVarInfo LocInfos[], int NumVarInfos) { for (int I = 0; I < NumVarInfos; I++) { // Emit an S_LOCAL record DebugVarInfo Var = LocInfos[I]; LocalSym Sym = {}; int SizeofSym = sizeof(LocalSym); EmitSymRecord(OST, SizeofSym + Var.Name.length() + 1, SymbolRecordKind::S_LOCAL); Sym.Type = TypeIndex(Var.TypeIndex); if (Var.IsParam) { Sym.Flags |= LocalSym::IsParameter; } OST.EmitBytes(StringRef((char *)&Sym, SizeofSym)); OST.EmitBytes(StringRef(Var.Name.c_str(), Var.Name.length() + 1)); for (const auto &Range : Var.Ranges) { // Emit a range record switch (Range.loc.vlType) { case ICorDebugInfo::VLT_REG: case ICorDebugInfo::VLT_REG_FP: { DefRangeRegisterSym Rec = {}; Rec.Range.OffsetStart = Range.startOffset; Rec.Range.Range = Range.endOffset - Range.startOffset; Rec.Range.ISectStart = 0; // Currently only support integer registers. // TODO: support xmm registers if (Range.loc.vlReg.vlrReg >= sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) { break; } Rec.Register = cvRegMapAmd64[Range.loc.vlReg.vlrReg]; EmitSymRecord(OST, sizeof(DefRangeRegisterSym), SymbolRecordKind::S_DEFRANGE_REGISTER); OST.EmitBytes( StringRef((char *)&Rec, offsetof(DefRangeRegisterSym, Range))); EmitVarDefRange(OST, Fn, Rec.Range); break; } case ICorDebugInfo::VLT_STK: { DefRangeRegisterRelSym Rec = {}; Rec.Range.OffsetStart = Range.startOffset; Rec.Range.Range = Range.endOffset - Range.startOffset; Rec.Range.ISectStart = 0; // TODO: support REGNUM_AMBIENT_SP if (Range.loc.vlStk.vlsBaseReg >= sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) { break; } assert(Range.loc.vlStk.vlsBaseReg < sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0]) && "Register number should be in the range of [REGNUM_RAX, " "REGNUM_R15]."); Rec.BaseRegister = cvRegMapAmd64[Range.loc.vlStk.vlsBaseReg]; Rec.BasePointerOffset = Range.loc.vlStk.vlsOffset; EmitSymRecord(OST, sizeof(DefRangeRegisterRelSym), SymbolRecordKind::S_DEFRANGE_REGISTER_REL); OST.EmitBytes( StringRef((char *)&Rec, offsetof(DefRangeRegisterRelSym, Range))); EmitVarDefRange(OST, Fn, Rec.Range); break; } case ICorDebugInfo::VLT_REG_BYREF: case ICorDebugInfo::VLT_STK_BYREF: case ICorDebugInfo::VLT_REG_REG: case ICorDebugInfo::VLT_REG_STK: case ICorDebugInfo::VLT_STK_REG: case ICorDebugInfo::VLT_STK2: case ICorDebugInfo::VLT_FPSTK: case ICorDebugInfo::VLT_FIXED_VA: // TODO: for optimized debugging break; default: assert(!"Unknown varloc type!"); break; } } } }
static void EmitSymRecord(MCObjectStreamer &OST, int Size, SymbolRecordKind SymbolKind) { SymRecord Rec = {ulittle16_t(Size + sizeof(ulittle16_t)), ulittle16_t(SymbolKind)}; OST.EmitBytes(StringRef((char *)&Rec, sizeof(Rec))); }