diff --git a/AutomatedTests/CMakeLists.txt b/AutomatedTests/CMakeLists.txt index f778367f4f..769a12faba 100644 --- a/AutomatedTests/CMakeLists.txt +++ b/AutomatedTests/CMakeLists.txt @@ -62,4 +62,13 @@ set_tests_properties(Init PROPERTIES PASS_REGULAR_EXPRESSION "constructor\nmain\ test(StdIO.c) set_tests_properties(StdIO PROPERTIES PASS_REGULAR_EXPRESSION "OK") +if(CMAKE_SYSTEM_NAME MATCHES Retro68) + add_application(Segments Segment1.c Segment2.c Segments.segmap Test.h Test.c) + set_target_properties(Segments PROPERTIES + LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-segments -Wl,${CMAKE_CURRENT_SOURCE_DIR}/Segments.segmap") + add_test(NAME Segments COMMAND ${LAUNCH_APPL} + -e ${RETRO68_LAUNCH_METHOD} ${RETRO68_TEST_CONFIG} Segments.bin) +endif() + + endif() # RETRO68_LAUNCH_METHOD diff --git a/AutomatedTests/Segment1.c b/AutomatedTests/Segment1.c new file mode 100644 index 0000000000..dcaca117f8 --- /dev/null +++ b/AutomatedTests/Segment1.c @@ -0,0 +1,96 @@ +#include "Test.h" +#include +#include +#include + +int variable; + +void Foo(); +void Bar(); + +Boolean Test(Boolean unloadFoo, Boolean unloadBar, Boolean compact) +{ + variable = 6; + Foo(); + if(variable != 54) + { + TestLog("Expected 54 after Foo()."); + return false; + } + + if(unloadFoo) + UnloadSeg(&Foo); + if(unloadBar) + UnloadSeg(&Bar); + + Size grow; + if(compact) + MaxMem(&grow); + + Bar(); + if(variable != 42) + { + TestLog("Expected 42 after Bar()."); + return false; + } + return true; +} + +int main() +{ + Size grow, maxblock, maxblock2, freemem, freemem2; + + MaxApplZone(); // just to keep things simple and predictable + MoreMasters(); + + maxblock = MaxMem(&grow); + freemem = FreeMem(); + + TestLog("1. No unloading"); + if(!Test(false, false, false)) + return 1; + + maxblock2 = MaxMem(&grow); + + + TestLog("2. UnloadSeg(&Foo)"); + if(!Test(true, false, false)) + return 1; + TestLog("3. UnloadSeg(&Bar)"); + if(!Test(false, true, false)) + return 1; + TestLog("4. UnloadSeg(&Foo); UnloadSeg(&Bar)"); + if(!Test(true, true, false)) + return 1; + + TestLog("5. UnloadSeg(&Foo); MaxMem()"); + if(!Test(true, false, true)) + return 1; + TestLog("6. UnloadSeg(&Bar); MaxMem()"); + if(!Test(false, true, true)) + return 1; + TestLog("7. UnloadSeg(&Foo); UnloadSeg(&Bar); MaxMem()"); + if(!Test(true, true, true)) + return 1; + + UnloadSeg(&Foo); + + maxblock2 = MaxMem(&grow); + freemem2 = FreeMem(); + + if(maxblock2 < maxblock || freemem2 < freemem) + { + TestLog("Leak"); + char s[256]; + sprintf(s, "maxblock: %d (delta %d), freemem: %d (delta %d)", + maxblock2, maxblock2-maxblock, freemem2, freemem2-freemem); + TestLog(s); + return 1; + } + else if(maxblock2 > maxblock || freemem2 > freemem) + TestLog("Magic Memory"); + + TestLog("OK"); + + return 0; +} diff --git a/AutomatedTests/Segment2.c b/AutomatedTests/Segment2.c new file mode 100644 index 0000000000..a17b77b408 --- /dev/null +++ b/AutomatedTests/Segment2.c @@ -0,0 +1,12 @@ +extern int variable; +#include +void Foo() +{ + variable *= 9; +} + +void Bar() +{ + variable /= 9; + variable *= 7; +} diff --git a/AutomatedTests/Segments.segmap b/AutomatedTests/Segments.segmap new file mode 100644 index 0000000000..088717550d --- /dev/null +++ b/AutomatedTests/Segments.segmap @@ -0,0 +1,2 @@ +SEGMENT The Second Segment + */Segment2.* diff --git a/libretro/malloc.c b/libretro/malloc.c index e49141b294..f3e0d2a79d 100644 --- a/libretro/malloc.c +++ b/libretro/malloc.c @@ -31,6 +31,12 @@ void referenceMyMalloc() {} +int* __errno() +{ + static int realErrno = 0; + return &realErrno; +} + void *_malloc_r(struct _reent *reent_ptr, size_t sz) { Ptr p = NewPtr(sz);