aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2019-02-21 21:14:09 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-02-21 21:14:09 +0000
commit5e15f34c504b1b03b7c5285496e8ba4b4a4831a9 (patch)
tree7d9d3bdf1ba5bf581f5b91a8eff4d72153371df1
parent7cdbd0d477176e0973beb7328e40c328aa73d1e5 (diff)
parenta535d3ca6557ced23d8f87d1b3f6b85bd2e8e068 (diff)
downloadbionic-5e15f34c504b1b03b7c5285496e8ba4b4a4831a9.tar.gz
-rw-r--r--libc/bionic/libc_init_static.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 3219239b7..41f100dbb 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -67,9 +67,20 @@ static void call_array(void(**list)()) {
}
#if defined(__aarch64__) || defined(__x86_64__)
-extern __LIBC_HIDDEN__ ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
+extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
static void call_ifunc_resolvers() {
+ if (__rela_iplt_start == nullptr || __rela_iplt_end == nullptr) {
+ // These symbols are not emitted by gold. Gold has code to do so, but for
+ // whatever reason it is not being run. In these cases ifuncs cannot be
+ // resolved, so we do not support using ifuncs in static executables linked
+ // with gold.
+ //
+ // Since they are weak, they will be non-null when linked with bfd/lld and
+ // null when linked with gold.
+ return;
+ }
+
typedef ElfW(Addr) (*ifunc_resolver_t)(void);
for (ElfW(Rela) *r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
@@ -78,9 +89,20 @@ static void call_ifunc_resolvers() {
}
}
#else
-extern __LIBC_HIDDEN__ ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
+extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
static void call_ifunc_resolvers() {
+ if (__rel_iplt_start == nullptr || __rel_iplt_end == nullptr) {
+ // These symbols are not emitted by gold. Gold has code to do so, but for
+ // whatever reason it is not being run. In these cases ifuncs cannot be
+ // resolved, so we do not support using ifuncs in static executables linked
+ // with gold.
+ //
+ // Since they are weak, they will be non-null when linked with bfd/lld and
+ // null when linked with gold.
+ return;
+ }
+
typedef ElfW(Addr) (*ifunc_resolver_t)(void);
for (ElfW(Rel) *r = __rel_iplt_start; r != __rel_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);