cmake: rework elf detection (#1058)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a0b1c0..b787631 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -125,8 +125,11 @@
 endif (Unwind_FOUND)
 
 check_include_file_cxx (dlfcn.h HAVE_DLFCN_H)
+check_include_file_cxx (elf.h HAVE_ELF_H)
 check_include_file_cxx (glob.h HAVE_GLOB_H)
+check_include_file_cxx (link.h HAVE_LINK_H)
 check_include_file_cxx (pwd.h HAVE_PWD_H)
+check_include_file_cxx (sys/exec_elf.h HAVE_SYS_EXEC_ELF_H)
 check_include_file_cxx (sys/syscall.h HAVE_SYS_SYSCALL_H)
 check_include_file_cxx (sys/time.h HAVE_SYS_TIME_H)
 check_include_file_cxx (sys/types.h HAVE_SYS_TYPES_H)
@@ -275,9 +278,9 @@
       set (HAVE_STACKTRACE 1)
     endif (HAVE_SYMBOLIZE)
   elseif (UNIX)
-    cmake_push_check_state (RESET)
-    check_cxx_symbol_exists (__ELF__ "" HAVE_SYMBOLIZE)
-    cmake_pop_check_state ()
+    if (HAVE_ELF_H OR HAVE_SYS_EXEC_ELF_H)
+      set (HAVE_SYMBOLIZE 1)
+    endif (HAVE_ELF_H OR HAVE_SYS_EXEC_ELF_H)
   elseif (APPLE AND HAVE_DLADDR)
     set (HAVE_SYMBOLIZE 1)
   endif (WIN32 OR CYGWIN)
diff --git a/bazel/glog.bzl b/bazel/glog.bzl
index 10cf3d2..199fe01 100644
--- a/bazel/glog.bzl
+++ b/bazel/glog.bzl
@@ -86,11 +86,13 @@
     freebsd_only_copts = [
         # Enable declaration of _Unwind_Backtrace
         "-D_GNU_SOURCE",
+        "-DHAVE_LINK_H",
     ]
 
     linux_only_copts = [
         # For utilities.h.
         "-DHAVE_EXECINFO_H",
+        "-DHAVE_LINK_H",
     ]
 
     darwin_only_copts = [
diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in
index f60570a..2347d74 100644
--- a/src/config.h.cmake.in
+++ b/src/config.h.cmake.in
@@ -52,6 +52,15 @@
 /* Define to 1 if you have the <syslog.h> header file. */
 #cmakedefine HAVE_SYSLOG_H
 
+/* Define to 1 if you have the <elf.h> header file. */
+#cmakedefine HAVE_ELF_H
+
+/* Define to 1 if you have the <sys/exec_elf.h> header file. */
+#cmakedefine HAVE_SYS_EXEC_ELF_H
+
+/* Define to 1 if you have the <link.h> header file. */
+#cmakedefine HAVE_LINK_H
+
 /* Define to 1 if you have the <sys/syscall.h> header file. */
 #cmakedefine HAVE_SYS_SYSCALL_H
 
diff --git a/src/symbolize.cc b/src/symbolize.cc
index 09bc9eb..11a9872 100644
--- a/src/symbolize.cc
+++ b/src/symbolize.cc
@@ -109,16 +109,11 @@
 }  // namespace glog_internal_namespace_
 }  // namespace google
 
-#  if defined(__ELF__)
+#  if defined(HAVE_LINK_H)
 
 #    if defined(HAVE_DLFCN_H)
 #      include <dlfcn.h>
 #    endif
-#    if defined(GLOG_OS_OPENBSD)
-#      include <sys/exec_elf.h>
-#    else
-#      include <elf.h>
-#    endif
 #    include <fcntl.h>
 #    include <sys/stat.h>
 #    include <sys/types.h>
diff --git a/src/symbolize.h b/src/symbolize.h
index dfd5fec..d9ca52d 100644
--- a/src/symbolize.h
+++ b/src/symbolize.h
@@ -61,6 +61,14 @@
 #include "config.h"
 #include "glog/platform.h"
 
+#if defined(HAVE_LINK_H)
+#  include <link.h>  // For ElfW() macro.
+#elif defined(HAVE_ELF_H)
+#  include <elf.h>
+#elif defined(HAVE_SYS_EXEC_ELF_H)
+#  include <sys/exec_elf.h>
+#endif
+
 #if defined(GLOG_USE_GLOG_EXPORT)
 #  include "glog/export.h"
 #endif
@@ -72,7 +80,7 @@
 #ifndef GLOG_NO_SYMBOLIZE_DETECTION
 #  ifndef HAVE_SYMBOLIZE
 // defined by gcc
-#    if defined(__ELF__) && defined(GLOG_OS_LINUX)
+#    if defined(HAVE_ELF_H) || defined(HAVE_SYS_EXEC_ELF_H)
 #      define HAVE_SYMBOLIZE
 #    elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
 // Use dladdr to symbolize.
@@ -86,26 +94,11 @@
 
 #ifdef HAVE_SYMBOLIZE
 
-#  if defined(__ELF__)  // defined by gcc
-#    if defined(__OpenBSD__)
-#      include <sys/exec_elf.h>
-#    else
-#      include <elf.h>
-#    endif
+#  if !defined(SIZEOF_VOID_P) && defined(__SIZEOF_POINTER__)
+#    define SIZEOF_VOID_P __SIZEOF_POINTER__
+#  endif
 
-#    if !defined(GLOG_OS_ANDROID)
-#      include <link.h>  // For ElfW() macro.
-#    endif
-
-// For systems where SIZEOF_VOID_P is not defined, determine it
-// based on __LP64__ (defined by gcc on 64-bit systems)
-#    if !defined(SIZEOF_VOID_P)
-#      if defined(__LP64__)
-#        define SIZEOF_VOID_P 8
-#      else
-#        define SIZEOF_VOID_P 4
-#      endif
-#    endif
+#  if defined(HAVE_ELF_H) || defined(HAVE_SYS_EXEC_ELF_H)
 
 // If there is no ElfW macro, let's define it by ourself.
 #    ifndef ElfW
@@ -130,7 +123,7 @@
 }  // namespace glog_internal_namespace_
 }  // namespace google
 
-#  endif /* __ELF__ */
+#  endif
 
 namespace google {
 inline namespace glog_internal_namespace_ {
diff --git a/src/symbolize_unittest.cc b/src/symbolize_unittest.cc
index 30945c1..f07484e 100644
--- a/src/symbolize_unittest.cc
+++ b/src/symbolize_unittest.cc
@@ -40,6 +40,7 @@
 #include "glog/logging.h"
 #include "googletest.h"
 #include "utilities.h"
+#include "stacktrace.h"
 
 #ifdef GLOG_USE_GFLAGS
 #  include <gflags/gflags.h>
@@ -60,7 +61,8 @@
 
 #  define always_inline
 
-#  if defined(__ELF__) || defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
+#  if defined(HAVE_ELF_H) || defined(HAVE_SYS_EXEC_ELF_H) || \
+      defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
 // A wrapper function for Symbolize() to make the unit test simple.
 static const char* TrySymbolize(void* pc, google::SymbolizeOptions options =
                                               google::SymbolizeOptions::kNone) {
@@ -73,8 +75,7 @@
 }
 #  endif
 
-#  if defined(__ELF__)
-
+#  if defined(HAVE_ELF_H) || defined(HAVE_SYS_EXEC_ELF_H)
 // This unit tests make sense only with GCC.
 // Uses lots of GCC specific features.
 #    if defined(__GNUC__) && !defined(__OPENCC__)
@@ -449,15 +450,15 @@
 #    endif
   cout << "Test case TestWithReturnAddress passed." << endl;
 }
-#  endif  // __ELF__
-#endif    // HAVE_STACKTRACE
+#  endif
+#endif  // HAVE_STACKTRACE
 
 int main(int argc, char** argv) {
   FLAGS_logtostderr = true;
   InitGoogleLogging(argv[0]);
   InitGoogleTest(&argc, argv);
 #if defined(HAVE_SYMBOLIZE) && defined(HAVE_STACKTRACE)
-#  if defined(__ELF__)
+#  if defined(HAVE_ELF_H) || defined(HAVE_SYS_EXEC_ELF_H)
   // We don't want to get affected by the callback interface, that may be
   // used to install some callback function at InitGoogle() time.
   InstallSymbolizeCallback(nullptr);
@@ -472,7 +473,7 @@
 #  else   // GLOG_OS_WINDOWS
   printf("PASS (no symbolize_unittest support)\n");
   return 0;
-#  endif  // __ELF__
+#  endif  // defined(HAVE_ELF_H) || defined(HAVE_SYS_EXEC_ELF_H)
 #else
   printf("PASS (no symbolize support)\n");
   return 0;