[ASan] subtract one from PCs in ASan error reports (as they originally contain return addresses). Make output tests stricter.

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@160508 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_stack.cc b/lib/asan/asan_stack.cc
index f90c69b..d6103c2 100644
--- a/lib/asan/asan_stack.cc
+++ b/lib/asan/asan_stack.cc
@@ -27,10 +27,23 @@
 namespace __asan {
 
 // ----------------------- AsanStackTrace ----------------------------- {{{1
+// PCs in stack traces are actually the return addresses, that is,
+// addresses of the next instructions after the call. That's why we
+// decrement them.
+static uptr patch_pc(uptr pc) {
+#ifdef __arm__
+  // Cancel Thumb bit.
+  pc = pc & (~1);
+#endif
+  return pc - 1;
+}
+
 #if defined(ASAN_USE_EXTERNAL_SYMBOLIZER)
 void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
   for (uptr i = 0; i < size && addr[i]; i++) {
     uptr pc = addr[i];
+    if (i < size - 1 && addr[i + 1])
+      pc = patch_pc(pc);
     char buff[4096];
     ASAN_USE_EXTERNAL_SYMBOLIZER((void*)pc, buff, sizeof(buff));
     AsanPrintf("  #%zu 0x%zx %s\n", i, pc, buff);
@@ -43,11 +56,12 @@
   uptr frame_num = 0;
   for (uptr i = 0; i < size && addr[i]; i++) {
     uptr pc = addr[i];
+    if (i < size - 1 && addr[i + 1])
+      pc = patch_pc(pc);
     AddressInfo addr_frames[64];
     uptr addr_frames_num = 0;
     if (flags()->symbolize) {
-      bool last_frame = (i == size - 1) || !addr[i + 1];
-      addr_frames_num = SymbolizeCode(pc - !last_frame, addr_frames,
+      addr_frames_num = SymbolizeCode(pc, addr_frames,
                                       ASAN_ARRAY_SIZE(addr_frames));
     }
     if (addr_frames_num > 0) {
diff --git a/lib/asan/output_tests/heap-overflow.cc b/lib/asan/output_tests/heap-overflow.cc
index bc8a9f8..534fbe0 100644
--- a/lib/asan/output_tests/heap-overflow.cc
+++ b/lib/asan/output_tests/heap-overflow.cc
@@ -14,9 +14,9 @@
 // Check-Common: {{allocated by thread T0 here:}}
 
 // Check-Linux: {{    #0 0x.* in .*malloc}}
-// Check-Linux: {{    #1 0x.* in main .*heap-overflow.cc:[45]}}
+// Check-Linux: {{    #1 0x.* in main .*heap-overflow.cc:4}}
 
 // Check-Darwin: {{    #0 0x.* in .*mz_malloc.*}}
 // Check-Darwin: {{    #1 0x.* in malloc_zone_malloc.*}}
 // Check-Darwin: {{    #2 0x.* in malloc.*}}
-// Check-Darwin: {{    #3 0x.* in main heap-overflow.cc:[45]}}
+// Check-Darwin: {{    #3 0x.* in main heap-overflow.cc:4}}
diff --git a/lib/asan/output_tests/large_func_test.cc b/lib/asan/output_tests/large_func_test.cc
index f5876f9..49751b3 100644
--- a/lib/asan/output_tests/large_func_test.cc
+++ b/lib/asan/output_tests/large_func_test.cc
@@ -41,7 +41,7 @@
 // Check-Linux:  {{    #0 0x.* in LargeFunction.*large_func_test.cc:15}}
 // Check-Darwin: {{    #0 0x.* in .*LargeFunction.*large_func_test.cc:15}}
 
-// Check-Common: {{    #1 0x.* in main .*large_func_test.cc:3[012]}}
+// Check-Common: {{    #1 0x.* in main .*large_func_test.cc:31}}
 // Check-Common: {{0x.* is located 44 bytes to the right of 400-byte region}}
 // Check-Common: {{allocated by thread T0 here:}}
 // Check-Common: {{    #0 0x.* in operator new.*}}
diff --git a/lib/asan/output_tests/null_deref.cc b/lib/asan/output_tests/null_deref.cc
index 983dbd8..c152a42 100644
--- a/lib/asan/output_tests/null_deref.cc
+++ b/lib/asan/output_tests/null_deref.cc
@@ -10,9 +10,8 @@
 // Check-Common:   {{0x0*00028 .*pc 0x.*}}
 // Check-Common: {{AddressSanitizer can not provide additional info. ABORTING}}
 
-// atos on Mac cannot resolve the file:line info for frame 0 on the O1 level.
-// It also can't extract the symbol name correctly.
+// atos on Mac cannot extract the symbol name correctly.
 // Check-Linux: {{    #0 0x.* in NullDeref.*null_deref.cc:3}}
-// Check-Darwin: {{    #0 0x.* in .*NullDeref.*}}
+// Check-Darwin: {{    #0 0x.* in .*NullDeref.*null_deref.cc:3}}
 
-// Check-Common: {{    #1 0x.* in main.*null_deref.cc:[67]}}
+// Check-Common: {{    #1 0x.* in main.*null_deref.cc:6}}
diff --git a/lib/asan/output_tests/shared-lib-test.cc b/lib/asan/output_tests/shared-lib-test.cc
index bf47068..060fcde 100644
--- a/lib/asan/output_tests/shared-lib-test.cc
+++ b/lib/asan/output_tests/shared-lib-test.cc
@@ -39,4 +39,4 @@
 // Check-Common: {{.*ERROR: AddressSanitizer global-buffer-overflow}}
 // Check-Common: {{READ of size 4 at 0x.* thread T0}}
 // Check-Common: {{    #0 0x.*}}
-// Check-Common: {{    #1 0x.* in main .*shared-lib-test.cc:3[567]}}
+// Check-Common: {{    #1 0x.* in main .*shared-lib-test.cc:35}}
diff --git a/lib/asan/output_tests/strncpy-overflow.cc b/lib/asan/output_tests/strncpy-overflow.cc
index 0333622..66d5810 100644
--- a/lib/asan/output_tests/strncpy-overflow.cc
+++ b/lib/asan/output_tests/strncpy-overflow.cc
@@ -11,7 +11,7 @@
 // Check-Common: {{WRITE of size 1 at 0x.* thread T0}}
 // Check-Linux: {{    #0 0x.* in .*strncpy}}
 // Check-Darwin: {{    #0 0x.* in wrap_strncpy}}
-// Check-Common: {{    #1 0x.* in main .*strncpy-overflow.cc:[78]}}
+// Check-Common: {{    #1 0x.* in main .*strncpy-overflow.cc:7}}
 // Check-Common: {{0x.* is located 0 bytes to the right of 9-byte region}}
 // Check-Common: {{allocated by thread T0 here:}}
 
diff --git a/lib/asan/output_tests/use-after-free.cc b/lib/asan/output_tests/use-after-free.cc
index 2d36bf0..c3e9dbe 100644
--- a/lib/asan/output_tests/use-after-free.cc
+++ b/lib/asan/output_tests/use-after-free.cc
@@ -13,12 +13,12 @@
 // Check-Common: {{freed by thread T0 here:}}
 
 // Check-Linux: {{    #0 0x.* in .*free}}
-// Check-Linux: {{    #1 0x.* in main .*use-after-free.cc:[45]}}
+// Check-Linux: {{    #1 0x.* in main .*use-after-free.cc:4}}
 
 // Check-Darwin: {{    #0 0x.* in .*mz_free.*}}
 // We override free() on Darwin, thus no malloc_zone_free
 // Check-Darwin: {{    #1 0x.* in wrap_free}}
-// Check-Darwin: {{    #2 0x.* in main .*use-after-free.cc:[45]}}
+// Check-Darwin: {{    #2 0x.* in main .*use-after-free.cc:4}}
 
 // Check-Common: {{previously allocated by thread T0 here:}}
 
diff --git a/lib/asan/scripts/asan_symbolize.py b/lib/asan/scripts/asan_symbolize.py
index 14ec5bf..e4897d0 100755
--- a/lib/asan/scripts/asan_symbolize.py
+++ b/lib/asan/scripts/asan_symbolize.py
@@ -17,22 +17,6 @@
 filetypes = {}
 DEBUG=False
 
-def patch_address(frameno, addr_s):
-  ''' Subtracts 1 or 2 from the top frame's address.
-  Top frame is normally the return address from asan_report*
-  call, which is not expected to return at all. Because of that, this
-  address often belongs to the next source code line, or even to a different
-  function. '''
-  if frameno == '0':
-    addr = int(addr_s, 16)
-    if os.uname()[4].startswith('arm'):
-      # Cancel the Thumb bit
-      addr = addr & (~1)
-    addr -= 1
-    return hex(addr)
-  return addr_s
-
-
 def fix_filename(file_name):
   for path_to_cut in sys.argv[1:]:
     file_name = re.sub(".*" + path_to_cut, "", file_name)
@@ -49,7 +33,6 @@
     frameno = match.group(2)
     binary = match.group(3)
     addr = match.group(4)
-    addr = patch_address(frameno, addr)
     if not pipes.has_key(binary):
       pipes[binary] = subprocess.Popen(["addr2line", "-f", "-e", binary],
                          stdin=subprocess.PIPE, stdout=subprocess.PIPE)
@@ -90,7 +73,7 @@
     orig_addr = match.group(3)
     binary = match.group(4)
     offset = match.group(5)
-    addr = patch_address(frameno, orig_addr)
+    addr = orig_addr
     load_addr = hex(int(orig_addr, 16) - int(offset, 16))
     filetype = get_macho_filetype(binary)