[llvm-commits] [compiler-rt] r147628 - in /compiler-rt/trunk/lib/asan: asan_linux.cc asan_procmaps.h asan_stack.cc

Kostya Serebryany kcc at google.com
Thu Jan 5 15:50:34 PST 2012


Author: kcc
Date: Thu Jan  5 17:50:34 2012
New Revision: 147628

URL: http://llvm.org/viewvc/llvm-project?rev=147628&view=rev
Log:
[asan] use dl_iterate_phdr for pre-symbolization on linux instead of parsing /proc/self/maps 

Modified:
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_procmaps.h
    compiler-rt/trunk/lib/asan/asan_stack.cc

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=147628&r1=147627&r2=147628&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Thu Jan  5 17:50:34 2012
@@ -24,17 +24,16 @@
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <link.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <unistd.h>
 
-extern char _DYNAMIC[];
-
 namespace __asan {
 
 void *AsanDoesNotSupportStaticLinkage() {
   // This will fail to link with -static.
-  return &_DYNAMIC;
+  return &_DYNAMIC;  // defined in link.h
 }
 
 static void *asan_mmap(void *addr, size_t length, int prot, int flags,
@@ -120,20 +119,20 @@
   current_ = proc_self_maps_buff_;
 }
 
-bool AsanProcMaps::Next(uint64_t *start, uint64_t *end,
-                        uint64_t *offset, char filename[],
+bool AsanProcMaps::Next(uintptr_t *start, uintptr_t *end,
+                        uintptr_t *offset, char filename[],
                         size_t filename_size) {
   char *last = proc_self_maps_buff_ + proc_self_maps_buff_len_;
   if (current_ >= last) return false;
   int consumed = 0;
   char flags[10];
   int major, minor;
-  uint64_t inode;
+  uintptr_t inode;
   char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
   if (next_line == NULL)
     next_line = last;
   if (SScanf(current_,
-             "%llx-%llx %4s %llx %x:%x %lld %n",
+             "%lx-%lx %4s %lx %x:%x %ld %n",
              start, end, flags, offset, &major, &minor,
              &inode, &consumed) != 7)
     return false;
@@ -154,6 +153,50 @@
   return true;
 }
 
+struct DlIterateData {
+  int count;
+  uintptr_t addr;
+  uintptr_t offset;
+  char *filename;
+  size_t filename_size;
+};
+
+static int dl_iterate_phdr_callback(struct dl_phdr_info *info,
+                                    size_t size, void *raw_data) {
+  DlIterateData *data = (DlIterateData*)raw_data;
+  int count = data->count++;
+  if (info->dlpi_addr > data->addr)
+    return 0;
+  if (count == 0) {
+    // The first item (the main executable) does not have a so name,
+    // but we can just read it from /proc/self/exe.
+    ssize_t path_len = readlink("/proc/self/exe",
+                                data->filename, data->filename_size - 1);
+    data->filename[path_len] = 0;
+  } else {
+    CHECK(info->dlpi_name);
+    real_strncpy(data->filename, info->dlpi_name, data->filename_size);
+  }
+  data->offset = data->addr - info->dlpi_addr;
+  return 1;
+}
+
+// Gets the object name and the offset using dl_iterate_phdr.
+bool AsanProcMaps::GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset,
+                                          char filename[],
+                                          size_t filename_size) {
+  DlIterateData data;
+  data.count = 0;
+  data.addr = addr;
+  data.filename = filename;
+  data.filename_size = filename_size;
+  if (dl_iterate_phdr(dl_iterate_phdr_callback, &data)) {
+    *offset = data.offset;
+    return true;
+  }
+  return false;
+}
+
 void AsanThread::SetThreadStackTopAndBottom() {
   if (tid() == 0) {
     // This is the main thread. Libpthread may not be initialized yet.
@@ -162,8 +205,8 @@
 
     // Find the mapping that contains a stack variable.
     AsanProcMaps proc_maps;
-    uint64_t start, end, offset;
-    uint64_t prev_end = 0;
+    uintptr_t start, end, offset;
+    uintptr_t prev_end = 0;
     while (proc_maps.Next(&start, &end, &offset, NULL, 0)) {
       if ((uintptr_t)&rl < end)
         break;

Modified: compiler-rt/trunk/lib/asan/asan_procmaps.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_procmaps.h?rev=147628&r1=147627&r2=147628&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_procmaps.h (original)
+++ compiler-rt/trunk/lib/asan/asan_procmaps.h Thu Jan  5 17:50:34 2012
@@ -21,9 +21,13 @@
 class AsanProcMaps {
  public:
   AsanProcMaps();
-  bool Next(uint64_t *start, uint64_t *end, uint64_t *offset,
+  bool Next(uintptr_t *start, uintptr_t *end, uintptr_t *offset,
             char filename[], size_t filename_size);
   void Reset();
+  // Gets the object file name and the offset in that object for a given
+  // address 'addr'. Returns true on success.
+  bool GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset,
+                              char filename[], size_t filename_size);
   ~AsanProcMaps();
  private:
 #if defined __linux__

Modified: compiler-rt/trunk/lib/asan/asan_stack.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.cc?rev=147628&r1=147627&r2=147628&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stack.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_stack.cc Thu Jan  5 17:50:34 2012
@@ -133,21 +133,12 @@
   for (size_t i = 0; i < size && addr[i]; i++) {
     proc_maps.Reset();
     uintptr_t pc = addr[i];
-    uint64_t start, end, offset;
+    uintptr_t offset;
     char filename[4096];
-    bool found = 0;
-    int map_idx = 0;
-    while (proc_maps.Next(&start, &end, &offset,
-                          filename, sizeof(filename))) {
-      if (pc >= start && pc <= end) {
-        found = true;
-        uintptr_t relative_pc = (map_idx == 0) ? pc : (pc - start);
-        Printf("    #%ld 0x%lx (%s+0x%lx)\n", i, pc, filename, relative_pc);
-        break;
-      }
-      map_idx++;
-    }
-    if (!found) {
+    if (proc_maps.GetObjectNameAndOffset(pc, &offset,
+                                         filename, sizeof(filename))) {
+      Printf("    #%ld 0x%lx (%s+0x%lx)\n", i, pc, filename, offset);
+    } else {
       Printf("    #%ld 0x%lx\n", i, pc);
     }
   }





More information about the llvm-commits mailing list