Refine SHA-1 related stuffs.

1. Introduce libbcc.sha1.so instead of raw file libbcc.so.sha1
    * Now tools/build/gen-sha1-stamp.py generated assembly contains
      symbols libbcc_so_SHA1 and libRS_so_SHA1 associated with their
      SHA-1 digests.
    * In that way, their SHA-1 information can be obtained via
      dlopen().
2. Refine Sha1Helper to Sha1Util.
2. Remove unused tools/build/dataconvert.py by the way.
diff --git a/Android.mk b/Android.mk
index 166ed54..4951f62 100644
--- a/Android.mk
+++ b/Android.mk
@@ -39,22 +39,29 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := libbcc.so.sha1
+LOCAL_MODULE := libbcc.sha1
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 
-include $(BUILD_SYSTEM)/base_rules.mk
 libbcc_SHA1_SRCS := \
   $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libbcc.so \
   $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRS.so
 
 libbcc_GEN_SHA1_STAMP := $(LOCAL_PATH)/tools/build/gen-sha1-stamp.py
+intermediates := $(call local-intermediates-dir)
 
-$(LOCAL_BUILT_MODULE): PRIVATE_SHA1_SRCS := $(libbcc_SHA1_SRCS)
-$(LOCAL_BUILT_MODULE): $(libbcc_SHA1_SRCS) $(libbcc_GEN_SHA1_STAMP)
-	$(hide) mkdir -p $(dir $@) && \
-	        $(libbcc_GEN_SHA1_STAMP) $@ $(PRIVATE_SHA1_SRCS)
+libbcc_SHA1_ASM := $(intermediates)/libbcc.sha1.S
+LOCAL_GENERATED_SOURCES += $(libbcc_SHA1_ASM)
+$(libbcc_SHA1_ASM): PRIVATE_SHA1_SRCS := $(libbcc_SHA1_SRCS)
+$(libbcc_SHA1_ASM): $(libbcc_SHA1_SRCS) $(libbcc_GEN_SHA1_STAMP)
+	@echo libbcc.sha1: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(libbcc_GEN_SHA1_STAMP) $(PRIVATE_SHA1_SRCS) > $@
 
+LOCAL_CFLAGS += -D_REENTRANT -DPIC -fPIC
+LOCAL_CFLAGS += -O3 -nodefaultlibs -nostdlib
+
+include $(BUILD_SHARED_LIBRARY)
 
 #=====================================================================
 # Device Shared Library libbcc
@@ -141,7 +148,7 @@
 
 # Modules that need get installed if and only if the target libbcc.so is
 # installed.
-LOCAL_REQUIRED_MODULES := libclcore.bc libbcc.so.sha1
+LOCAL_REQUIRED_MODULES := libclcore.bc libbcc.sha1.so
 
 # Link-Time Optimization on libbcc.so
 #
diff --git a/include/bcc/RenderScript/RSInfo.h b/include/bcc/RenderScript/RSInfo.h
index bdabe3a..37019c5 100644
--- a/include/bcc/RenderScript/RSInfo.h
+++ b/include/bcc/RenderScript/RSInfo.h
@@ -23,6 +23,7 @@
 
 #include "bcc/RenderScript/RSScript.h"
 #include "bcc/Support/Log.h"
+#include "bcc/Support/Sha1Util.h"
 
 #include <utils/String8.h>
 #include <utils/Vector.h>
@@ -81,7 +82,7 @@
 struct __attribute__((packed)) DependencyTableItem {
   StringIndexTy id;
   // SHA-1 checksum is stored as a string in string pool (and has fixed-length
-  // 20 bytes)
+  // SHA1_DIGEST_LENGTH (=20) bytes)
   StringIndexTy sha1;
 };
 
@@ -164,8 +165,8 @@
 private:
   // SHA-1 of the built-in dependencies. Will be initialized in
   // LoadBuiltInSHA1Information().
-  static uint8_t LibBCCSHA1[20];
-  static uint8_t LibRSSHA1[20];
+  static const uint8_t *LibBCCSHA1;
+  static const uint8_t *LibRSSHA1;
 
   static bool CheckDependency(const RSInfo &pInfo,
                               const char *pInputFilename,
diff --git a/include/bcc/RenderScript/RSScript.h b/include/bcc/RenderScript/RSScript.h
index d8dd8b4..2a96d35 100644
--- a/include/bcc/RenderScript/RSScript.h
+++ b/include/bcc/RenderScript/RSScript.h
@@ -23,6 +23,7 @@
 #include <llvm/Support/CodeGen.h>
 
 #include "bcc/Script.h"
+#include "bcc/Support/Sha1Util.h"
 
 namespace bcc {
 
@@ -34,7 +35,7 @@
   class SourceDependency {
   private:
     std::string mSourceName;
-    uint8_t mSHA1[20];
+    uint8_t mSHA1[SHA1_DIGEST_LENGTH];
 
   public:
     SourceDependency(const std::string &pSourceName,
diff --git a/include/bcc/Support/Sha1Helper.h b/include/bcc/Support/Sha1Helper.h
deleted file mode 100644
index da98a36..0000000
--- a/include/bcc/Support/Sha1Helper.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2010-2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BCC_SUPPORT_SHA1_HELPER_H
-#define BCC_SUPPORT_SHA1_HELPER_H
-
-#include <stddef.h>
-
-namespace bcc {
-
-extern unsigned char sha1LibBCC_SHA1[20];
-extern char const *pathLibBCC_SHA1;
-
-extern unsigned char sha1LibRS[20];
-extern char const *pathLibRS;
-
-void calcSHA1(unsigned char *result, char const *data, size_t size);
-
-void calcFileSHA1(unsigned char *result, char const *filename);
-
-// Read binary representation of sha1 from filename.
-void readSHA1(unsigned char *result, int resultsize, char const *filename);
-
-} // end namespace bcc
-
-#endif // BCC_SUPPORT_SHA1_HELPER_H
diff --git a/include/bcc/Support/Sha1Util.h b/include/bcc/Support/Sha1Util.h
new file mode 100644
index 0000000..b7712ed
--- /dev/null
+++ b/include/bcc/Support/Sha1Util.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_SHA1_UTIL_H
+#define BCC_SUPPORT_SHA1_UTIL_H
+
+#include <stdint.h>
+
+#include <cstddef>
+
+// This guard prevents system sha1.h (such as the one in bionic) has been
+// included before this header.
+#ifndef SHA1_DIGEST_LENGTH
+#define SHA1_DIGEST_LENGTH 20
+#endif
+
+namespace bcc {
+
+class Sha1Util {
+private:
+  Sha1Util(); // DISABLED.
+  Sha1Util(Sha1Util &); // DISABLED.
+
+public:
+  // Return true on success.
+  static bool GetSHA1DigestFromFile(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                    const char *pFilename);
+
+  // Return true on success.
+  static bool GetSHA1DigestFromBuffer(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                      const uint8_t *pData, size_t pSize);
+
+  // Useful function when passing buffer of type  "const char *."
+  static bool GetSHA1DigestFromBuffer(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                      const char *pData, size_t pSize) {
+    return GetSHA1DigestFromBuffer(pResult,
+                                   reinterpret_cast<const uint8_t*>(pData),
+                                   pSize);
+  }
+};
+
+} // end namespace bcc
+
+#endif // BCC_SUPPORT_SHA1_UTIL_H
diff --git a/lib/Core/bcc.cpp b/lib/Core/bcc.cpp
index fd1153c..5a7bfa5 100644
--- a/lib/Core/bcc.cpp
+++ b/lib/Core/bcc.cpp
@@ -31,7 +31,7 @@
 #include "bcc/Source.h"
 #include "bcc/Support/Log.h"
 #include "bcc/Support/Initialization.h"
-#include "bcc/Support/Sha1Helper.h"
+#include "bcc/Support/Sha1Util.h"
 
 #include "bcc_internal.h"
 
@@ -132,9 +132,9 @@
   }
 
   if (need_dependency_check) {
-    uint8_t sha1[20];
-    calcSHA1(sha1, pBitcode, pBitcodeSize);
-    if (!pCtx->script->addSourceDependency(pName, sha1)) {
+    uint8_t sha1[SHA1_DIGEST_LENGTH];
+    if (!Sha1Util::GetSHA1DigestFromBuffer(sha1, pBitcode, pBitcodeSize) ||
+        !pCtx->script->addSourceDependency(pName, sha1)) {
       return false;
     }
   }
@@ -206,9 +206,9 @@
   }
 
   if (need_dependency_check) {
-    uint8_t sha1[20];
-    calcFileSHA1(sha1, pPath);
-    if (!pCtx->script->addSourceDependency(pPath, sha1)) {
+    uint8_t sha1[SHA1_DIGEST_LENGTH];
+    if (!Sha1Util::GetSHA1DigestFromFile(sha1, pPath) ||
+        !pCtx->script->addSourceDependency(pPath, sha1)) {
       return false;
     }
   }
diff --git a/lib/RenderScript/RSInfo.cpp b/lib/RenderScript/RSInfo.cpp
index 536c83b..f3010cf 100644
--- a/lib/RenderScript/RSInfo.cpp
+++ b/lib/RenderScript/RSInfo.cpp
@@ -17,35 +17,36 @@
 //#define LOG_NDEBUG 0
 #include "bcc/RenderScript/RSInfo.h"
 
+#include <dlfcn.h>
+
 #include <cstring>
 #include <new>
 
 #include "bcc/Support/FileBase.h"
 #include "bcc/Support/Log.h"
-#include "bcc/Support/Sha1Helper.h"
 
 using namespace bcc;
 
 const char RSInfo::LibBCCPath[] = "/system/lib/libbcc.so";
 const char RSInfo::LibRSPath[] = "/system/lib/libRS.so";
-uint8_t RSInfo::LibBCCSHA1[20];
-uint8_t RSInfo::LibRSSHA1[20];
+const uint8_t *RSInfo::LibBCCSHA1 = NULL;
+const uint8_t *RSInfo::LibRSSHA1 = NULL;
 
 void RSInfo::LoadBuiltInSHA1Information() {
-  static bool loaded = false;
-
-  if (loaded) {
+  if (LibBCCSHA1 != NULL) {
+    // Loaded before.
     return;
   }
 
-  // Read SHA-1 checksum of libbcc from hard-coded patch
-  // /system/lib/libbcc.so.sha1.
-  readSHA1(LibBCCSHA1, 20, "/system/lib/libbcc.so.sha1");
+  void *h = ::dlopen("/system/lib/libbcc.sha1.so", RTLD_LAZY | RTLD_NOW);
+  if (h == NULL) {
+    ALOGE("Failed to load SHA-1 information from shared library '"
+          "/system/lib/libbcc.sha1.so'! (%s)", ::dlerror());
+    return;
+  }
 
-  // Calculate the SHA-1 checksum of libRS.so.
-  calcFileSHA1(LibRSSHA1, LibRSPath);
-
-  loaded = true;
+  LibBCCSHA1 = reinterpret_cast<const uint8_t *>(::dlsym(h, "libbcc_so_SHA1"));
+  LibRSSHA1 = reinterpret_cast<const uint8_t *>(::dlsym(h, "libRS_so_SHA1"));
 
   return;
 }
@@ -86,7 +87,7 @@
         pInfo.mDependencyTable[1];
 
     // Check libbcc.so.
-    if (::memcmp(cache_libbcc_dep.second, LibBCCSHA1, 20) != 0) {
+    if (::memcmp(cache_libbcc_dep.second, LibBCCSHA1, SHA1_DIGEST_LENGTH) != 0) {
         ALOGD("Cache %s is dirty due to %s has been updated.", pInputFilename,
               LibBCCPath);
         PRINT_DEPENDENCY("current - ", LibBCCPath, LibBCCSHA1);
@@ -96,7 +97,7 @@
     }
 
     // Check libRS.so.
-    if (::memcmp(cache_libRS_dep.second, LibRSSHA1, 20) != 0) {
+    if (::memcmp(cache_libRS_dep.second, LibRSSHA1, SHA1_DIGEST_LENGTH) != 0) {
         ALOGD("Cache %s is dirty due to %s has been updated.", pInputFilename,
               LibRSPath);
         PRINT_DEPENDENCY("current - ", LibRSPath, LibRSSHA1);
@@ -113,7 +114,8 @@
       if ((::strncmp(in_dep.getSourceName().c_str(),
                      cache_dep.first,
                      in_dep.getSourceName().length()) != 0) ||
-          (::memcmp(in_dep.getSHA1Checksum(), cache_dep.second, 20) != 0)) {
+          (::memcmp(in_dep.getSHA1Checksum(), cache_dep.second,
+                    SHA1_DIGEST_LENGTH) != 0)) {
         ALOGD("Cache %s is dirty due to the source it dependends on has been "
               "changed:", pInputFilename);
         PRINT_DEPENDENCY("given - ", in_dep.getSourceName().c_str(),
diff --git a/lib/RenderScript/RSInfoExtractor.cpp b/lib/RenderScript/RSInfoExtractor.cpp
index 549e5e0..c303ef3 100644
--- a/lib/RenderScript/RSInfoExtractor.cpp
+++ b/lib/RenderScript/RSInfoExtractor.cpp
@@ -112,12 +112,13 @@
 
   uint8_t *sha1 = reinterpret_cast<uint8_t *>(pStringPool + *pWriteStart);
 
-  // SHA-1 is special. It's 20-bytes long without null-terminator.
-  ::memcpy(sha1, pSHA1, 20);
+  // SHA-1 is special. It's size of SHA1_DIGEST_LENGTH (=20) bytes long without
+  // null-terminator.
+  ::memcpy(sha1, pSHA1, SHA1_DIGEST_LENGTH);
   // Record in the result RSInfo object.
   pDepTable.push(std::make_pair(source_name, sha1));
   // Update the string pool pointer.
-  *pWriteStart += 20;
+  *pWriteStart += SHA1_DIGEST_LENGTH;
 
   return true;
 }
@@ -164,15 +165,15 @@
 
   // Don't forget to reserve the space for the dependency informationin string
   // pool.
-  string_pool_size += ::strlen(LibBCCPath) + 1 + 20;
-  string_pool_size += ::strlen(LibRSPath) + 1 + 20;
+  string_pool_size += ::strlen(LibBCCPath) + 1 + SHA1_DIGEST_LENGTH;
+  string_pool_size += ::strlen(LibRSPath) + 1 + SHA1_DIGEST_LENGTH;
   for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
     const RSScript::SourceDependency *source_dep = pDeps[i];
     if (source_dep != NULL) {
       // +1 for null-terminator
       string_pool_size += source_dep->getSourceName().length() + 1;
-      // +20 for SHA-1 checksum
-      string_pool_size += 20;
+      // +SHA1_DIGEST_LENGTH for SHA-1 checksum
+      string_pool_size += SHA1_DIGEST_LENGTH;
     }
   }
 
diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk
index 4bafba7..9782310 100644
--- a/lib/Support/Android.mk
+++ b/lib/Support/Android.mk
@@ -22,13 +22,12 @@
 #=====================================================================
 
 libbcc_support_SRC_FILES := \
-  sha1.c \
   CompilerConfig.cpp \
   FileBase.cpp \
   Initialization.cpp \
   InputFile.cpp \
   OutputFile.cpp \
-  Sha1Helper.cpp \
+  Sha1Util.cpp \
   TargetCompilerConfigs.cpp
 
 ifeq ($(libbcc_USE_DISASSEMBLER),1)
@@ -45,6 +44,7 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 
+# Bionic already includes SHA-1 routines.
 LOCAL_SRC_FILES := $(libbcc_support_SRC_FILES)
 
 include $(LIBBCC_DEVICE_BUILD_MK)
@@ -63,7 +63,9 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 
-LOCAL_SRC_FILES := $(libbcc_support_SRC_FILES)
+LOCAL_SRC_FILES := \
+  sha1.c \
+  $(libbcc_support_SRC_FILES)
 
 include $(LIBBCC_HOST_BUILD_MK)
 include $(LIBBCC_GEN_CONFIG_MK)
diff --git a/lib/Support/Sha1Helper.cpp b/lib/Support/Sha1Helper.cpp
deleted file mode 100644
index 6885131..0000000
--- a/lib/Support/Sha1Helper.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * copyright 2010-2012, the android open source project
- *
- * licensed under the apache license, version 2.0 (the "license");
- * you may not use this file except in compliance with the license.
- * you may obtain a copy of the license at
- *
- *     http://www.apache.org/licenses/license-2.0
- *
- * unless required by applicable law or agreed to in writing, software
- * distributed under the license is distributed on an "as is" basis,
- * without warranties or conditions of any kind, either express or implied.
- * see the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-#include "bcc/Support/Sha1Helper.h"
-
-#include <cstring>
-
-#include <utils/StopWatch.h>
-
-#include "bcc/Config/Config.h"
-#include "bcc/Support/Log.h"
-#include "bcc/Support/InputFile.h"
-
-#include "sha1.h"
-
-namespace bcc {
-
-unsigned char sha1LibBCC_SHA1[20];
-char const *pathLibBCC_SHA1 = "/system/lib/libbcc.so.sha1";
-
-unsigned char sha1LibRS[20];
-char const *pathLibRS = "/system/lib/libRS.so";
-
-void calcSHA1(unsigned char *result, char const *data, size_t size) {
-  SHA1_CTX hashContext;
-
-  SHA1Init(&hashContext);
-  SHA1Update(&hashContext,
-             reinterpret_cast<const unsigned char *>(data),
-             static_cast<unsigned long>(size));
-
-  SHA1Final(result, &hashContext);
-}
-
-
-void calcFileSHA1(unsigned char *result, char const *filename) {
-  android::StopWatch calcFileSHA1Timer("calcFileSHA1 time");
-
-  InputFile file(filename);
-
-  if (file.hasError()) {
-    ALOGE("Unable to open the file %s before SHA-1 checksum "
-          "calculation! (%s)", filename, file.getErrorMessage().c_str());
-    memset(result, '\0', 20);
-    return;
-  }
-
-  SHA1_CTX hashContext;
-  SHA1Init(&hashContext);
-
-  char buf[256];
-  while (true) {
-    ssize_t nread = file.read(buf, sizeof(buf));
-
-    if (nread < 0) {
-      break;
-    }
-
-    SHA1Update(&hashContext,
-               reinterpret_cast<unsigned char *>(buf),
-               static_cast<unsigned long>(nread));
-
-    if ((size_t)nread < sizeof(buf)) {
-      // finished.
-      break;
-    }
-  }
-
-  SHA1Final(result, &hashContext);
-}
-
-void readSHA1(unsigned char *result, int result_size, char const *filename) {
-  InputFile file(filename);
-  if (file.hasError()) {
-    ALOGE("Unable to open the binary sha1 file %s! (%s)", filename,
-          file.getErrorMessage().c_str());
-    memset(result, '\0', result_size);
-    return;
-  }
-  file.read((char *)result, result_size);
-}
-
-} // namespace bcc
diff --git a/lib/Support/Sha1Util.cpp b/lib/Support/Sha1Util.cpp
new file mode 100644
index 0000000..7cc636c
--- /dev/null
+++ b/lib/Support/Sha1Util.cpp
@@ -0,0 +1,77 @@
+/*
+ * copyright 2012, the android open source project
+ *
+ * licensed under the apache license, version 2.0 (the "license");
+ * you may not use this file except in compliance with the license.
+ * you may obtain a copy of the license at
+ *
+ *     http://www.apache.org/licenses/license-2.0
+ *
+ * unless required by applicable law or agreed to in writing, software
+ * distributed under the license is distributed on an "as is" basis,
+ * without warranties or conditions of any kind, either express or implied.
+ * see the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+#include "bcc/Support/Sha1Util.h"
+
+#include <sha1.h>
+
+#include <cstring>
+
+#include "bcc/Support/Log.h"
+#include "bcc/Support/InputFile.h"
+
+using namespace bcc;
+
+bool Sha1Util::GetSHA1DigestFromFile(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                     const char *pFilename) {
+  InputFile file(pFilename);
+
+  if (file.hasError()) {
+    ALOGE("Unable to open the file %s before SHA-1 checksum "
+          "calculation! (%s)", pFilename, file.getErrorMessage().c_str());
+    return false;
+  }
+
+  SHA1_CTX sha1_context;
+  SHA1Init(&sha1_context);
+
+  char buf[256];
+  while (true) {
+    ssize_t nread = file.read(buf, sizeof(buf));
+
+    if (nread < 0) {
+      // Some errors occurred during file reading.
+      return false;
+    }
+
+    SHA1Update(&sha1_context,
+               reinterpret_cast<unsigned char *>(buf),
+               static_cast<unsigned long>(nread));
+
+    if (static_cast<size_t>(nread) < sizeof(buf)) {
+      break;
+    }
+  }
+
+  SHA1Final(pResult, &sha1_context);
+
+  return true;
+}
+
+bool Sha1Util::GetSHA1DigestFromBuffer(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                       const uint8_t *pData, size_t pSize) {
+  SHA1_CTX sha1_context;
+
+  SHA1Init(&sha1_context);
+
+  SHA1Update(&sha1_context,
+             reinterpret_cast<const unsigned char *>(pData),
+             static_cast<unsigned long>(pSize));
+
+  SHA1Final(pResult, &sha1_context);
+
+  return true;
+}
diff --git a/tools/build/dataconvert.py b/tools/build/dataconvert.py
deleted file mode 100755
index 9aec157..0000000
--- a/tools/build/dataconvert.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-
-"""Convert data files to assembly output."""
-
-import sys
-
-
-def PrintHeader(var_name):
-  """Print out header for assembly file."""
-  sys.stdout.write("""
-#ifdef __APPLE_CC__
-/*\n\
- * The mid-2007 version of gcc that ships with Macs requires a\n\
- * comma on the .section line, but the rest of the world thinks\n\
- * that's a syntax error. It also wants globals to be explicitly\n\
- * prefixed with \"_\" as opposed to modern gccs that do the\n\
- * prefixing for you.\n\
- */\n\
-.globl _%s\n\
-  .section .rodata,\n\
-  .align 8\n\
-_%s:\n\
-#else\n\
-.globl %s\n\
-  .section .rodata\n\
-  .align 8\n\
-%s:\n\
-#endif\n\
-""" % (var_name, var_name, var_name, var_name))
-
-
-def File2Asm(var_name):
-  """Convert file to assembly output."""
-  PrintHeader(var_name)
-
-  input_size = 0
-  col = 0
-  while True:
-    buf = sys.stdin.read(1024)
-    if len(buf) <= 0:
-      break
-    input_size += len(buf)
-    for c in buf:
-      if col == 0:
-        sys.stdout.write(".byte ")
-      sys.stdout.write("0x%02x" % ord(c))
-      col += 1
-      if col == 8:
-        sys.stdout.write("\n")
-        col = 0
-      elif col % 4 == 0:
-        sys.stdout.write(", ")
-      else:
-        sys.stdout.write(",")
-  if col != 0:
-    sys.stdout.write("\n")
-
-  # encode file size
-  PrintHeader(var_name + "_size")
-  sys.stdout.write("  .long %d\n" % input_size)
-
-
-def main(argv):
-  if len(argv) < 2:
-    print "usage: %s <name>" % argv[0]
-    return 1
-
-  File2Asm(argv[1])
-
-if __name__ == "__main__":
-  main(sys.argv)
diff --git a/tools/build/gen-sha1-stamp.py b/tools/build/gen-sha1-stamp.py
index 9f9b728..239d040 100755
--- a/tools/build/gen-sha1-stamp.py
+++ b/tools/build/gen-sha1-stamp.py
@@ -15,6 +15,7 @@
 # limitations under the License.
 #
 
+import os
 import sys
 
 try:
@@ -33,20 +34,88 @@
             break
     f.close()
 
+"""The result is a list of pair of file path and its SHA-1 digest"""
 def compute_sha1_list(path_list):
-    h = sha1()
+    result = []
     for path in path_list:
+        h = sha1()
         compute_sha1(h, path)
-    return h.digest()
+        result.append((path, h.digest()))
+    return result
+
+"""For each path like /xxx/libfoo.so, generate a symbol named libfoo_so_SHA1"""
+def get_symbol_name(path):
+    return os.path.basename(path).replace('.', '_') + '_SHA1';
+
+"""Print out header for assembly file."""
+def print_asm_header(symbols):
+    sys.stdout.write("""
+/*\
+ * The mid-2007 version of gcc that ships with Macs requires a\n\
+ * comma on the .section line, but the rest of the world thinks\n\
+ * that's a syntax error. It also wants globals to be explicitly\n\
+ * prefixed with \"_\" as opposed to modern gccs that do the\n\
+ * prefixing for you.\n\
+ */\n\
+""")
+    for sym in symbols:
+        sys.stdout.write("""
+#ifdef __APPLE_CC__
+.globl _%s\n\
+#else\n\
+.globl %s\n\
+#endif\
+""" % (sym, sym))
+    sys.stdout.write("""
+#ifdef __APPLE_CC__
+  .section .rodata,\n\
+#else\n\
+  .section .rodata\n\
+#endif\
+""" )
+
+def print_asm_data(data, size):
+    col = 0
+    sys.stdout.write(".align 8\n")
+    for i in xrange(size):
+        c = data[i]
+        if col == 0:
+            sys.stdout.write(".byte ")
+        elif col % 4 == 0:
+            sys.stdout.write(", ")
+        else:
+            sys.stdout.write(",")
+        sys.stdout.write("0x%02x" % ord(c))
+        col += 1
+        if col == 8:
+            sys.stdout.write("\n")
+            col = 0
+    if col != 0:
+        sys.stdout.write("\n")
+
+def print_asm_symbol_data(sym, h):
+    sys.stdout.write("""
+#ifdef __APPLE_CC__
+_%s:\n\
+#else\n\
+%s:\n\
+#endif\n\
+""" % (sym, sym))
+    print_asm_data(h, 20)
+
+def print_asm(x):
+    symbols = [get_symbol_name(item[0]) for item in x]
+    print_asm_header(symbols)
+    for (symbol, y) in zip(symbols, x):
+        print_asm_symbol_data(symbol, y[1])
 
 def main():
     if len(sys.argv) < 2:
         print 'USAGE:', sys.argv[0], '[OUTPUT] [INPUTs]'
         sys.exit(1)
 
-    f = open(sys.argv[1], 'wb')
-    f.write(compute_sha1_list(sys.argv[2:]))
-    f.close()
+    result = compute_sha1_list(sys.argv[1:])
+    print_asm(result)
 
 if __name__ == '__main__':
     main()