Skip to content

Commit be30428

Browse files
JohnsterIDxezon
authored andcommitted
fix(compatibility): Add compiler guards and GCC inline assembly for StackDump (#2067)
Add explicit compiler checks and GCC-specific inline assembly implementation for the StackDump function to enable MinGW-w64 support. Changes: - Add #ifdef _MSC_VER guards around MSVC-specific inline assembly - Implement GCC-compatible inline assembly version using __asm__ __volatile__ - Add #error directive for unsupported compilers - Maintain identical functionality across compilers This enables stack dumping functionality to work correctly with both MSVC and MinGW-w64/GCC toolchains.
1 parent bb9acc6 commit be30428

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

Generals/Code/GameEngine/Source/Common/System/StackDump.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ void StackDump(void (*callback)(const char*))
6969

7070
DWORD myeip,myesp,myebp;
7171

72+
#if defined(_MSC_VER)
7273
_asm
7374
{
7475
MYEIP1:
@@ -79,6 +80,20 @@ _asm
7980
mov eax, ebp
8081
mov dword ptr [myebp] , eax
8182
}
83+
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(_M_IX86))
84+
// GCC/Clang inline assembly for x86-32
85+
__asm__ __volatile__(
86+
"call 1f\n\t"
87+
"1: pop %0\n\t"
88+
"mov %%esp, %1\n\t"
89+
"mov %%ebp, %2"
90+
: "=r"(myeip), "=r"(myesp), "=r"(myebp)
91+
:
92+
: "memory"
93+
);
94+
#else
95+
#error "Unsupported compiler or architecture for register capture"
96+
#endif
8297

8398

8499
MakeStackTrace(myeip,myesp,myebp, 2, callback);
@@ -314,6 +329,7 @@ void FillStackAddresses(void**addresses, unsigned int count, unsigned int skip)
314329
gsContext.ContextFlags = CONTEXT_FULL;
315330

316331
DWORD myeip,myesp,myebp;
332+
#if defined(_MSC_VER)
317333
_asm
318334
{
319335
MYEIP2:
@@ -325,6 +341,21 @@ _asm
325341
mov dword ptr [myebp] , eax
326342
xor eax,eax
327343
}
344+
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(_M_IX86))
345+
// GCC/Clang inline assembly for x86-32
346+
__asm__ __volatile__(
347+
"call 1f\n\t"
348+
"1: pop %0\n\t"
349+
"mov %%esp, %1\n\t"
350+
"mov %%ebp, %2\n\t"
351+
"xor %%eax, %%eax"
352+
: "=r"(myeip), "=r"(myesp), "=r"(myebp)
353+
:
354+
: "eax", "memory"
355+
);
356+
#else
357+
#error "Unsupported compiler or architecture for register capture"
358+
#endif
328359
memset(&stack_frame, 0, sizeof(STACKFRAME));
329360
stack_frame.AddrPC.Mode = AddrModeFlat;
330361
stack_frame.AddrPC.Offset = myeip;

GeneralsMD/Code/GameEngine/Source/Common/System/StackDump.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ void StackDump(void (*callback)(const char*))
6969

7070
DWORD myeip,myesp,myebp;
7171

72+
#if defined(_MSC_VER)
7273
_asm
7374
{
7475
MYEIP1:
@@ -79,6 +80,20 @@ _asm
7980
mov eax, ebp
8081
mov dword ptr [myebp] , eax
8182
}
83+
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(_M_IX86))
84+
// GCC/Clang inline assembly for x86-32
85+
__asm__ __volatile__(
86+
"call 1f\n\t"
87+
"1: pop %0\n\t"
88+
"mov %%esp, %1\n\t"
89+
"mov %%ebp, %2"
90+
: "=r"(myeip), "=r"(myesp), "=r"(myebp)
91+
:
92+
: "memory"
93+
);
94+
#else
95+
#error "Unsupported compiler or architecture for register capture"
96+
#endif
8297

8398

8499
MakeStackTrace(myeip,myesp,myebp, 2, callback);
@@ -314,6 +329,7 @@ void FillStackAddresses(void**addresses, unsigned int count, unsigned int skip)
314329
gsContext.ContextFlags = CONTEXT_FULL;
315330

316331
DWORD myeip,myesp,myebp;
332+
#if defined(_MSC_VER)
317333
_asm
318334
{
319335
MYEIP2:
@@ -325,6 +341,21 @@ _asm
325341
mov dword ptr [myebp] , eax
326342
xor eax,eax
327343
}
344+
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(_M_IX86))
345+
// GCC/Clang inline assembly for x86-32
346+
__asm__ __volatile__(
347+
"call 1f\n\t"
348+
"1: pop %0\n\t"
349+
"mov %%esp, %1\n\t"
350+
"mov %%ebp, %2\n\t"
351+
"xor %%eax, %%eax"
352+
: "=r"(myeip), "=r"(myesp), "=r"(myebp)
353+
:
354+
: "eax", "memory"
355+
);
356+
#else
357+
#error "Unsupported compiler or architecture for register capture"
358+
#endif
328359
memset(&stack_frame, 0, sizeof(STACKFRAME));
329360
stack_frame.AddrPC.Mode = AddrModeFlat;
330361
stack_frame.AddrPC.Offset = myeip;

0 commit comments

Comments
 (0)