Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -94,6 +94,7 @@ struct LocalVariable { const DILocalVariable *DIVar = nullptr; SmallVector DefRanges; + bool isRegRelative() const; }; struct InlineSite { @@ -212,6 +213,8 @@ void emitTypeInformation(); + void emitObjectInformation(); + void emitCompilerInformation(); void emitInlineeLinesSubsection(); @@ -251,9 +254,16 @@ /// Emits local variables in the appropriate order. void emitLocalVariableList(ArrayRef Locals); - /// Emits an S_LOCAL record and its associated defined ranges. + /// Emits either an S_LOCAL record and its associated defined ranges, or an + /// S_BPREL32, depending on where the variable lives. void emitLocalVariable(const LocalVariable &Var); + /// Emits an S_LOCAL record and its associated defined ranges. + void emitGenericLocalVariable(const LocalVariable &Var); + + /// Emits an S_BPREL32 or S_REGREL32 symbol. + void emitRegRelativeLocalVariable(const LocalVariable &Var); + /// Translates the DIType to codeview if necessary and returns a type index /// for it. codeview::TypeIndex getTypeIndex(DITypeRef TypeRef, Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -441,6 +441,7 @@ switchToDebugSectionForSymbol(nullptr); MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols); + emitObjectInformation(); emitCompilerInformation(); endCVSubsection(CompilerInfo); @@ -621,6 +622,18 @@ } } +void CodeViewDebug::emitObjectInformation() { + //MCContext &Context = MMI->getContext(); + //MCSymbol *ObjNameBegin = Context.createTempSymbol(), + // *ObjNameEnd = Context.createTempSymbol(); + //OS.AddComment("Record length"); + //OS.emitAbsoluteSymbolDiff(ObjNameEnd, ObjNameBegin, 2); + //OS.EmitLabel(ObjNameBegin); + //OS.AddComment("Record kind: S_OBJNAME"); + //OS.EmitIntValue(SymbolKind::S_OBJNAME, 2); + //uint32_t Flags = 0; +} + void CodeViewDebug::emitCompilerInformation() { MCContext &Context = MMI->getContext(); MCSymbol *CompilerBegin = Context.createTempSymbol(), @@ -2060,10 +2073,53 @@ emitLocalVariable(L); } -void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { +bool CodeViewDebug::LocalVariable::isRegRelative() const { + if (DefRanges.size() != 1) + return false; + if (DefRanges[0].Ranges.size() != 1) + return false; + if (!DefRanges[0].InMemory) + return false; + return true; +} + +void CodeViewDebug::emitRegRelativeLocalVariable(const LocalVariable &Var) { + // BpRelativeSym record, see SymbolRecord.h for more info. + MCSymbol *RegRelBegin = MMI->getContext().createTempSymbol(), + *RegRelEnd = MMI->getContext().createTempSymbol(); + OS.AddComment("Record length"); + OS.emitAbsoluteSymbolDiff(RegRelEnd, RegRelBegin, 2); + OS.EmitLabel(RegRelBegin); + + TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType()); + int32_t Offset = Var.DefRanges[0].DataOffset; + StringRef Name = Var.DIVar->getName(); + if (Var.DefRanges[0].CVRegister == uint16_t(RegisterId::EBP)) { + OS.AddComment("Record kind: S_BPREL32"); + OS.EmitIntValue(unsigned(SymbolKind::S_BPREL32), 2); + OS.AddComment("Base pointer offset"); + OS.EmitIntValue(Offset, 4); + OS.AddComment("TypeIndex"); + OS.EmitIntValue(TI.getIndex(), 4); + emitNullTerminatedSymbolName(OS, Name); + } else { + OS.AddComment("Record kind: S_REGREL32"); + OS.EmitIntValue(unsigned(SymbolKind::S_REGREL32), 2); + OS.AddComment("Register offset"); + OS.EmitIntValue(Offset, 4); + OS.AddComment("TypeIndex"); + OS.EmitIntValue(TI.getIndex(), 4); + OS.AddComment("Register Id"); + OS.EmitIntValue(Var.DefRanges[0].CVRegister, 2); + emitNullTerminatedSymbolName(OS, Name); + } + OS.EmitLabel(RegRelEnd); +} + +void CodeViewDebug::emitGenericLocalVariable(const LocalVariable &Var) { // LocalSym record, see SymbolRecord.h for more info. MCSymbol *LocalBegin = MMI->getContext().createTempSymbol(), - *LocalEnd = MMI->getContext().createTempSymbol(); + *LocalEnd = MMI->getContext().createTempSymbol(); OS.AddComment("Record length"); OS.emitAbsoluteSymbolDiff(LocalEnd, LocalBegin, 2); OS.EmitLabel(LocalBegin); @@ -2096,8 +2152,8 @@ uint16_t RegRelFlags = 0; if (DefRange.IsSubfield) { RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag | - (DefRange.StructOffset - << DefRangeRegisterRelSym::OffsetInParentShift); + (DefRange.StructOffset + << DefRangeRegisterRelSym::OffsetInParentShift); } DefRangeRegisterRelSym Sym(S_DEFRANGE_REGISTER_REL); Sym.Hdr.Register = DefRange.CVRegister; @@ -2105,10 +2161,11 @@ Sym.Hdr.BasePointerOffset = DefRange.DataOffset; ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL); BytePrefix += - StringRef(reinterpret_cast(&SymKind), sizeof(SymKind)); + StringRef(reinterpret_cast(&SymKind), sizeof(SymKind)); BytePrefix += - StringRef(reinterpret_cast(&Sym.Hdr), sizeof(Sym.Hdr)); - } else { + StringRef(reinterpret_cast(&Sym.Hdr), sizeof(Sym.Hdr)); + } + else { assert(DefRange.DataOffset == 0 && "unexpected offset into register"); if (DefRange.IsSubfield) { // Unclear what matters here. @@ -2119,25 +2176,35 @@ ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_SUBFIELD_REGISTER); BytePrefix += StringRef(reinterpret_cast(&SymKind), - sizeof(SymKind)); + sizeof(SymKind)); BytePrefix += StringRef(reinterpret_cast(&Sym.Hdr), - sizeof(Sym.Hdr)); - } else { + sizeof(Sym.Hdr)); + } + else { // Unclear what matters here. DefRangeRegisterSym Sym(S_DEFRANGE_REGISTER); Sym.Hdr.Register = DefRange.CVRegister; Sym.Hdr.MayHaveNoName = 0; ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER); BytePrefix += StringRef(reinterpret_cast(&SymKind), - sizeof(SymKind)); + sizeof(SymKind)); BytePrefix += StringRef(reinterpret_cast(&Sym.Hdr), - sizeof(Sym.Hdr)); + sizeof(Sym.Hdr)); } } OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix); } } +void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { + if (Var.isRegRelative()) { + emitRegRelativeLocalVariable(Var); + return; + } + + emitGenericLocalVariable(Var); +} + void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) { const Function *GV = MF->getFunction(); assert(FnDebugInfo.count(GV));