diff -u -r ../orig-src/llvm/lib/Support/Unix/Path.inc ./llvm/lib/Support/Unix/Path.inc --- ../orig-src/llvm/lib/Support/Unix/Path.inc 2023-09-29 21:36:47.056335287 +0000 +++ ./llvm/lib/Support/Unix/Path.inc 2023-09-29 21:40:31.091417185 +0000 @@ -250,6 +250,44 @@ // If we don't have procfs mounted, fall back to argv[0] if (getprogpath(exe_path, argv0) != NULL) return exe_path; +#elif defined(__ANDROID__) // termux-exec linker wrapping does not work with /proc/self/exe + if (char *real_path = realpath("/proc/self/exe", nullptr)) { + if (char *real_linker_path = realpath( +#ifdef __LP64__ + "/system/bin/linker64", +#else + "/system/bin/linker", +#endif + nullptr)) { + if (strcmp(real_path, real_linker_path) != 0) { + free(real_linker_path); + std::string ret = std::string(real_path); + free(real_path); + return ret; + } + free(real_linker_path); + free(real_path); + if (FILE *cmdfile = fopen("/proc/self/cmdline", "r")) { + char *cmd = nullptr; + size_t len = 0; + ssize_t nread = getdelim(&cmd, &len, '\0', cmdfile); + if (nread > 0) { + nread = getdelim(&cmd, &len, '\0', cmdfile); // 2nd read to skip linker + fclose(cmdfile); + if (nread > 0 && (real_path = realpath(cmd, nullptr))) { + free(cmd); + std::string ret = std::string(real_path); + free(real_path); + return ret; + } + } else fclose(cmdfile); + free(cmd); + } + } else free(real_path); + } + // Fall back to the classical detection. + char exe_path[PATH_MAX]; + if (getprogpath(exe_path, argv0)) return exe_path; #elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) char exe_path[PATH_MAX]; const char *aPath = "/proc/self/exe";