// Diagnostic for the gnoExecProbe exec-into failure: distinguishes a PATH/ // access() resolution miss from a K_execve transfer-of-control failure. // Runs in the SAME harness as gnoExecProbe (GNO_PROG2=gnoExeced deployed to // /bin). Each marker isolates one step so we can see exactly where exec dies. // // Bank-2 absolute uint16 markers (DBR-independent): // 0x025000 C0DE reached end (fallback; set only if every exec returned) // 0x025010 E0EC gnoExeced ran -> some exec transferred control (success) // 0x025020 F00D access("/bin/gnoexeced", F_OK) == 0 (our libc finds it) // else EE00|errno (access failed -> which errno) // 0x025022 EE00|errno after execv("/bin/gnoexeced") RETURNED (explicit path, // bypasses PATH; only set if the exec failed to transfer) // 0x025024 EE00|errno after execvp("gnoexeced") RETURNED (PATH-resolved; // only set if that exec failed too) #include extern int access(const char *path, int mode); extern int execv(const char *path, char *const *argv); extern int execvp(const char *file, char *const *argv); extern int errno; #define M(a) (*(volatile uint16_t *)(a)) #define BAD 0xDEAD #define F_OK 0 int main(void) { char *argv[2]; int r; M(0x025000UL) = 0x0000; M(0x025010UL) = BAD; M(0x025020UL) = BAD; M(0x025022UL) = BAD; M(0x025024UL) = BAD; argv[0] = "gnoexeced"; argv[1] = 0; // Step 1: does our own access() see the file gsh clearly found at /bin? errno = 0; r = access("/bin/gnoexeced", F_OK); if (r == 0) { M(0x025020UL) = 0xF00D; } else { M(0x025020UL) = 0xEE00 | (uint16_t)(errno & 0xFF); } // Step 2: explicit-path execv (bypasses $PATH entirely). On success this // never returns -- gnoExeced sets 0x025010 + 0x025000 in the same image. errno = 0; execv("/bin/gnoexeced", argv); M(0x025022UL) = 0xEE00 | (uint16_t)(errno & 0xFF); // only if it returned // Step 3: PATH-resolved execvp, as gnoExecProbe does. errno = 0; execvp("gnoexeced", argv); M(0x025024UL) = 0xEE00 | (uint16_t)(errno & 0xFF); // only if it returned // Reached only if BOTH execs failed to transfer control. M(0x025000UL) = 0xC0DE; for (volatile unsigned long j = 0; j < 300000UL; j++) { } return 0; }