60 lines
1.5 KiB
C++
60 lines
1.5 KiB
C++
// cxxProbe.cpp - full C++ ABI validation incl. dtor invocation.
|
|
// $025000 = 0xC0DE Singleton ctor (1st inst())
|
|
// $025002 = 0x4242 heap value via new + member access
|
|
// $025004 = 1 Singleton ctor count after 3 inst()s (guard works)
|
|
// $025006 = 0x6707 global ctor (init_array)
|
|
// $025008 = 0x900D end of main
|
|
// $02500A = 0xDEAD Singleton DTOR ran (via __cxa_atexit walk)
|
|
// $02500C = 0xFEED Global DTOR ran (via __cxa_atexit walk)
|
|
extern "C" {
|
|
#include <stdint.h>
|
|
}
|
|
|
|
static int gSingletonCtorCalls = 0;
|
|
|
|
struct Singleton {
|
|
int n;
|
|
Singleton() : n(0xC0DE) {
|
|
gSingletonCtorCalls++;
|
|
*(volatile uint16_t *)0x025000UL = (uint16_t)n;
|
|
}
|
|
~Singleton() {
|
|
*(volatile uint16_t *)0x02500AUL = 0xDEAD;
|
|
}
|
|
};
|
|
|
|
static Singleton &inst() {
|
|
static Singleton s;
|
|
return s;
|
|
}
|
|
|
|
struct Heap {
|
|
int v;
|
|
Heap(int x) : v(x) {}
|
|
};
|
|
|
|
struct GlobalCtor {
|
|
GlobalCtor() {
|
|
*(volatile uint16_t *)0x025006UL = 0x6707;
|
|
}
|
|
~GlobalCtor() {
|
|
*(volatile uint16_t *)0x02500CUL = 0xFEED;
|
|
}
|
|
};
|
|
|
|
static GlobalCtor gGlobal;
|
|
static volatile Heap *gHeapEscape = nullptr;
|
|
|
|
int main(void) {
|
|
inst(); inst();
|
|
Singleton &s = inst();
|
|
(void)s;
|
|
Heap *h = new Heap(0x4242);
|
|
gHeapEscape = h;
|
|
*(volatile uint16_t *)0x025002UL = (uint16_t)gHeapEscape->v;
|
|
gHeapEscape = nullptr;
|
|
delete h;
|
|
*(volatile uint16_t *)0x025004UL = (uint16_t)gSingletonCtorCalls;
|
|
*(volatile uint16_t *)0x025008UL = 0x900D;
|
|
return 0;
|
|
}
|