Fix linker self-exec detection
When the linker is invoked on itself, (`linker64 /system/bin/linker64`),
the linker prints an error, because self-invocation isn't allowed. The
current method for detecting self-invocation fails because the second
linker instance can crash in a constructor function before reaching
__linker_init.
Fix the problem by moving the error check into a constructor function,
which finishes initializing libc sufficiently to call async_safe_fatal.
The only important thing missing is __libc_sysinfo on 32-bit x86. The aux
vector isn't readily accessible, so use the fallback int 0x80.
Bug: http://b/123637025
Test: bionic unit tests (32-bit x86)
Change-Id: I8be6369e8be3938906628ae1f82be13e6c510119
diff --git a/libc/arch-x86/bionic/__libc_init_sysinfo.cpp b/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
index 849d253..5c44b4e 100644
--- a/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
+++ b/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
@@ -32,6 +32,10 @@
// This file is compiled without stack protection, because it runs before TLS
// has been set up.
+__LIBC_HIDDEN__ __attribute__((__naked__)) void __libc_int0x80() {
+ __asm__ volatile("int $0x80; ret");
+}
+
__LIBC_HIDDEN__ void __libc_init_sysinfo() {
bool dummy;
__libc_sysinfo = reinterpret_cast<void*>(__bionic_getauxval(AT_SYSINFO, dummy));
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 7140776..4f3b4f7 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -66,9 +66,6 @@
// Use an initializer so __libc_sysinfo will have a fallback implementation
// while .preinit_array constructors run.
#if defined(__i386__)
-static __attribute__((__naked__)) void __libc_int0x80() {
- __asm__ volatile("int $0x80; ret");
-}
__LIBC_HIDDEN__ void* __libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80);
#endif
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 21a2a24..4c4172a 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -87,6 +87,7 @@
#if defined(__i386__)
__LIBC_HIDDEN__ extern void* __libc_sysinfo;
+__LIBC_HIDDEN__ void __libc_int0x80();
__LIBC_HIDDEN__ void __libc_init_sysinfo();
#endif