Is there a way for a program to know if it's executed under the simulator and not on an actual CPU?
Alright. Just in case someone is still interested in the topic, I'd like to offer a working cross-platform example of how the simulator can be detected using a debug script. Kudos goes to Chad Clendening and Per Westermark for the idea.
This code works on both the ARM and the 8051 simulators, with slightly different debug scripts. I now don't have all the necessary hardware to test the code on it, but I hope it works on it just as good :) Anyway, I would appreciate it if someone would check that out :)
/* sim-detect.c */ #include <stdio.h> #include <string.h> #if defined(__arm__) /* This is here only to print a message over UART. In the IDE it will show up in a Serial Window. */ #include <lpc21xx.h> #define VPB_CLOCK 12000000 #define BAUD_RATE 9600 int sendchar(int ch) { while (!(U0LSR & 0x20)) ; return (U0THR = ch); } /* ------------------------------------------------------------------------- */ int getkey(void) { while (!(U0LSR & 0x01)) ; return U0RBR; } /* ------------------------------------------------------------------------- */ struct __FILE { int handle; }; /* ------------------------------------------------------------------------- */ int fputc(int ch, FILE *f) { return sendchar(ch); } /* ------------------------------------------------------------------------- */ void _sys_exit(int return_code) { for (;;) ; } /* ------------------------------------------------------------------------- */ #elif defined(__C51__) #include <reg51.h> #endif /* Attention! These memory address values were chosen for demonstration purposes only. They may be incompatible with your particular memory layout. */ #if defined(__arm__) #define SIM_DETECTOR_ATTR __attribute__((section(".ARM.__at_0x40000000"))) #elif defined(__C51__) #define SIM_DETECTOR_ATTR _at_ 0x30 #else #define SIM_DETECTOR_ATTR #endif volatile unsigned char sim_detector SIM_DETECTOR_ATTR; int main(void) { /* set up UART0 to see the detection message */ #if defined(__arm__) PINSEL0 = 0x00000005; U0LCR = 0x83; U0DLL = (VPB_CLOCK/16/BAUD_RATE) & 0xFF; U0DLM = ((VPB_CLOCK/16/BAUD_RATE) >> 8) & 0xFF; U0LCR = 0x03; #elif defined(__C51__) SCON = 0x50; TMOD |= 0x20; TH1 = 213; TR1 = 1; TI = 1; #endif sim_detector = 0x55; if (sim_detector == 0xAA) puts("SIMULATOR DETECTED"); else puts("SIMULATOR NOT DETECTED"); return 0; }
The debug script for the ARM:
/* debug-arm.ini */ signal void sim_detect(unsigned long adr) { unsigned char val; while (1) { /* wait for write access */ wwatch(adr); /* read value */ val = _RBYTE(adr); /* uncomment the line below if you want to see sim_detector values */ // printf("sim_detector = %X\n", val); /* change value */ val = ~val; /* write value back */ _WBYTE(adr, val); } } sim_detect(0x40000000);
The debug script for the 8051:
/* debug-c51.ini */ signal void sim_detect(unsigned long adr) { unsigned char val; while (1) { /* wait for write access */ wwatch(adr); /* read value */ val = _RBYTE(adr); /* uncomment the line below if you want to see sim_detector values */ // printf("val = %X\n", val); /* change value */ val = ~val; /* write value back */ _WBYTE(adr, val); } } sim_detect(D:0x30);