Merge "Add (no-op) ifuncs for SVE optimized routines."
diff --git a/libc/include/nl_types.h b/libc/include/nl_types.h
index 1c80e4e..f4d7f43 100644
--- a/libc/include/nl_types.h
+++ b/libc/include/nl_types.h
@@ -62,7 +62,7 @@
*
* Available since API level 28.
*/
-nl_catd catopen(const char* __name, int __flag) __INTRODUCED_IN(26);
+nl_catd _Nonnull catopen(const char* _Nonnull __name, int __flag) __INTRODUCED_IN(26);
/**
* [catgets(3)](http://man7.org/linux/man-pages/man3/catgets.3.html) translates the given message
@@ -72,13 +72,13 @@
*
* Available since API level 28.
*/
-char* catgets(nl_catd __catalog, int __set_number, int __msg_number, const char* __msg) __INTRODUCED_IN(26);
+char* _Nonnull catgets(nl_catd _Nonnull __catalog, int __set_number, int __msg_number, const char* _Nonnull __msg) __INTRODUCED_IN(26);
/**
* [catclose(3)](http://man7.org/linux/man-pages/man3/catclose.3.html) closes a message catalog.
*
* On Android, this always returns -1 with `errno` set to `EBADF`.
*/
-int catclose(nl_catd __catalog) __INTRODUCED_IN(26);
+int catclose(nl_catd _Nonnull __catalog) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index f0e7b1b..833157e 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -203,35 +203,29 @@
ElfW(Addr) entry_point;
};
-static ExecutableInfo get_executable_info() {
+static ExecutableInfo get_executable_info(const char* arg_path) {
ExecutableInfo result = {};
+ char const* exe_path = "/proc/self/exe";
- if (is_first_stage_init()) {
- // /proc fs is not mounted when first stage init starts. Therefore we can't
- // use /proc/self/exe for init.
- stat("/init", &result.file_stat);
-
- // /init may be a symlink, so try to read it as such.
- char path[PATH_MAX];
- ssize_t path_len = readlink("/init", path, sizeof(path));
- if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
- result.path = "/init";
- } else {
- result.path = std::string(path, path_len);
+ // Stat "/proc/self/exe" instead of executable_path because
+ // the executable could be unlinked by this point and it should
+ // not cause a crash (see http://b/31084669)
+ if (TEMP_FAILURE_RETRY(stat(exe_path, &result.file_stat) == -1)) {
+ // Fallback to argv[0] for the case where /proc isn't available
+ if (TEMP_FAILURE_RETRY(stat(arg_path, &result.file_stat) == -1)) {
+ async_safe_fatal("unable to stat either \"/proc/self/exe\" or \"%s\": %s",
+ arg_path, strerror(errno));
}
+ exe_path = arg_path;
+ }
+
+ // Path might be a symlink
+ char sym_path[PATH_MAX];
+ ssize_t sym_path_len = readlink(exe_path, sym_path, sizeof(sym_path));
+ if (sym_path_len > 0 && sym_path_len < static_cast<ssize_t>(sizeof(sym_path))) {
+ result.path = std::string(sym_path, sym_path_len);
} else {
- // Stat "/proc/self/exe" instead of executable_path because
- // the executable could be unlinked by this point and it should
- // not cause a crash (see http://b/31084669)
- if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &result.file_stat)) != 0) {
- async_safe_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno));
- }
- char path[PATH_MAX];
- ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
- if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
- async_safe_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
- }
- result.path = std::string(path, path_len);
+ result.path = std::string(exe_path, strlen(exe_path));
}
result.phdr = reinterpret_cast<const ElfW(Phdr)*>(getauxval(AT_PHDR));
@@ -359,7 +353,7 @@
}
const ExecutableInfo exe_info = exe_to_load ? load_executable(exe_to_load) :
- get_executable_info();
+ get_executable_info(args.argv[0]);
INFO("[ Linking executable \"%s\" ]", exe_info.path.c_str());