#include <stdio.h> // fprintf(), NULL
#include <stdlib.h> // exit(), EXIT_SUCCESS
#include <string.h>
#include <dlfcn.h>
#include <mach-o/dyld_priv.h>
#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL()
extern uint32_t _cpu_capabilities;
extern const char* foo();
typedef const char* (*BarProc)(void);
const char* myStr = "myStr";
int myInt;
int main()
{
if ( !_dyld_is_memory_immutable(myStr, 6) ) {
FAIL("_dyld_is_memory_immutable() returned false for string in main executable");
return EXIT_SUCCESS;
}
if ( _dyld_is_memory_immutable(strdup("hello"), 6) ) {
FAIL("_dyld_is_memory_immutable() returned true for result from strdup()");
return EXIT_SUCCESS;
}
if ( _dyld_is_memory_immutable(&myInt, 4) ) {
FAIL("_dyld_is_memory_immutable() returned true for global variabe in main executable");
return EXIT_SUCCESS;
}
if ( !_dyld_is_memory_immutable(foo(), 4) ) {
FAIL("_dyld_is_memory_immutable() returned false for string in statically linked dylib");
return EXIT_SUCCESS;
}
if ( !_dyld_is_memory_immutable(&strcpy, 4) ) {
FAIL("_dyld_is_memory_immutable() returned false for function in dyld shared cache");
return EXIT_SUCCESS;
}
if ( _dyld_is_memory_immutable(&_cpu_capabilities, 4) ) {
FAIL("_dyld_is_memory_immutable() returned true for global variabe in shared cache");
return EXIT_SUCCESS;
}
void* handle = dlopen("libbar.dylib", 0);
if ( handle == NULL ) {
FAIL("dlopen(libbar.dylib) failed");
return EXIT_SUCCESS;
}
BarProc proc = dlsym(handle, "bar");
if ( proc == NULL ) {
FAIL("dlsym(bar) failed");
return EXIT_SUCCESS;
}
const char* barStr = (*proc)();
if ( _dyld_is_memory_immutable(barStr, 4) ) {
FAIL("_dyld_is_memory_immutable() returned true for string in unloadable dylib");
return EXIT_SUCCESS;
}
PASS("_dyld_is_memory_immutable");
return 0;
}