Avoid external linkage call inside __ifunc__
authorAlisson Gusatti Azzolini <azzolini@fb.com>
Fri, 23 Sep 2016 01:49:16 +0000 (18:49 -0700)
committerFacebook Github Bot 0 <facebook-github-bot-0-bot@fb.com>
Fri, 23 Sep 2016 01:53:29 +0000 (18:53 -0700)
Summary:
In debug mode, CpuId() ends up triggering external linkage from inside this __ifunc__.
However, in PIC, the relocation of external symbols are not ready yet, causing a segfault.

This only reproes in dynamic linking (PIC / so) and dbg mode.

Reviewed By: luciang

Differential Revision: D3895239

fbshipit-source-id: 2b7856c10abb5cfe24736d5bfac28e7e9d0e8272

folly/CpuId.h

index 6957d934402f70c8bee93a10201c5594722c461b..908480411ffdf69dfb5fffa7b819dd13a4df5711 100644 (file)
@@ -32,7 +32,13 @@ namespace folly {
  */
 class CpuId {
  public:
  */
 class CpuId {
  public:
-  CpuId() {
+  // Always inline in order for this to be usable from a __ifunc__.
+  // In shared library mde, a __ifunc__ runs at relocation time, while the
+  // PLT hasn't been fully populated yet; thus, ifuncs cannot use symbols
+  // with potentially external linkage. (This issue is less likely in opt
+  // mode since inlining happens more likely, and it doesn't happen for
+  // statically linked binaries which don't depend on the PLT)
+  FOLLY_ALWAYS_INLINE CpuId() {
 #ifdef _MSC_VER
     int reg[4];
     __cpuid(static_cast<int*>(reg), 0);
 #ifdef _MSC_VER
     int reg[4];
     __cpuid(static_cast<int*>(reg), 0);
@@ -91,9 +97,12 @@ class CpuId {
 #endif
   }
 
 #endif
   }
 
-#define X(name, r, bit) bool name() const { return (r) & (1U << bit); }
+#define X(name, r, bit)                   \
+  FOLLY_ALWAYS_INLINE bool name() const { \
+    return (r) & (1U << bit);             \
+  }
 
 
-  // cpuid(1): Processor Info and Feature Bits.
+// cpuid(1): Processor Info and Feature Bits.
 #define C(name, bit) X(name, f1c_, bit)
   C(sse3, 0)
   C(pclmuldq, 1)
 #define C(name, bit) X(name, f1c_, bit)
   C(sse3, 0)
   C(pclmuldq, 1)