forked from OSchip/llvm-project
[Support] Fix getMainExecutable on FreeBSD when called via an absolute path
On FreeBSD, absolute paths are passed unmodified in AT_EXECPATH, but relative paths are resolved to absolute paths, and any symlinks will be followed in the process. This means that the resource dir calculation will be wrong if Clang is invoked as an absolute path to a symlink, and this currently causes clang/test/Driver/rocm-detect.hip to fail on FreeBSD. Thus, make sure to call realpath on the result, just like is done on macOS. Whilst here, clean up the old fallback auxargs loop to use the actual type for auxargs rather than using lots of hacky casts that rely on addresses and pointers being the same (which is not the case on CHERI, and thus Arm's prototype Morello, although for little-endian systems it happens to work still as the word-sized integer will be padded to a full pointer, and it's someone academic given dereferencing past the end of environ will give a bounds fault, but CheriBSD is new enough that the elf_aux_info path will be used). This also makes the code easier to follow, and removes the confusing double-increment of p. Reviewed By: dim, arichardson Differential Revision: https://reviews.llvm.org/D103346
This commit is contained in:
parent
aa9a30b83a
commit
762f707c00
|
@ -209,8 +209,11 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
|
|||
// to the file.
|
||||
char exe_path[PATH_MAX];
|
||||
#if __FreeBSD_version >= 1300057
|
||||
if (elf_aux_info(AT_EXECPATH, exe_path, sizeof(exe_path)) == 0)
|
||||
return exe_path;
|
||||
if (elf_aux_info(AT_EXECPATH, exe_path, sizeof(exe_path)) == 0) {
|
||||
char link_path[PATH_MAX];
|
||||
if (realpath(exe_path, link_path))
|
||||
return link_path;
|
||||
}
|
||||
#else
|
||||
// elf_aux_info(AT_EXECPATH, ... is not available in all supported versions,
|
||||
// fall back to finding the ELF auxiliary vectors after the process's
|
||||
|
@ -219,9 +222,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
|
|||
while (*p++ != 0)
|
||||
;
|
||||
// Iterate through auxiliary vectors for AT_EXECPATH.
|
||||
for (; *(uintptr_t *)p != AT_NULL; p++) {
|
||||
if (*(uintptr_t *)p++ == AT_EXECPATH)
|
||||
return *p;
|
||||
for (Elf_Auxinfo *aux = (Elf_Auxinfo *)p; aux->a_type != AT_NULL; aux++) {
|
||||
if (aux->a_type == AT_EXECPATH) {
|
||||
char link_path[PATH_MAX];
|
||||
if (realpath((char *)aux->a_un.a_ptr, link_path))
|
||||
return link_path;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Fall back to argv[0] if auxiliary vectors are not available.
|
||||
|
|
Loading…
Reference in New Issue