mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 12:02:21 +02:00
Improved Win32 debugging
This commit is contained in:
parent
cbae124dd5
commit
ad9075d1aa
11 changed files with 86 additions and 39 deletions
|
@ -1210,3 +1210,4 @@ namespace std
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
//
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue