Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/coreclr/inc/cvconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -1580,10 +1580,12 @@ typedef enum CV_HREG_e {
CV_ARM64_LR = 80,
CV_ARM64_SP = 81,
CV_ARM64_ZR = 82,
CV_ARM64_PC = 83,

// statue register
// status registers

CV_ARM64_NZCV = 90,
CV_ARM64_CPSR = 91,

// 32-bit floating point registers

Expand Down
43 changes: 27 additions & 16 deletions src/coreclr/tools/aot/ObjWriter/jitDebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,36 @@
#define JIT_DEBUG_INFO_H

typedef unsigned int DWORD;

#define PORTABILITY_WARNING(msg)
#include "cordebuginfo.h"

// RegNum enumeration is architecture-specific and we need it for all
// architectures we support.

namespace X86 {
#define TARGET_X86 1
#include "cordebuginfo.h"
#undef TARGET_X86
}

namespace Amd64 {
#define TARGET_AMD64 1
#include "cordebuginfo.h"
#undef TARGET_AMD64
}

namespace Arm {
#define TARGET_ARM 1
#include "cordebuginfo.h"
#undef TARGET_ARM
}

namespace Arm64 {
#define TARGET_ARM64 1
#include "cordebuginfo.h"
#include "cvconst.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#undef TARGET_ARM64
}

struct DebugLocInfo {
int NativeOffset;
Expand Down Expand Up @@ -38,18 +63,4 @@ struct DebugEHClauseInfo {
HandlerOffset(HandlerOffset), HandlerLength(HandlerLength) {}
};

typedef unsigned short CVRegMapping;

#define CVREGDAT(p2, cv) cv

const CVRegMapping cvRegMapAmd64[] = {
CVREGDAT(REGNUM_RAX, CV_AMD64_RAX), CVREGDAT(REGNUM_RCX, CV_AMD64_RCX),
CVREGDAT(REGNUM_RDX, CV_AMD64_RDX), CVREGDAT(REGNUM_RBX, CV_AMD64_RBX),
CVREGDAT(REGNUM_RSP, CV_AMD64_RSP), CVREGDAT(REGNUM_RBP, CV_AMD64_RBP),
CVREGDAT(REGNUM_RSI, CV_AMD64_RSI), CVREGDAT(REGNUM_RDI, CV_AMD64_RDI),
CVREGDAT(REGNUM_R8, CV_AMD64_R8), CVREGDAT(REGNUM_R9, CV_AMD64_R9),
CVREGDAT(REGNUM_R10, CV_AMD64_R10), CVREGDAT(REGNUM_R11, CV_AMD64_R11),
CVREGDAT(REGNUM_R12, CV_AMD64_R12), CVREGDAT(REGNUM_R13, CV_AMD64_R13),
CVREGDAT(REGNUM_R14, CV_AMD64_R14), CVREGDAT(REGNUM_R15, CV_AMD64_R15)};

#endif // JIT_DEBUG_INFO_H
78 changes: 62 additions & 16 deletions src/coreclr/tools/aot/ObjWriter/objwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "objwriter.h"
#include "debugInfo/dwarf/dwarfTypeBuilder.h"
#include "debugInfo/codeView/codeViewTypeBuilder.h"
#include "cvconst.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
Expand Down Expand Up @@ -343,14 +344,18 @@ void ObjectWriter::EmitSymbolDef(const char *SymbolName, bool global) {

Triple TheTriple = TMachine->getTargetTriple();

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

if (TheTriple.getObjectFormat() == Triple::ELF &&
Streamer->getCurrentSectionOnly()->getKind().isText()) {
switch (TheTriple.getArch()) {
case Triple::arm:
case Triple::armeb:
case Triple::thumb:
case Triple::thumbeb:
case Triple::aarch64:
case Triple::aarch64_be:
Streamer->EmitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
break;
default:
Expand Down Expand Up @@ -599,6 +604,51 @@ void ObjectWriter::EmitVarDefRange(const MCSymbol *Fn,
Streamer->EmitIntValue(Range.Range, 2);
}

// Maps an ICorDebugInfo register number to the corresponding CodeView
// register number
CVRegNum ObjectWriter::GetCVRegNum(ICorDebugInfo::RegNum RegNum) {
switch (TMachine->getTargetTriple().getArch()) {
case Triple::x86:
if (X86::ICorDebugInfo::REGNUM_EAX <= RegNum &&
RegNum <= X86::ICorDebugInfo::REGNUM_EDI) {
return RegNum - X86::ICorDebugInfo::REGNUM_EAX + CV_REG_EAX;
}
break;
case Triple::x86_64:
if (Amd64::ICorDebugInfo::REGNUM_RAX <= RegNum &&
RegNum <= Amd64::ICorDebugInfo::REGNUM_R15) {
return RegNum - Amd64::ICorDebugInfo::REGNUM_RAX + CV_AMD64_RAX;
}
break;
case Triple::arm:
case Triple::armeb:
case Triple::thumb:
case Triple::thumbeb:
if (Arm::ICorDebugInfo::REGNUM_R0 <= RegNum &&
RegNum <= Arm::ICorDebugInfo::REGNUM_PC) {
return RegNum - Arm::ICorDebugInfo::REGNUM_R0 + CV_ARM_R0;
}
break;
case Triple::aarch64:
case Triple::aarch64_be:
if (Arm64::ICorDebugInfo::REGNUM_X0 <= RegNum &&
RegNum < Arm64::ICorDebugInfo::REGNUM_PC) {
return RegNum - Arm64::ICorDebugInfo::REGNUM_X0 + CV_ARM64_X0;
}
// Special registers are ordered FP, LR, SP, PC in ICorDebugInfo's
// enumeration and FP, LR, SP, *ZR*, PC in CodeView's enumeration.
// For that reason handle the PC register separately.
if (RegNum == Arm64::ICorDebugInfo::REGNUM_PC) {
return CV_ARM64_PC;
}
break;
default:
assert(false && "Unexpected architecture");
break;
}
return CV_REG_NONE;
}

void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
const DebugVarInfo LocInfos[],
int NumVarInfos) {
Expand All @@ -625,8 +675,8 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,

// Currently only support integer registers.
// TODO: support xmm registers
if (Range.loc.vlReg.vlrReg >=
sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) {
CVRegNum CVReg = GetCVRegNum(Range.loc.vlReg.vlrReg);
if (CVReg == CV_REG_NONE) {
break;
}
SymbolRecordKind SymbolKind = SymbolRecordKind::DefRangeRegisterSym;
Expand All @@ -639,8 +689,9 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
DefRangeRegisterSymbol.Range.Range =
Range.endOffset - Range.startOffset;
DefRangeRegisterSymbol.Range.ISectStart = 0;
DefRangeRegisterSymbol.Hdr.Register =
cvRegMapAmd64[Range.loc.vlReg.vlrReg];
DefRangeRegisterSymbol.Hdr.Register = CVReg;
DefRangeRegisterSymbol.Hdr.MayHaveNoName = 0;

unsigned Length = sizeof(DefRangeRegisterSymbol.Hdr);
Streamer->EmitBytes(
StringRef((char *)&DefRangeRegisterSymbol.Hdr, Length));
Expand All @@ -651,16 +702,11 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
case ICorDebugInfo::VLT_STK: {

// TODO: support REGNUM_AMBIENT_SP
if (Range.loc.vlStk.vlsBaseReg >=
sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0])) {
CVRegNum CVReg = GetCVRegNum(Range.loc.vlStk.vlsBaseReg);
if (CVReg == CV_REG_NONE) {
break;
}

assert(Range.loc.vlStk.vlsBaseReg <
sizeof(cvRegMapAmd64) / sizeof(cvRegMapAmd64[0]) &&
"Register number should be in the range of [REGNUM_RAX, "
"REGNUM_R15].");

SymbolRecordKind SymbolKind = SymbolRecordKind::DefRangeRegisterRelSym;
unsigned SizeofDefRangeRegisterRelSym =
sizeof(DefRangeRegisterRelSym::Hdr) +
Expand All @@ -672,8 +718,8 @@ void ObjectWriter::EmitCVDebugVarInfo(const MCSymbol *Fn,
DefRangeRegisterRelSymbol.Range.Range =
Range.endOffset - Range.startOffset;
DefRangeRegisterRelSymbol.Range.ISectStart = 0;
DefRangeRegisterRelSymbol.Hdr.Register =
cvRegMapAmd64[Range.loc.vlStk.vlsBaseReg];
DefRangeRegisterRelSymbol.Hdr.Register = CVReg;
DefRangeRegisterRelSymbol.Hdr.Flags = 0;
DefRangeRegisterRelSymbol.Hdr.BasePointerOffset =
Range.loc.vlStk.vlsOffset;

Expand Down Expand Up @@ -1015,7 +1061,7 @@ void ObjectWriter::EmitARMExIdxPerOffset()
break;
case CFI_ADJUST_CFA_OFFSET:
assert(Reg == DWARF_REG_ILLEGAL &&
"Unexpected Register Value for OpAdjustCfaOffset");
"Unexpected Register Value for OpAdjustCfaOffset");
ATS.emitPad(CFIsPerOffset[i].Offset);
break;
case CFI_DEF_CFA_REGISTER:
Expand Down
13 changes: 8 additions & 5 deletions src/coreclr/tools/aot/ObjWriter/objwriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"

#include "cfi.h"
#include "jitDebugInfo.h"
#include <string>
#include <set>
#include "debugInfo/typeBuilder.h"
#include "debugInfo/dwarf/dwarfGen.h"

#include <set>
#include <string>

using namespace llvm;
using namespace llvm::codeview;

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

typedef uint16_t CVRegNum;

enum CustomSectionAttributes : int32_t {
CustomSectionAttributes_ReadOnly = 0x0000,
CustomSectionAttributes_Writeable = 0x0001,
Expand Down Expand Up @@ -127,6 +128,8 @@ class ObjectWriter {
void EmitCOFFSecRel32Value(MCExpr const *Value);

void EmitVarDefRange(const MCSymbol *Fn, const LocalVariableAddrRange &Range);

CVRegNum GetCVRegNum(ICorDebugInfo::RegNum RegNum);
void EmitCVDebugVarInfo(const MCSymbol *Fn, const DebugVarInfo LocInfos[],
int NumVarInfos);
void EmitCVDebugFunctionInfo(const char *FunctionName, int FunctionSize);
Expand Down