1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Improved Win32 debugging

This commit is contained in:
Brian Fiete 2019-11-30 13:28:40 -08:00
parent cbae124dd5
commit ad9075d1aa
11 changed files with 86 additions and 39 deletions

View file

@ -1210,3 +1210,4 @@ namespace std
} }
}; };
} }

View file

@ -1816,6 +1816,9 @@ namespace IDE
bool SaveWorkspace() bool SaveWorkspace()
{ {
if (mWorkspace.mNeedsCreate)
mWorkspace.mNeedsCreate = false;
if (!mWorkspace.IsSingleFileWorkspace) if (!mWorkspace.IsSingleFileWorkspace)
{ {
#if !CLI #if !CLI
@ -9376,6 +9379,11 @@ namespace IDE
public void AutoGenerateStartupCode(Project project) public void AutoGenerateStartupCode(Project project)
{ {
// We have to save this to ensure any new project is actually created. Maybe overkill,
// but best to stay conservative since this path won't be heavily tested
if (!SaveAll())
return;
String namespaceName = scope .(); String namespaceName = scope .();
String className = scope .(); String className = scope .();
String startupStr = project.mBeefGlobalOptions.mStartupObject; String startupStr = project.mBeefGlobalOptions.mStartupObject;
@ -9411,6 +9419,8 @@ namespace IDE
String srcPath = scope .(); String srcPath = scope .();
project.mRootFolder.GetFullImportPath(srcPath); project.mRootFolder.GetFullImportPath(srcPath);
Directory.CreateDirectory(srcPath).IgnoreError();
srcPath.Append(Path.DirectorySeparatorChar); srcPath.Append(Path.DirectorySeparatorChar);
srcPath.Append("Program.bf"); srcPath.Append("Program.bf");

View file

@ -14742,6 +14742,7 @@ void BeMCContext::Generate(BeFunction* function)
//mDbgPreferredRegs[8] = X64Reg_RAX; //mDbgPreferredRegs[8] = X64Reg_RAX;
mDebugging = function->mName == mDebugging = function->mName ==
//"?TestPrimitives@Nullable@Tests@bf@@SAXXZ" //"?TestPrimitives@Nullable@Tests@bf@@SAXXZ"
"?Hey@Blurg@bf@@SAHXZ"; "?Hey@Blurg@bf@@SAHXZ";
//"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z"; //"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z";

View file

@ -6113,9 +6113,19 @@ addr_target COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* loc
else else
result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RBP] + defRangeFPRel.offFramePointer; result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RBP] + defRangeFPRel.offFramePointer;
#else #else
if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_ESP) if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_VFRAME)
//result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + BF_ALIGN(dwSubprogram->mFrameBaseLen, 16) + defRangeFPRel.offFramePointer; {
result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen + defRangeFPRel.offFramePointer; if (defRangeFPRel.offFramePointer > 0)
{
// Note that a positive offFramePointer always refers to params, and param fp reg is always EBP-relative.
// If this is not true in some cases then we need to actually pass in knowledge of whether is loc data is
// from a param or not, and we have to store the param fp reg just like the local fp reg (mLocalBaseReg)
result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer;
}
else
//result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer - 4;
result = ((stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen) & ~7) + defRangeFPRel.offFramePointer;
}
else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX) else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX)
result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBX] + defRangeFPRel.offFramePointer; result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBX] + defRangeFPRel.offFramePointer;
else else

View file

@ -780,7 +780,7 @@ void BfContext::ValidateDependencies()
while (itr != mResolvedTypes.end()) while (itr != mResolvedTypes.end())
{ {
auto type = itr.mCurEntry->mValue; auto type = itr.mCurEntry->mValue;
if (type->IsGenericTypeInstance()) if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined))
{ {
// We can't contain deleted generic arguments without being deleted ourselves // We can't contain deleted generic arguments without being deleted ourselves
BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type; BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;

View file

@ -18197,4 +18197,3 @@ void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr)
PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None); PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None);
} }
//

View file

@ -995,6 +995,7 @@ BfIRBuilder::BfIRBuilder(BfModule* module) : BfIRConstHolder(module)
mActiveFunctionHasBody = false; mActiveFunctionHasBody = false;
mHasStarted = false; mHasStarted = false;
mCmdCount = 0; mCmdCount = 0;
mIsBeefBackend = false;
} }
bool BfIRBuilder::HasExports() bool BfIRBuilder::HasExports()
@ -1375,6 +1376,8 @@ void BfIRBuilder::Start(const StringImpl& moduleName, int ptrSize, bool isOptimi
void BfIRBuilder::SetBackend(bool isBeefBackend) void BfIRBuilder::SetBackend(bool isBeefBackend)
{ {
mIsBeefBackend = isBeefBackend;
BF_ASSERT(mIRCodeGen == NULL); BF_ASSERT(mIRCodeGen == NULL);
if (mDbgVerifyCodeGen) if (mDbgVerifyCodeGen)
{ {
@ -1883,11 +1886,12 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine)
bool wantDIData = DbgHasInfo() && (!type->IsUnspecializedType()); bool wantDIData = DbgHasInfo() && (!type->IsUnspecializedType());
// Types that don't have a proper 'defining module' need to be defined in every module they are used // Types that don't have a proper 'defining module' need to be defined in every module they are used
bool isDefiningModule = (type->GetModule() == mModule) || (type->IsFunction()); bool wantsDIForwardDecl = (type->GetModule() != mModule) && (!type->IsFunction());
bool wantsForwardDecl = !isDefiningModule && !forceDefine; // Forward declarations of valuetypes doesn't work in LLVM backend for Win32.....
// if ((!mIsBeefBackend) && (type->IsValueType()))
// wantsDIForwardDecl = false;
if (mModule->mExtensionCount != 0) if (mModule->mExtensionCount != 0)
wantsForwardDecl = true; wantsDIForwardDecl = true;
bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive());
@ -2144,7 +2148,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine)
else else
curDIScope = CreateNamespaceScope(checkType, fileDIScope); curDIScope = CreateNamespaceScope(checkType, fileDIScope);
String typeName = GetDebugTypeName(typeInstance, false); String typeName = GetDebugTypeName(typeInstance, false);
if (wantsForwardDecl) if (wantsDIForwardDecl)
{ {
if (type->IsInterface()) if (type->IsInterface())
{ {
@ -2170,9 +2174,13 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine)
diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type,
typeName, curDIScope, fileDIScope, 0, (int64)BF_ALIGN(typeInstance->mInstSize, typeInstance->mInstAlign) * 8, (int64)typeInstance->mInstAlign * 8, flags); typeName, curDIScope, fileDIScope, 0, (int64)BF_ALIGN(typeInstance->mInstSize, typeInstance->mInstAlign) * 8, (int64)typeInstance->mInstAlign * 8, flags);
mDITemporaryTypes.push_back(typeInstance); mDITemporaryTypes.push_back(typeInstance);
if (!type->IsUnspecializedType())
{
BF_ASSERT(!mDeferredDbgTypeDefs.Contains(type));
mDeferredDbgTypeDefs.Add(type);
}
} }
DbgSetInstType(type, diForwardDecl); DbgSetInstType(type, diForwardDecl);
@ -2257,9 +2265,11 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
bool isGlobalContainer = typeDef->IsGlobalsContainer(); bool isGlobalContainer = typeDef->IsGlobalsContainer();
bool isDefiningModule = true; bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction()));
auto diForwardDecl = DbgGetTypeInst(typeInstance); auto diForwardDecl = DbgGetTypeInst(typeInstance);
//BF_ASSERT(WantsDbgDefinition(type));
llvm::SmallVector<BfIRMDNode, 8> diFieldTypes; llvm::SmallVector<BfIRMDNode, 8> diFieldTypes;
bool isPacked = false; bool isPacked = false;
@ -2330,7 +2340,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
{ {
if (fieldDef->mIsConst) if (fieldDef->mIsConst)
{ {
if (wantDIData) if (isDefiningModule)
{ {
if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry())) if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
{ {
@ -2464,7 +2474,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
} }
else if (fieldDef->mIsStatic) else if (fieldDef->mIsStatic)
{ {
if (wantDIData) if (isDefiningModule)
{ {
int flags = 0; int flags = 0;
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0, auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
@ -2523,6 +2533,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
if (type->IsBoxed()) if (type->IsBoxed())
wantsMethods = false; wantsMethods = false;
if (!isDefiningModule)
wantsMethods = false;
if (wantsMethods) if (wantsMethods)
{ {
for (int methodIdx = 0; methodIdx < (int)typeInstance->mMethodInstanceGroups.size(); methodIdx++) for (int methodIdx = 0; methodIdx < (int)typeInstance->mMethodInstanceGroups.size(); methodIdx++)
@ -2747,6 +2760,18 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
} }
} }
bool BfIRBuilder::WantsDbgDefinition(BfType* type)
{
if ((type->GetModule() == mModule) || (type->IsFunction()))
return true;
// Forward declarations of valuetypes doesn't work in LLVM backend
// if ((!mIsBeefBackend) && (type->IsValueType()))
// return true;
return false;
}
void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine) void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
{ {
// This PopulateType is generally NOT needed, but here is a scenario in which it is: // This PopulateType is generally NOT needed, but here is a scenario in which it is:
@ -2757,7 +2782,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
if (type->IsDataIncomplete()) if (type->IsDataIncomplete())
mModule->PopulateType(type, BfPopulateType_Data); mModule->PopulateType(type, BfPopulateType_Data);
bool isDefiningModule = (type->GetModule() == mModule) || (type->IsFunction()); bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction()));
if (mModule->mExtensionCount != 0) if (mModule->mExtensionCount != 0)
isDefiningModule = false; isDefiningModule = false;
@ -2772,7 +2797,6 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
DbgSetTypeSize(DbgGetType(type), BF_ALIGN(type->mSize, type->mAlign) * 8, type->mAlign * 8); DbgSetTypeSize(DbgGetType(type), BF_ALIGN(type->mSize, type->mAlign) * 8, type->mAlign * 8);
} }
bool wantsForwardDecl = !isDefiningModule && !forceDefine;
bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive());
auto typeInstance = type->ToTypeInstance(); auto typeInstance = type->ToTypeInstance();
@ -2780,12 +2804,6 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
return; return;
auto typeDef = typeInstance->mTypeDef; auto typeDef = typeInstance->mTypeDef;
if (DbgHasInfo() && (!type->IsUnspecializedType()) && (!wantsForwardDecl))
{
BF_ASSERT(!mDeferredDbgTypeDefs.Contains(type));
mDeferredDbgTypeDefs.Add(type);
}
#ifdef BFIR_RENTRY_CHECK #ifdef BFIR_RENTRY_CHECK
ReEntryCheck reEntryCheck(&mDefReentrySet, type); ReEntryCheck reEntryCheck(&mDefReentrySet, type);
@ -3007,12 +3025,17 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
void BfIRBuilder::ReplaceDITemporaryTypes() void BfIRBuilder::ReplaceDITemporaryTypes()
{ {
for (auto typeInstance : mDITemporaryTypes) //for (auto typeInstance : mDITemporaryTypes)
for (int i = 0; i < (int)mDITemporaryTypes.size(); i++)
{ {
if (mTypeMap[typeInstance] == BfIRPopulateType_Full) auto typeInstance = mDITemporaryTypes[i];
auto populateType = mTypeMap[typeInstance];
if (populateType == BfIRPopulateType_Full)
continue; continue;
mTypeMap[typeInstance] = BfIRPopulateType_Eventually_Full;
CreateTypeDefinition(typeInstance, false); CreateTypeDefinition(typeInstance, false);
mTypeMap[typeInstance] = BfIRPopulateType_Full;
} }
mDITemporaryTypes.Clear(); mDITemporaryTypes.Clear();
} }
@ -4510,8 +4533,9 @@ void BfIRBuilder::DbgFinalize()
{ {
while ((!mDeferredDbgTypeDefs.IsEmpty()) || (!mDITemporaryTypes.IsEmpty())) while ((!mDeferredDbgTypeDefs.IsEmpty()) || (!mDITemporaryTypes.IsEmpty()))
{ {
for (auto deferredType : mDeferredDbgTypeDefs) //for (auto deferredType : mDeferredDbgTypeDefs)
CreateDbgTypeDefinition(deferredType); for (int i = 0; i < (int)mDeferredDbgTypeDefs.size(); i++)
CreateDbgTypeDefinition(mDeferredDbgTypeDefs[i]);
mDeferredDbgTypeDefs.Clear(); mDeferredDbgTypeDefs.Clear();
ReplaceDITemporaryTypes(); ReplaceDITemporaryTypes();

View file

@ -849,6 +849,7 @@ public:
bool mDbgVerifyCodeGen; bool mDbgVerifyCodeGen;
int mCurFakeId; int mCurFakeId;
bool mHasGlobalDefs; bool mHasGlobalDefs;
bool mIsBeefBackend;
int mNumFunctionsWithBodies; int mNumFunctionsWithBodies;
int mBlockCount; int mBlockCount;
bool mHasStarted; bool mHasStarted;
@ -938,6 +939,7 @@ public:
BfIRMDNode CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope); BfIRMDNode CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope);
String GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName); String GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName);
void CreateDbgTypeDefinition(BfType* type); void CreateDbgTypeDefinition(BfType* type);
bool WantsDbgDefinition(BfType * type);
void CreateTypeDeclaration(BfType* type, bool forceDefine); void CreateTypeDeclaration(BfType* type, bool forceDefine);
void CreateTypeDefinition(BfType* type, bool forceDefine); void CreateTypeDefinition(BfType* type, bool forceDefine);
void ReplaceDITemporaryTypes(); void ReplaceDITemporaryTypes();

View file

@ -351,7 +351,7 @@ public:
enum LocalBaseRegKind : uint8 enum LocalBaseRegKind : uint8
{ {
LocalBaseRegKind_None, LocalBaseRegKind_None,
LocalBaseRegKind_ESP, LocalBaseRegKind_VFRAME,
LocalBaseRegKind_EBP, LocalBaseRegKind_EBP,
LocalBaseRegKind_EBX LocalBaseRegKind_EBX
}; };

View file

@ -2150,8 +2150,8 @@ int DebugTarget::GetFrameBaseRegister(DbgSubprogram* dwSubprogram)
} }
#ifdef BF_DBG_32 #ifdef BF_DBG_32
if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_ESP) if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_VFRAME)
return X86Reg_ESP; return X86Reg_EBP;
else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX) else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX)
return X86Reg_EBX; return X86Reg_EBX;
return X86Reg_EBP; return X86Reg_EBP;