crazy_linker: Fix isnanf symbol lookup in clang builds.

Clang builds for arm32 generate calls to isnanf.  Android's libm.so isnanf
is weak.  Android's dlsym() returns NULL for weak symbols.  In libm.so,
isnanf is a synonym for a (strong) __isnanf.

If resolving isnanf from Android libm.so fails, retry __isnanf.

http://code.google.com/p/chromium/issues/detail?id=376828

Change-Id: Ib04f933e6a317e5a65cd2762b02027b0388b0e4a
Signed-off-by: Simon Baldwin <simonb@google.com>
diff --git a/sources/android/crazy_linker/src/crazy_linker_shared_library.cpp b/sources/android/crazy_linker/src/crazy_linker_shared_library.cpp
index f312884..406346e 100644
--- a/sources/android/crazy_linker/src/crazy_linker_shared_library.cpp
+++ b/sources/android/crazy_linker/src/crazy_linker_shared_library.cpp
@@ -112,6 +112,23 @@
       // wrap->GetName());
       if (wrap->IsSystem()) {
         address = ::dlsym(wrap->GetSystem(), symbol_name);
+#ifdef __arm__
+        // Android libm.so defines isnanf as weak. This means that its
+        // address cannot be found by dlsym(), which always returns NULL
+        // for weak symbols. However, libm.so contains the real isnanf
+        // as __isnanf. If we encounter isnanf and fail to resolve it in
+        // libm.so, retry with __isnanf.
+        //
+        // This occurs only in clang, which lacks __builtin_isnanf. The
+        // gcc compiler implements isnanf as a builtin, so the symbol
+        // isnanf never need be resolved in gcc builds.
+        //
+        // http://code.google.com/p/chromium/issues/detail?id=376828
+        if (!address &&
+            !strcmp(symbol_name, "isnanf") &&
+            !strcmp(wrap->GetName(), "libm.so"))
+          address = ::dlsym(wrap->GetSystem(), "__isnanf");
+#endif
         if (address)
           return address;
       }