[llvm-commits] [compiler-rt] r148385 - in /compiler-rt/trunk/lib/asan: asan_internal.h asan_linux.cc asan_mac.cc asan_procmaps.h
Alexander Potapenko
glider at google.com
Wed Jan 18 03:16:05 PST 2012
Author: glider
Date: Wed Jan 18 05:16:05 2012
New Revision: 148385
URL: http://llvm.org/viewvc/llvm-project?rev=148385&view=rev
Log:
Implement AsanProcMaps for Mac OS. The code from sysinfo/ is not needed anymore and should be cleaned up.
Modified:
compiler-rt/trunk/lib/asan/asan_internal.h
compiler-rt/trunk/lib/asan/asan_linux.cc
compiler-rt/trunk/lib/asan/asan_mac.cc
compiler-rt/trunk/lib/asan/asan_procmaps.h
Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=148385&r1=148384&r2=148385&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Wed Jan 18 05:16:05 2012
@@ -43,7 +43,8 @@
#ifdef __linux__
# define ASAN_USE_SYSINFO 0
#else
-# define ASAN_USE_SYSINFO 1
+// TODO(glider): clean up sysinfo.
+# define ASAN_USE_SYSINFO 0
#endif
#endif
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=148385&r1=148384&r2=148385&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Wed Jan 18 05:16:05 2012
@@ -220,17 +220,7 @@
bool AsanProcMaps::GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset,
char filename[],
size_t filename_size) {
- AsanProcMaps proc_maps;
- uintptr_t start, end, file_offset;
- while (proc_maps.Next(&start, &end, &file_offset, filename, filename_size)) {
- if (addr >= start && addr < end) {
- *offset = (addr - start) + file_offset;
- return true;
- }
- }
- if (filename_size)
- filename[0] = '\0';
- return false;
+ return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
}
#else // __arm__
Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=148385&r1=148384&r2=148385&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Wed Jan 18 05:16:05 2012
@@ -17,11 +17,13 @@
#include "asan_mac.h"
#include "asan_internal.h"
+#include "asan_procmaps.h"
#include "asan_stack.h"
#include "asan_thread.h"
#include "asan_thread_registry.h"
#include <crt_externs.h> // for _NSGetEnviron
+#include <mach-o/dyld.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/ucontext.h>
@@ -145,6 +147,94 @@
return close(fd);
}
+AsanProcMaps::AsanProcMaps() {
+ Reset();
+}
+
+AsanProcMaps::~AsanProcMaps() {
+}
+
+void AsanProcMaps::Reset() {
+ // Count down from the top.
+ // TODO(glider): as per man 3 dyld, iterating over the headers with
+ // _dyld_image_count is thread-unsafe.
+ current_image_ = _dyld_image_count();
+ current_load_cmd_ = -1;
+}
+
+// Similar code is used in Google Perftools,
+// http://code.google.com/p/google-perftools.
+template<uint32_t kMagic, uint32_t kLCSegment,
+ typename MachHeader, typename SegmentCommand>
+static bool NextExtMachHelper(const mach_header* hdr,
+ int current_image, int current_load_cmd,
+ uintptr_t *start, uintptr_t *end,
+ uintptr_t *offset,
+ char filename[], size_t filename_size) {
+ if (hdr->magic != kMagic)
+ return false;
+ const char* lc = (const char *)hdr + sizeof(MachHeader);
+ // TODO(csilvers): make this not-quadradic (increment and hold state)
+ for (int j = 0; j < current_load_cmd; j++) // advance to *our* load_cmd
+ lc += ((const load_command *)lc)->cmdsize;
+ if (((const load_command *)lc)->cmd == kLCSegment) {
+ const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image);
+ const SegmentCommand* sc = (const SegmentCommand *)lc;
+ if (start) *start = sc->vmaddr + dlloff;
+ if (end) *end = sc->vmaddr + sc->vmsize + dlloff;
+ if (offset) *offset = sc->fileoff;
+ if (filename) {
+ real_strncpy(filename, _dyld_get_image_name(current_image),
+ filename_size);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool AsanProcMaps::Next(uintptr_t *start, uintptr_t *end,
+ uintptr_t *offset, char filename[],
+ size_t filename_size) {
+ // We return a separate entry for each segment in the DLL. (TODO(csilvers):
+ // can we do better?) A DLL ("image") has load-commands, some of which
+ // talk about segment boundaries.
+ // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/minivoicemail/dlfcn.c?revision=53912
+ for (; current_image_ >= 0; current_image_--) {
+ const mach_header* hdr = _dyld_get_image_header(current_image_);
+ if (!hdr) continue;
+ if (current_load_cmd_ < 0) // set up for this image
+ current_load_cmd_ = hdr->ncmds; // again, go from the top down
+
+ // We start with the next load command (we've already looked at this one).
+ for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {
+#ifdef MH_MAGIC_64
+ if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64,
+ struct mach_header_64, struct segment_command_64>(
+ hdr, current_image_, current_load_cmd_,
+ start, end, offset, filename, filename_size)) {
+ return true;
+ }
+#endif
+ if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT,
+ struct mach_header, struct segment_command>(
+ hdr, current_image_, current_load_cmd_,
+ start, end, offset, filename, filename_size)) {
+ return true;
+ }
+ }
+ // If we get here, no more load_cmd's in this image talk about
+ // segments. Go on to the next image.
+ }
+ // We didn't find anything.
+ return false;
+}
+
+bool AsanProcMaps::GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset,
+ char filename[],
+ size_t filename_size) {
+ return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
+}
+
void AsanThread::SetThreadStackTopAndBottom() {
size_t stacksize = pthread_get_stacksize_np(pthread_self());
void *stackaddr = pthread_get_stackaddr_np(pthread_self());
@@ -154,7 +244,6 @@
CHECK(AddrIsInStack((uintptr_t)&local));
}
-
AsanLock::AsanLock(LinkerInitialized) {
// We assume that OS_SPINLOCK_INIT is zero
}
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=148385&r1=148384&r2=148385&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_procmaps.h (original)
+++ compiler-rt/trunk/lib/asan/asan_procmaps.h Wed Jan 18 05:16:05 2012
@@ -30,13 +30,33 @@
char filename[], size_t filename_size);
~AsanProcMaps();
private:
+ // Default implementation of GetObjectNameAndOffset.
+ // Quite slow, because it iterates through the whole process map for each
+ // lookup.
+ bool IterateForObjectNameAndOffset(uintptr_t addr, uintptr_t *offset,
+ char filename[], size_t filename_size) {
+ AsanProcMaps proc_maps;
+ uintptr_t start, end, file_offset;
+ while (proc_maps.Next(&start, &end, &file_offset,
+ filename, filename_size)) {
+ if (addr >= start && addr < end) {
+ *offset = (addr - start) + file_offset;
+ return true;
+ }
+ }
+ if (filename_size)
+ filename[0] = '\0';
+ return false;
+ }
+
#if defined __linux__
char *proc_self_maps_buff_;
size_t proc_self_maps_buff_mmaped_size_;
size_t proc_self_maps_buff_len_;
char *current_;
#elif defined __APPLE__
-// FIXME: Mac code goes here
+ int current_image_;
+ int current_load_cmd_;
#endif
};
More information about the llvm-commits
mailing list