Skip to content

Commit 641254d

Browse files
committed
Fix emitting CodeView information for locals
1 parent 3d3b11a commit 641254d

File tree

4 files changed

+100
-38
lines changed

4 files changed

+100
-38
lines changed

src/coreclr/inc/cvconst.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1580,10 +1580,12 @@ typedef enum CV_HREG_e {
15801580
CV_ARM64_LR = 80,
15811581
CV_ARM64_SP = 81,
15821582
CV_ARM64_ZR = 82,
1583+
CV_ARM64_PC = 83,
15831584

1584-
// statue register
1585+
// status registers
15851586

15861587
CV_ARM64_NZCV = 90,
1588+
CV_ARM64_CPSR = 91,
15871589

15881590
// 32-bit floating point registers
15891591

src/coreclr/tools/aot/ObjWriter/jitDebugInfo.h

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,36 @@
22
#define JIT_DEBUG_INFO_H
33

44
typedef unsigned int DWORD;
5+
6+
#define PORTABILITY_WARNING(msg)
7+
#include "cordebuginfo.h"
8+
9+
// RegNum enumeration is architecture-specific and we need it for all
10+
// architectures we support.
11+
12+
namespace X86 {
13+
#define TARGET_X86 1
14+
#include "cordebuginfo.h"
15+
#undef TARGET_X86
16+
}
17+
18+
namespace Amd64 {
519
#define TARGET_AMD64 1
20+
#include "cordebuginfo.h"
21+
#undef TARGET_AMD64
22+
}
23+
24+
namespace Arm {
25+
#define TARGET_ARM 1
26+
#include "cordebuginfo.h"
27+
#undef TARGET_ARM
28+
}
629

30+
namespace Arm64 {
31+
#define TARGET_ARM64 1
732
#include "cordebuginfo.h"
8-
#include "cvconst.h"
9-
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
33+
#undef TARGET_ARM64
34+
}
1035

1136
struct DebugLocInfo {
1237
int NativeOffset;
@@ -38,18 +63,4 @@ struct DebugEHClauseInfo {
3863
HandlerOffset(HandlerOffset), HandlerLength(HandlerLength) {}
3964
};
4065

41-
typedef unsigned short CVRegMapping;
42-
43-
#define CVREGDAT(p2, cv) cv
44-
45-
const CVRegMapping cvRegMapAmd64[] = {
46-
CVREGDAT(REGNUM_RAX, CV_AMD64_RAX), CVREGDAT(REGNUM_RCX, CV_AMD64_RCX),
47-
CVREGDAT(REGNUM_RDX, CV_AMD64_RDX), CVREGDAT(REGNUM_RBX, CV_AMD64_RBX),
48-
CVREGDAT(REGNUM_RSP, CV_AMD64_RSP), CVREGDAT(REGNUM_RBP, CV_AMD64_RBP),
49-
CVREGDAT(REGNUM_RSI, CV_AMD64_RSI), CVREGDAT(REGNUM_RDI, CV_AMD64_RDI),
50-
CVREGDAT(REGNUM_R8, CV_AMD64_R8), CVREGDAT(REGNUM_R9, CV_AMD64_R9),
51-
CVREGDAT(REGNUM_R10, CV_AMD64_R10), CVREGDAT(REGNUM_R11, CV_AMD64_R11),
52-
CVREGDAT(REGNUM_R12, CV_AMD64_R12), CVREGDAT(REGNUM_R13, CV_AMD64_R13),
53-
CVREGDAT(REGNUM_R14, CV_AMD64_R14), CVREGDAT(REGNUM_R15, CV_AMD64_R15)};
54-
5566
#endif // JIT_DEBUG_INFO_H

src/coreclr/tools/aot/ObjWriter/objwriter.cpp

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "objwriter.h"
1616
#include "debugInfo/dwarf/dwarfTypeBuilder.h"
1717
#include "debugInfo/codeView/codeViewTypeBuilder.h"
18+
#include "cvconst.h"
1819
#include "llvm/DebugInfo/CodeView/CodeView.h"
1920
#include "llvm/DebugInfo/CodeView/Line.h"
2021
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -343,14 +344,18 @@ void ObjectWriter::EmitSymbolDef(const char *SymbolName, bool global) {
343344

344345
Triple TheTriple = TMachine->getTargetTriple();
345346

346-
// A Thumb2 function symbol should be marked with an appropriate ELF
347-
// attribute to make later computation of a relocation address value correct
347+
// An ARM function symbol should be marked with an appropriate ELF attribute
348+
// to make later computation of a relocation address value correct
348349

349350
if (TheTriple.getObjectFormat() == Triple::ELF &&
350351
Streamer->getCurrentSectionOnly()->getKind().isText()) {
351352
switch (TheTriple.getArch()) {
353+
case Triple::arm:
354+
case Triple::armeb:
352355
case Triple::thumb:
356+
case Triple::thumbeb:
353357
case Triple::aarch64:
358+
case Triple::aarch64_be:
354359
Streamer->EmitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
355360
break;
356361
default:
@@ -599,6 +604,51 @@ void ObjectWriter::EmitVarDefRange(const MCSymbol *Fn,
599604
Streamer->EmitIntValue(Range.Range, 2);
600605
}
601606

607+
// Maps an ICorDebugInfo register number to the corresponding CodeView
608+
// register number
609+
CVRegNum ObjectWriter::GetCVRegNum(ICorDebugInfo::RegNum RegNum) {
610+
switch (TMachine->getTargetTriple().getArch()) {
611+
case Triple::x86:
612+
if (X86::ICorDebugInfo::REGNUM_EAX <= RegNum &&
613+
RegNum <= X86::ICorDebugInfo::REGNUM_EDI) {
614+
return RegNum - X86::ICorDebugInfo::REGNUM_EAX + CV_REG_EAX;
615+
}
616+
break;
617+
case Triple::x86_64:
618+
if (Amd64::ICorDebugInfo::REGNUM_RAX <= RegNum &&
619+
RegNum <= Amd64::ICorDebugInfo::REGNUM_R15) {
620+
return RegNum - Amd64::ICorDebugInfo::REGNUM_RAX + CV_AMD64_RAX;
621+
}
622+
break;
623+
case Triple::arm:
624+
case Triple::armeb:
625+
case Triple::thumb:
626+
case Triple::thumbeb:
627+
if (Arm::ICorDebugInfo::REGNUM_R0 <= RegNum &&
628+
RegNum <= Arm::ICorDebugInfo::REGNUM_PC) {
629+
return RegNum - Arm::ICorDebugInfo::REGNUM_R0 + CV_ARM_R0;
630+
}
631+
break;
632+
case Triple::aarch64:
633+
case Triple::aarch64_be:
634+
if (Arm64::ICorDebugInfo::REGNUM_X0 <= RegNum &&
635+
RegNum < Arm64::ICorDebugInfo::REGNUM_PC) {
636+
return RegNum - Arm64::ICorDebugInfo::REGNUM_X0 + CV_ARM64_X0;
637+
}
638+
// Special registers are ordered FP, LR, SP, PC in the ICorDebugInfo's
639+
// enumeration and FP, LR, SP, *ZR*, PC in the CodeView's enumeration.
640+
// For that reason handle the PC register separately.
641+
if (RegNum == Arm64::ICorDebugInfo::REGNUM_PC) {
642+
return CV_ARM64_PC;
643+
}
644+
break;
645+
default:
646+
assert(false && "Unexpected architecture");
647+
break;
648+
}
649+
return CV_REG_NONE;
650+
}
651+
602652
void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
603653
const DebugVarInfo LocInfos[],
604654
int NumVarInfos) {
@@ -625,8 +675,8 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
625675

626676
// Currently only support integer registers.
627677
// TODO: support xmm registers
628-
if (Range.loc.vlReg.vlrReg >=
629-
sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) {
678+
CVRegNum CVReg = GetCVRegNum(Range.loc.vlReg.vlrReg);
679+
if (CVReg == CV_REG_NONE) {
630680
break;
631681
}
632682
SymbolRecordKind SymbolKind = SymbolRecordKind::DefRangeRegisterSym;
@@ -639,8 +689,9 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
639689
DefRangeRegisterSymbol.Range.Range =
640690
Range.endOffset - Range.startOffset;
641691
DefRangeRegisterSymbol.Range.ISectStart = 0;
642-
DefRangeRegisterSymbol.Hdr.Register =
643-
cvRegMapAmd64[Range.loc.vlReg.vlrReg];
692+
DefRangeRegisterSymbol.Hdr.Register = CVReg;
693+
DefRangeRegisterSymbol.Hdr.MayHaveNoName = 0;
694+
644695
unsigned Length = sizeof(DefRangeRegisterSymbol.Hdr);
645696
Streamer->EmitBytes(
646697
StringRef((char *)&DefRangeRegisterSymbol.Hdr, Length));
@@ -651,16 +702,11 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
651702
case ICorDebugInfo::VLT_STK: {
652703

653704
// TODO: support REGNUM_AMBIENT_SP
654-
if (Range.loc.vlStk.vlsBaseReg >=
655-
sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) {
705+
CVRegNum CVReg = GetCVRegNum(Range.loc.vlStk.vlsBaseReg);
706+
if (CVReg == CV_REG_NONE) {
656707
break;
657708
}
658709

659-
assert(Range.loc.vlStk.vlsBaseReg <
660-
sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0]) &&
661-
"Register number should be in the range of [REGNUM_RAX, "
662-
"REGNUM_R15].");
663-
664710
SymbolRecordKind SymbolKind = SymbolRecordKind::DefRangeRegisterRelSym;
665711
unsigned SizeofDefRangeRegisterRelSym =
666712
sizeof(DefRangeRegisterRelSym::Hdr) +
@@ -672,8 +718,8 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
672718
DefRangeRegisterRelSymbol.Range.Range =
673719
Range.endOffset - Range.startOffset;
674720
DefRangeRegisterRelSymbol.Range.ISectStart = 0;
675-
DefRangeRegisterRelSymbol.Hdr.Register =
676-
cvRegMapAmd64[Range.loc.vlStk.vlsBaseReg];
721+
DefRangeRegisterRelSymbol.Hdr.Register = CVReg;
722+
DefRangeRegisterRelSymbol.Hdr.Flags = 0;
677723
DefRangeRegisterRelSymbol.Hdr.BasePointerOffset =
678724
Range.loc.vlStk.vlsOffset;
679725

@@ -1015,7 +1061,7 @@ void ObjectWriter::EmitARMExIdxPerOffset()
10151061
break;
10161062
case CFI_ADJUST_CFA_OFFSET:
10171063
assert(Reg == DWARF_REG_ILLEGAL &&
1018-
"Unexpected Register Value for OpAdjustCfaOffset");
1064+
"Unexpected Register Value for OpAdjustCfaOffset");
10191065
ATS.emitPad(CFIsPerOffset[i].Offset);
10201066
break;
10211067
case CFI_DEF_CFA_REGISTER:

src/coreclr/tools/aot/ObjWriter/objwriter.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "llvm/CodeGen/AsmPrinter.h"
11-
#include "llvm/MC/MCCodeEmitter.h"
1211
#include "llvm/MC/MCInstrInfo.h"
1312
#include "llvm/MC/MCObjectFileInfo.h"
1413
#include "llvm/Target/TargetOptions.h"
15-
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
14+
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
1615

1716
#include "cfi.h"
1817
#include "jitDebugInfo.h"
19-
#include <string>
20-
#include <set>
21-
#include "debugInfo/typeBuilder.h"
2218
#include "debugInfo/dwarf/dwarfGen.h"
2319

20+
#include <set>
21+
#include <string>
22+
2423
using namespace llvm;
2524
using namespace llvm::codeview;
2625

@@ -39,6 +38,8 @@ using namespace llvm::codeview;
3938
#define STDMETHODCALLTYPE
4039
#endif // defined(HOST_X86) && !defined(HOST_UNIX)
4140

41+
typedef uint16_t CVRegNum;
42+
4243
enum CustomSectionAttributes : int32_t {
4344
CustomSectionAttributes_ReadOnly = 0x0000,
4445
CustomSectionAttributes_Writeable = 0x0001,
@@ -127,6 +128,8 @@ class ObjectWriter {
127128
void EmitCOFFSecRel32Value(MCExpr const *Value);
128129

129130
void EmitVarDefRange(const MCSymbol *Fn, const LocalVariableAddrRange &Range);
131+
132+
CVRegNum GetCVRegNum(ICorDebugInfo::RegNum RegNum);
130133
void EmitCVDebugVarInfo(const MCSymbol *Fn, const DebugVarInfo LocInfos[],
131134
int NumVarInfos);
132135
void EmitCVDebugFunctionInfo(const char *FunctionName, int FunctionSize);

0 commit comments

Comments
 (0)