Modify the library fix up code.

Modify the library lookup code to try and find the various places
that a library might really exist in the symbols directory. This
is for atest which can run executables in different locations
than the actual where the symbolized file exists.

Test: Ran using /data/local/tmp, /data/local/tests,
Test: /data/local/tests/vendor, /data/local/tests/unrestricted and
Test: verified the correct library was found.
Test: Used tombstones crash data and verified all libraries
Test: still found properly.
Test: Ran atest CtsBionicTestCases and verified the symbolized
Test: binary could be found using a real tombstone crash.
Test: Did the same as above, but changed the path in the tombstone
Test: crash data from /data/local/tmp to /data/local/tests and
Test: /data/local/tests/unrestricted.
Change-Id: Iaa121823ef6142eaf9f7de3232b147bd7389bea5
diff --git a/scripts/stack_core.py b/scripts/stack_core.py
index 3f22e38..6801fa1 100755
--- a/scripts/stack_core.py
+++ b/scripts/stack_core.py
@@ -295,6 +295,58 @@
       return file_name, tmp_shared_lib
     return None, None
 
+  def GetLibPath(self, lib):
+    symbol_dir = symbol.SYMBOLS_DIR
+    if os.path.isfile(symbol_dir + lib):
+      return lib
+
+    # When using atest, test paths are different between the out/ directory
+    # and device. Apply fixups.
+    if not lib.startswith("/data/local/tests/") and not lib.startswith("/data/local/tmp/"):
+      print("WARNING: Cannot find %s in symbol directory" % lib)
+      return lib
+
+    test_name = lib.rsplit("/", 1)[-1]
+    test_dir = "/data/nativetest"
+    test_dir_bitness = ""
+    if symbol.ARCH.endswith("64"):
+      bitness = "64"
+      test_dir_bitness = "64"
+    else:
+      bitness = "32"
+
+    # Unfortunately, the location of the real symbol file is not
+    # standardized, so we need to go hunting for it.
+
+    # This is in vendor, look for the value in:
+    #   /data/nativetest{64}/vendor/test_name/test_name
+    if lib.startswith("/data/local/tests/vendor/"):
+       lib_path = os.path.join(test_dir + test_dir_bitness, "vendor", test_name, test_name)
+       if os.path.isfile(symbol_dir + lib_path):
+         return lib_path
+
+    # Look for the path in:
+    #   /data/nativetest{64}/test_name/test_name
+    lib_path = os.path.join(test_dir + test_dir_bitness, test_name, test_name)
+    if os.path.isfile(symbol_dir + lib_path):
+      return lib_path
+
+    # CtsXXX tests are in really non-standard locations try:
+    #  /data/nativetest/{test_name}
+    lib_path = os.path.join(test_dir, test_name)
+    if os.path.isfile(symbol_dir + lib_path):
+      return lib_path
+    # Try:
+    #   /data/nativetest/{test_name}{32|64}
+    lib_path += bitness
+    if os.path.isfile(symbol_dir + lib_path):
+      return lib_path
+
+    # Cannot find location, give up and return the original path
+    print("WARNING: Cannot find %s in symbol directory" % lib)
+    return lib
+
+
   def ProcessLine(self, line):
     ret = False
     process_header = self.process_info_line.search(line)
@@ -388,14 +440,7 @@
 
         # When using atest, test paths are different between the out/ directory
         # and device. Apply fixups.
-        if lib.startswith("/data/local/tests/") or lib.startswith("/data/local/tmp/"):
-          test_name = lib.rsplit("/", 1)[-1]
-          prefix = "/data/nativetest"
-          if symbol.ARCH.endswith("64"):
-            prefix += "64"
-          if lib.startswith("/data/local/tests/vendor/"):
-            prefix += "/vendor"
-          lib = prefix + "/" + test_name + "/" + test_name
+        lib = self.GetLibPath(lib)
 
         # If a calls b which further calls c and c is inlined to b, we want to
         # display "a -> b -> c" in the stack trace instead of just "a -> c"