diff mbox

Do not build libsanitizer also for powerpc*-*-linux*

Message ID 20140530134933.GZ10386@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek May 30, 2014, 1:49 p.m. UTC
On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote:
> On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote:
> > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote:
> > > This is being discussed in the thread at
> > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>.  Until that
> > > has been resolved, I do agree to check in the following patch (and have
> > > successfully tested it, but cannot formally approve it for commit; thus
> > > copying the libsanitizer maintainers):
> > 
> > The re-enablement patch was submitted to the llvm mailing list here:
> > 
> >   http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html
> > 
> > Once that is committed and merged into gcc, we can re-enable building
> > libsanitizer for powerpc*-linux.
> 
> Ok, it was committed upstream as revision 209879.  Kostya, can we get
> this merged into gcc trunk and powerpc*-linux re-enabled again?  Thanks.

I've cherry-picked the two upstream commits and after testing on
x86_64-linux/i686-linux committed to trunk.

2014-05-30  Jakub Jelinek  <jakub@redhat.com>

	* sanitizer_common/sanitizer_stacktrace.cc: Cherry pick upstream
	r209879.
	* sanitizer_common/sanitizer_common.h: Likewise.
	* asan/asan_mapping.h: Likewise.
	* asan/asan_linux.cc: Likewise.
	* tsan/tsan_mman.cc: Cherry pick upstream r209744.
	* sanitizer_common/sanitizer_allocator.h: Likewise.



	Jakub

Comments

Konstantin Serebryany May 30, 2014, 6:02 p.m. UTC | #1
Thanks Jakub!
Looks like there is not rush with another merge now.

--kcc

On Fri, May 30, 2014 at 5:49 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote:
>> On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote:
>> > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote:
>> > > This is being discussed in the thread at
>> > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>.  Until that
>> > > has been resolved, I do agree to check in the following patch (and have
>> > > successfully tested it, but cannot formally approve it for commit; thus
>> > > copying the libsanitizer maintainers):
>> >
>> > The re-enablement patch was submitted to the llvm mailing list here:
>> >
>> >   http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html
>> >
>> > Once that is committed and merged into gcc, we can re-enable building
>> > libsanitizer for powerpc*-linux.
>>
>> Ok, it was committed upstream as revision 209879.  Kostya, can we get
>> this merged into gcc trunk and powerpc*-linux re-enabled again?  Thanks.
>
> I've cherry-picked the two upstream commits and after testing on
> x86_64-linux/i686-linux committed to trunk.
>
> 2014-05-30  Jakub Jelinek  <jakub@redhat.com>
>
>         * sanitizer_common/sanitizer_stacktrace.cc: Cherry pick upstream
>         r209879.
>         * sanitizer_common/sanitizer_common.h: Likewise.
>         * asan/asan_mapping.h: Likewise.
>         * asan/asan_linux.cc: Likewise.
>         * tsan/tsan_mman.cc: Cherry pick upstream r209744.
>         * sanitizer_common/sanitizer_allocator.h: Likewise.
>
> --- libsanitizer/sanitizer_common/sanitizer_stacktrace.cc       (revision 209878)
> +++ libsanitizer/sanitizer_common/sanitizer_stacktrace.cc       (revision 209879)
> @@ -18,11 +18,13 @@
>  namespace __sanitizer {
>
>  uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
> -#ifdef __arm__
> +#if defined(__arm__)
>    // Cancel Thumb bit.
>    pc = pc & (~1);
> -#endif
> -#if defined(__sparc__)
> +#elif defined(__powerpc__) || defined(__powerpc64__)
> +  // PCs are always 4 byte aligned.
> +  return pc - 4;
> +#elif defined(__sparc__)
>    return pc - 8;
>  #else
>    return pc - 1;
> --- libsanitizer/sanitizer_common/sanitizer_common.h    (revision 209878)
> +++ libsanitizer/sanitizer_common/sanitizer_common.h    (revision 209879)
> @@ -28,7 +28,11 @@ struct StackTrace;
>  const uptr kWordSize = SANITIZER_WORDSIZE / 8;
>  const uptr kWordSizeInBits = 8 * kWordSize;
>
> -const uptr kCacheLineSize = 64;
> +#if defined(__powerpc__) || defined(__powerpc64__)
> +  const uptr kCacheLineSize = 128;
> +#else
> +  const uptr kCacheLineSize = 64;
> +#endif
>
>  const uptr kMaxPathLength = 512;
>
> --- libsanitizer/asan/asan_mapping.h    (revision 209878)
> +++ libsanitizer/asan/asan_mapping.h    (revision 209879)
> @@ -87,6 +87,7 @@ static const u64 kDefaultShadowOffset64
>  static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000;  // < 2G.
>  static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
>  static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000;
> +static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
>  static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30;  // 0x40000000
>  static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46;  // 0x400000000000
>
> @@ -109,6 +110,8 @@ static const u64 kFreeBSD_ShadowOffset64
>  # else
>  #  if defined(__aarch64__)
>  #    define SHADOW_OFFSET kAArch64_ShadowOffset64
> +#  elif defined(__powerpc64__)
> +#    define SHADOW_OFFSET kPPC64_ShadowOffset64
>  #  elif SANITIZER_FREEBSD
>  #    define SHADOW_OFFSET kFreeBSD_ShadowOffset64
>  #  elif SANITIZER_MAC
> --- libsanitizer/asan/asan_linux.cc     (revision 209878)
> +++ libsanitizer/asan/asan_linux.cc     (revision 209879)
> @@ -188,6 +188,13 @@ void GetPcSpBp(void *context, uptr *pc,
>    *bp = ucontext->uc_mcontext.gregs[REG_EBP];
>    *sp = ucontext->uc_mcontext.gregs[REG_ESP];
>  # endif
> +#elif defined(__powerpc__) || defined(__powerpc64__)
> +  ucontext_t *ucontext = (ucontext_t*)context;
> +  *pc = ucontext->uc_mcontext.regs->nip;
> +  *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
> +  // The powerpc{,64}-linux ABIs do not specify r31 as the frame
> +  // pointer, but GCC always uses r31 when we need a frame pointer.
> +  *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
>  #elif defined(__sparc__)
>    ucontext_t *ucontext = (ucontext_t*)context;
>    uptr *stk_ptr;
> --- libsanitizer/tsan/tsan_mman.cc      (revision 209743)
> +++ libsanitizer/tsan/tsan_mman.cc      (revision 209744)
> @@ -217,19 +217,15 @@ using namespace __tsan;
>
>  extern "C" {
>  uptr __tsan_get_current_allocated_bytes() {
> -  u64 stats[AllocatorStatCount];
> +  uptr stats[AllocatorStatCount];
>    allocator()->GetStats(stats);
> -  u64 m = stats[AllocatorStatMalloced];
> -  u64 f = stats[AllocatorStatFreed];
> -  return m >= f ? m - f : 1;
> +  return stats[AllocatorStatAllocated];
>  }
>
>  uptr __tsan_get_heap_size() {
> -  u64 stats[AllocatorStatCount];
> +  uptr stats[AllocatorStatCount];
>    allocator()->GetStats(stats);
> -  u64 m = stats[AllocatorStatMmapped];
> -  u64 f = stats[AllocatorStatUnmapped];
> -  return m >= f ? m - f : 1;
> +  return stats[AllocatorStatMapped];
>  }
>
>  uptr __tsan_get_free_bytes() {
> --- libsanitizer/sanitizer_common/sanitizer_allocator.h (revision 209743)
> +++ libsanitizer/sanitizer_common/sanitizer_allocator.h (revision 209744)
> @@ -198,14 +198,12 @@ template<class SizeClassAllocator> struc
>
>  // Memory allocator statistics
>  enum AllocatorStat {
> -  AllocatorStatMalloced,
> -  AllocatorStatFreed,
> -  AllocatorStatMmapped,
> -  AllocatorStatUnmapped,
> +  AllocatorStatAllocated,
> +  AllocatorStatMapped,
>    AllocatorStatCount
>  };
>
> -typedef u64 AllocatorStatCounters[AllocatorStatCount];
> +typedef uptr AllocatorStatCounters[AllocatorStatCount];
>
>  // Per-thread stats, live in per-thread cache.
>  class AllocatorStats {
> @@ -214,16 +212,21 @@ class AllocatorStats {
>      internal_memset(this, 0, sizeof(*this));
>    }
>
> -  void Add(AllocatorStat i, u64 v) {
> +  void Add(AllocatorStat i, uptr v) {
>      v += atomic_load(&stats_[i], memory_order_relaxed);
>      atomic_store(&stats_[i], v, memory_order_relaxed);
>    }
>
> -  void Set(AllocatorStat i, u64 v) {
> +  void Sub(AllocatorStat i, uptr v) {
> +    v = atomic_load(&stats_[i], memory_order_relaxed) - v;
>      atomic_store(&stats_[i], v, memory_order_relaxed);
>    }
>
> -  u64 Get(AllocatorStat i) const {
> +  void Set(AllocatorStat i, uptr v) {
> +    atomic_store(&stats_[i], v, memory_order_relaxed);
> +  }
> +
> +  uptr Get(AllocatorStat i) const {
>      return atomic_load(&stats_[i], memory_order_relaxed);
>    }
>
> @@ -231,7 +234,7 @@ class AllocatorStats {
>    friend class AllocatorGlobalStats;
>    AllocatorStats *next_;
>    AllocatorStats *prev_;
> -  atomic_uint64_t stats_[AllocatorStatCount];
> +  atomic_uintptr_t stats_[AllocatorStatCount];
>  };
>
>  // Global stats, used for aggregation and querying.
> @@ -260,7 +263,7 @@ class AllocatorGlobalStats : public Allo
>    }
>
>    void Get(AllocatorStatCounters s) const {
> -    internal_memset(s, 0, AllocatorStatCount * sizeof(u64));
> +    internal_memset(s, 0, AllocatorStatCount * sizeof(uptr));
>      SpinMutexLock l(&mu_);
>      const AllocatorStats *stats = this;
>      for (;;) {
> @@ -270,6 +273,9 @@ class AllocatorGlobalStats : public Allo
>        if (stats == this)
>          break;
>      }
> +    // All stats must be positive.
> +    for (int i = 0; i < AllocatorStatCount; i++)
> +      s[i] = ((sptr)s[i]) > 0 ? s[i] : 1;
>    }
>
>   private:
> @@ -522,7 +528,7 @@ class SizeClassAllocator64 {
>          map_size += kUserMapSize;
>        CHECK_GE(region->mapped_user + map_size, end_idx);
>        MapWithCallback(region_beg + region->mapped_user, map_size);
> -      stat->Add(AllocatorStatMmapped, map_size);
> +      stat->Add(AllocatorStatMapped, map_size);
>        region->mapped_user += map_size;
>      }
>      uptr total_count = (region->mapped_user - beg_idx - size)
> @@ -841,7 +847,7 @@ class SizeClassAllocator32 {
>      uptr res = reinterpret_cast<uptr>(MmapAlignedOrDie(kRegionSize, kRegionSize,
>                                        "SizeClassAllocator32"));
>      MapUnmapCallback().OnMap(res, kRegionSize);
> -    stat->Add(AllocatorStatMmapped, kRegionSize);
> +    stat->Add(AllocatorStatMapped, kRegionSize);
>      CHECK_EQ(0U, (res & (kRegionSize - 1)));
>      possible_regions.set(ComputeRegionId(res), static_cast<u8>(class_id));
>      return res;
> @@ -907,7 +913,7 @@ struct SizeClassAllocatorLocalCache {
>    void *Allocate(SizeClassAllocator *allocator, uptr class_id) {
>      CHECK_NE(class_id, 0UL);
>      CHECK_LT(class_id, kNumClasses);
> -    stats_.Add(AllocatorStatMalloced, SizeClassMap::Size(class_id));
> +    stats_.Add(AllocatorStatAllocated, SizeClassMap::Size(class_id));
>      PerClass *c = &per_class_[class_id];
>      if (UNLIKELY(c->count == 0))
>        Refill(allocator, class_id);
> @@ -922,7 +928,7 @@ struct SizeClassAllocatorLocalCache {
>      // If the first allocator call on a new thread is a deallocation, then
>      // max_count will be zero, leading to check failure.
>      InitCache();
> -    stats_.Add(AllocatorStatFreed, SizeClassMap::Size(class_id));
> +    stats_.Sub(AllocatorStatAllocated, SizeClassMap::Size(class_id));
>      PerClass *c = &per_class_[class_id];
>      CHECK_NE(c->max_count, 0UL);
>      if (UNLIKELY(c->count == c->max_count))
> @@ -1033,8 +1039,8 @@ class LargeMmapAllocator {
>        stats.currently_allocated += map_size;
>        stats.max_allocated = Max(stats.max_allocated, stats.currently_allocated);
>        stats.by_size_log[size_log]++;
> -      stat->Add(AllocatorStatMalloced, map_size);
> -      stat->Add(AllocatorStatMmapped, map_size);
> +      stat->Add(AllocatorStatAllocated, map_size);
> +      stat->Add(AllocatorStatMapped, map_size);
>      }
>      return reinterpret_cast<void*>(res);
>    }
> @@ -1052,8 +1058,8 @@ class LargeMmapAllocator {
>        chunks_sorted_ = false;
>        stats.n_frees++;
>        stats.currently_allocated -= h->map_size;
> -      stat->Add(AllocatorStatFreed, h->map_size);
> -      stat->Add(AllocatorStatUnmapped, h->map_size);
> +      stat->Sub(AllocatorStatAllocated, h->map_size);
> +      stat->Sub(AllocatorStatMapped, h->map_size);
>      }
>      MapUnmapCallback().OnUnmap(h->map_beg, h->map_size);
>      UnmapOrDie(reinterpret_cast<void*>(h->map_beg), h->map_size);
>
>
>         Jakub
Peter Bergner May 31, 2014, 7:53 p.m. UTC | #2
On Fri, 2014-05-30 at 15:49 +0200, Jakub Jelinek wrote:
> On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote:
> > On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote:
> > > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote:
> > > > This is being discussed in the thread at
> > > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>.  Until that
> > > > has been resolved, I do agree to check in the following patch (and have
> > > > successfully tested it, but cannot formally approve it for commit; thus
> > > > copying the libsanitizer maintainers):
> > > 
> > > The re-enablement patch was submitted to the llvm mailing list here:
> > > 
> > >   http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html
> > > 
> > > Once that is committed and merged into gcc, we can re-enable building
> > > libsanitizer for powerpc*-linux.
> > 
> > Ok, it was committed upstream as revision 209879.  Kostya, can we get
> > this merged into gcc trunk and powerpc*-linux re-enabled again?  Thanks.
> 
> I've cherry-picked the two upstream commits and after testing on
> x86_64-linux/i686-linux committed to trunk.

Great, thanks!  I bootstrapped and ran the asan testsuite.  I'm now seeing
lots of FAILs due to:

  ASan runtime does not come first in initial library list; you should either
  link runtime to your application or manually preload it with LD_PRELOAD.

...which Paolo mentioned in the other thread that he is hitting this too.
There was some discussion on what to do, but has there been a decision on
how to fix this yet?  Or is it fixed upstream and we just need to merge
that fix too?

Peter
Konstantin Serebryany June 2, 2014, 4:54 a.m. UTC | #3
On Sat, May 31, 2014 at 11:53 PM, Peter Bergner <bergner@vnet.ibm.com> wrote:
> On Fri, 2014-05-30 at 15:49 +0200, Jakub Jelinek wrote:
>> On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote:
>> > On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote:
>> > > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote:
>> > > > This is being discussed in the thread at
>> > > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>.  Until that
>> > > > has been resolved, I do agree to check in the following patch (and have
>> > > > successfully tested it, but cannot formally approve it for commit; thus
>> > > > copying the libsanitizer maintainers):
>> > >
>> > > The re-enablement patch was submitted to the llvm mailing list here:
>> > >
>> > >   http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html
>> > >
>> > > Once that is committed and merged into gcc, we can re-enable building
>> > > libsanitizer for powerpc*-linux.
>> >
>> > Ok, it was committed upstream as revision 209879.  Kostya, can we get
>> > this merged into gcc trunk and powerpc*-linux re-enabled again?  Thanks.
>>
>> I've cherry-picked the two upstream commits and after testing on
>> x86_64-linux/i686-linux committed to trunk.
>
> Great, thanks!  I bootstrapped and ran the asan testsuite.  I'm now seeing
> lots of FAILs due to:
>
>   ASan runtime does not come first in initial library list; you should either
>   link runtime to your application or manually preload it with LD_PRELOAD.
>
> ...which Paolo mentioned in the other thread that he is hitting this too.
> There was some discussion on what to do, but has there been a decision on
> how to fix this yet?  Or is it fixed upstream and we just need to merge
> that fix too?
Yuri needs to send the patch to llvm-commits.
>
> Peter
>
>
Yury Gribov June 2, 2014, 5:57 a.m. UTC | #4
>> There was some discussion on what to do, but has there been a decision on
>> how to fix this yet?  Or is it fixed upstream and we just need to merge
>> that fix too?
> Yuri needs to send the patch to llvm-commits.

I think I already did that: D3911

-Y
Konstantin Serebryany June 2, 2014, 10:48 a.m. UTC | #5
Committed as r210012, please don't forget to add llvm-commits to CC
next time (I did not see the message)
Thanks!

On Mon, Jun 2, 2014 at 9:57 AM, Yury Gribov <y.gribov@samsung.com> wrote:
>>> There was some discussion on what to do, but has there been a decision on
>>> how to fix this yet?  Or is it fixed upstream and we just need to merge
>>> that fix too?
>>
>> Yuri needs to send the patch to llvm-commits.
>
>
> I think I already did that: D3911
>
> -Y
Peter Bergner June 3, 2014, 4:42 a.m. UTC | #6
On Mon, 2014-06-02 at 14:48 +0400, Konstantin Serebryany wrote:
> Committed as r210012, please don't forget to add llvm-commits to CC
> next time (I did not see the message)
> Thanks!

I took that patch and applied it to the gcc sources, but I still
see the error on ppc:

[bergner@makalu-lp1
asan]$ /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/ /home/bergner/gcc/gcc-fsf-mainline-asan/gcc/testsuite/c-c++-common/asan/asan-interface-1.c   -B/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/  -B/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/  -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs  -fsanitize=address -g -I/home/bergner/gcc/gcc-fsf-mainline-asan/gcc/testsuite/../../libsanitizer/include -fno-diagnostics-show-caret -fdiagnostics-color=never   -O0  -lm   -m32 -o ./asan-interface-1.exe

[bergner@makalu-lp1 asan]$
LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ./asan-interface-1.exe ==36082==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.

[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe 
	linux-vdso32.so.1 =>  (0x00100000)
	libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000)
	libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000)
	libc.so.6 => /lib/power8/libc.so.6 (0x0f740000)
	/lib/ld.so.1 (0x206b0000)
	libpthread.so.0 => /lib/power8/libpthread.so.0 (0x0f6f0000)
	libdl.so.2 => /lib/libdl.so.2 (0x0f6b0000)
	libstdc++.so.6 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libstdc++-v3/src/.libs/libstdc++.so.6 (0x0f520000)
	libgcc_s.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32/libgcc_s.so.1 (0x0f4c0000)

If I explicitly add a -lasan before the -lm on the compile, then
everything works fine.  Is this a test case error for not linking
-lasan before -lm or ???

Peter
Yury Gribov June 3, 2014, 6:19 a.m. UTC | #7
> I took that patch and applied it to the gcc sources,
> but I still see the error on ppc:
>...
> [bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe
> 	linux-vdso32.so.1 =>  (0x00100000)
> 	libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000)
> 	libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000)

Now check indeed seems to be useful: libasan should be the first library 
in the list when -fsanitize=address flag is present. Are compiler specs 
for Power somehow special?

-Y
Jakub Jelinek June 3, 2014, 6:41 a.m. UTC | #8
On Tue, Jun 03, 2014 at 10:19:48AM +0400, Yury Gribov wrote:
> >I took that patch and applied it to the gcc sources,
> >but I still see the error on ppc:
> >...
> >[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe
> >	linux-vdso32.so.1 =>  (0x00100000)
> >	libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000)
> >	libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000)
> 
> Now check indeed seems to be useful: libasan should be the first
> library in the list when -fsanitize=address flag is present. Are
> compiler specs for Power somehow special?

-fsanitize=address should insert -lasan quite early on the linker command
line, please try to cut'n'paste the command line from testsuite/g++/g++.log
and add -v to see what is passed to the linker.
Perhaps the linker reorders the libraries?
Or do you have LD_PRELOAD?

	Jakub
Peter Bergner June 3, 2014, 1:06 p.m. UTC | #9
On Tue, 2014-06-03 at 08:41 +0200, Jakub Jelinek wrote:
> On Tue, Jun 03, 2014 at 10:19:48AM +0400, Yury Gribov wrote:
> > >I took that patch and applied it to the gcc sources,
> > >but I still see the error on ppc:
> > >...
> > >[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe
> > >	linux-vdso32.so.1 =>  (0x00100000)
> > >	libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000)
> > >	libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000)
> > 
> > Now check indeed seems to be useful: libasan should be the first
> > library in the list when -fsanitize=address flag is present. Are
> > compiler specs for Power somehow special?
> 
> -fsanitize=address should insert -lasan quite early on the linker command
> line, please try to cut'n'paste the command line from testsuite/g++/g++.log
> and add -v to see what is passed to the linker.
> Perhaps the linker reorders the libraries?
> Or do you have LD_PRELOAD?

No LD_PRELOAD.  It adds -lasan "early", but after the libraries and
object files that are explicitly added to the linker command.
Since -lm is explicitly added to the linker command, the implicitly
added -lasan comes after.  The -v command is below.

Peter


/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/collect2
-plugin /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/liblto_plugin.so -plugin-opt=/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/lto-wrapper -plugin-opt=-fresolution=/tmp/cckyoSrJ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -V -m elf32ppclinux -dynamic-linker /lib/ld.so.1 -o ./asan-interface-1.exe /lib/../lib/crt1.o /lib/../lib/crti.o /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32/crtbegin.o -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32 -L/lib/../lib -L/usr/lib/../lib -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan /tmp/ccUTAlke.o -lm -lasan -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32/crtend.o /lib/../lib/crtn.o
Yury Gribov June 3, 2014, 1:17 p.m. UTC | #10
> It adds -lasan "early", but after the libraries and
 > object files that are explicitly added to the linker command.
 > Since -lm is explicitly added to the linker command, the implicitly
 > added -lasan comes after.  The -v command is below.

Hm, -lasan manages to override user-specified -lm on gcc trunk for x64:

$ /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/xgcc 
-B/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/ 
/home/ygribov/src/gcc-master/gcc/testsuite/c-c++-common/asan/asan-interface-1.c 
 
-B/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/ 
 
-B/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/ 
 
-L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/.libs 
  -fsanitize=address -g 
-I/home/ygribov/src/gcc-master/gcc/testsuite/../../libsanitizer/include 
-fno-diagnostics-show-caret -fdiagnostics-color=never   -O0    -lm   -o 
./asan-interface-1.exe -v

...

  /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/collect2 -plugin 
/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/liblto_plugin.so 
-plugin-opt=/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/lto-wrapper 
-plugin-opt=-fresolution=/tmp/ccZD4gPg.res 
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s 
-plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc 
-plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 
-dynamic-linker /lib64/ld-linux-x86-64.so.2 -o ./asan-interface-1.exe 
/usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o 
/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/crtbegin.o 
-L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/.libs 
-L/tmp/gcc-bootstrap-and-regtest/build-orig/gcc 
-L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer 
-L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan 
-L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu 
/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/libasan_preinit.o 
-lasan /tmp/ccgt1Kd9.o -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc 
-lgcc --as-needed -lgcc_s --no-as-needed 
/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/crtend.o 
/usr/lib/x86_64-linux-gnu/crtn.o

-Y
Jakub Jelinek June 3, 2014, 1:21 p.m. UTC | #11
On Tue, Jun 03, 2014 at 08:06:41AM -0500, Peter Bergner wrote:
> On Tue, 2014-06-03 at 08:41 +0200, Jakub Jelinek wrote:
> > On Tue, Jun 03, 2014 at 10:19:48AM +0400, Yury Gribov wrote:
> > > >I took that patch and applied it to the gcc sources,
> > > >but I still see the error on ppc:
> > > >...
> > > >[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe
> > > >	linux-vdso32.so.1 =>  (0x00100000)
> > > >	libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000)
> > > >	libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000)
> > > 
> > > Now check indeed seems to be useful: libasan should be the first
> > > library in the list when -fsanitize=address flag is present. Are
> > > compiler specs for Power somehow special?
> > 
> > -fsanitize=address should insert -lasan quite early on the linker command
> > line, please try to cut'n'paste the command line from testsuite/g++/g++.log
> > and add -v to see what is passed to the linker.
> > Perhaps the linker reorders the libraries?
> > Or do you have LD_PRELOAD?
> 
> No LD_PRELOAD.  It adds -lasan "early", but after the libraries and
> object files that are explicitly added to the linker command.
> Since -lm is explicitly added to the linker command, the implicitly
> added -lasan comes after.  The -v command is below.

Ah, that is a powerpc*-linux* bug.  All other linux targets include
config/gnu-user.h header, perhaps early and override it, but rs6000*
seems to be the only? exception that does not.

So, either you need to include that header and perhaps tweak afterwards,
or duplicate the asan/tsan related stuff in there and make sure to keep it
up to date.

	Jakub
Peter Bergner June 3, 2014, 1:39 p.m. UTC | #12
On Tue, 2014-06-03 at 15:21 +0200, Jakub Jelinek wrote:
> On Tue, Jun 03, 2014 at 08:06:41AM -0500, Peter Bergner wrote:
> > No LD_PRELOAD.  It adds -lasan "early", but after the libraries and
> > object files that are explicitly added to the linker command.
> > Since -lm is explicitly added to the linker command, the implicitly
> > added -lasan comes after.  The -v command is below.
> 
> Ah, that is a powerpc*-linux* bug.  All other linux targets include
> config/gnu-user.h header, perhaps early and override it, but rs6000*
> seems to be the only? exception that does not.
> 
> So, either you need to include that header and perhaps tweak afterwards,
> or duplicate the asan/tsan related stuff in there and make sure to keep it
> up to date.

I'll try adding the include.  Thanks for pointing that out!

Peter
diff mbox

Patch

--- libsanitizer/sanitizer_common/sanitizer_stacktrace.cc	(revision 209878)
+++ libsanitizer/sanitizer_common/sanitizer_stacktrace.cc	(revision 209879)
@@ -18,11 +18,13 @@ 
 namespace __sanitizer {
 
 uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
-#ifdef __arm__
+#if defined(__arm__)
   // Cancel Thumb bit.
   pc = pc & (~1);
-#endif
-#if defined(__sparc__)
+#elif defined(__powerpc__) || defined(__powerpc64__)
+  // PCs are always 4 byte aligned.
+  return pc - 4;
+#elif defined(__sparc__)
   return pc - 8;
 #else
   return pc - 1;
--- libsanitizer/sanitizer_common/sanitizer_common.h	(revision 209878)
+++ libsanitizer/sanitizer_common/sanitizer_common.h	(revision 209879)
@@ -28,7 +28,11 @@  struct StackTrace;
 const uptr kWordSize = SANITIZER_WORDSIZE / 8;
 const uptr kWordSizeInBits = 8 * kWordSize;
 
-const uptr kCacheLineSize = 64;
+#if defined(__powerpc__) || defined(__powerpc64__)
+  const uptr kCacheLineSize = 128;
+#else
+  const uptr kCacheLineSize = 64;
+#endif
 
 const uptr kMaxPathLength = 512;
 
--- libsanitizer/asan/asan_mapping.h	(revision 209878)
+++ libsanitizer/asan/asan_mapping.h	(revision 209879)
@@ -87,6 +87,7 @@  static const u64 kDefaultShadowOffset64
 static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000;  // < 2G.
 static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
 static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000;
+static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
 static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30;  // 0x40000000
 static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46;  // 0x400000000000
 
@@ -109,6 +110,8 @@  static const u64 kFreeBSD_ShadowOffset64
 # else
 #  if defined(__aarch64__)
 #    define SHADOW_OFFSET kAArch64_ShadowOffset64
+#  elif defined(__powerpc64__)
+#    define SHADOW_OFFSET kPPC64_ShadowOffset64
 #  elif SANITIZER_FREEBSD
 #    define SHADOW_OFFSET kFreeBSD_ShadowOffset64
 #  elif SANITIZER_MAC
--- libsanitizer/asan/asan_linux.cc	(revision 209878)
+++ libsanitizer/asan/asan_linux.cc	(revision 209879)
@@ -188,6 +188,13 @@  void GetPcSpBp(void *context, uptr *pc,
   *bp = ucontext->uc_mcontext.gregs[REG_EBP];
   *sp = ucontext->uc_mcontext.gregs[REG_ESP];
 # endif
+#elif defined(__powerpc__) || defined(__powerpc64__)
+  ucontext_t *ucontext = (ucontext_t*)context;
+  *pc = ucontext->uc_mcontext.regs->nip;
+  *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
+  // The powerpc{,64}-linux ABIs do not specify r31 as the frame
+  // pointer, but GCC always uses r31 when we need a frame pointer.
+  *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
 #elif defined(__sparc__)
   ucontext_t *ucontext = (ucontext_t*)context;
   uptr *stk_ptr;
--- libsanitizer/tsan/tsan_mman.cc	(revision 209743)
+++ libsanitizer/tsan/tsan_mman.cc	(revision 209744)
@@ -217,19 +217,15 @@  using namespace __tsan;
 
 extern "C" {
 uptr __tsan_get_current_allocated_bytes() {
-  u64 stats[AllocatorStatCount];
+  uptr stats[AllocatorStatCount];
   allocator()->GetStats(stats);
-  u64 m = stats[AllocatorStatMalloced];
-  u64 f = stats[AllocatorStatFreed];
-  return m >= f ? m - f : 1;
+  return stats[AllocatorStatAllocated];
 }
 
 uptr __tsan_get_heap_size() {
-  u64 stats[AllocatorStatCount];
+  uptr stats[AllocatorStatCount];
   allocator()->GetStats(stats);
-  u64 m = stats[AllocatorStatMmapped];
-  u64 f = stats[AllocatorStatUnmapped];
-  return m >= f ? m - f : 1;
+  return stats[AllocatorStatMapped];
 }
 
 uptr __tsan_get_free_bytes() {
--- libsanitizer/sanitizer_common/sanitizer_allocator.h	(revision 209743)
+++ libsanitizer/sanitizer_common/sanitizer_allocator.h	(revision 209744)
@@ -198,14 +198,12 @@  template<class SizeClassAllocator> struc
 
 // Memory allocator statistics
 enum AllocatorStat {
-  AllocatorStatMalloced,
-  AllocatorStatFreed,
-  AllocatorStatMmapped,
-  AllocatorStatUnmapped,
+  AllocatorStatAllocated,
+  AllocatorStatMapped,
   AllocatorStatCount
 };
 
-typedef u64 AllocatorStatCounters[AllocatorStatCount];
+typedef uptr AllocatorStatCounters[AllocatorStatCount];
 
 // Per-thread stats, live in per-thread cache.
 class AllocatorStats {
@@ -214,16 +212,21 @@  class AllocatorStats {
     internal_memset(this, 0, sizeof(*this));
   }
 
-  void Add(AllocatorStat i, u64 v) {
+  void Add(AllocatorStat i, uptr v) {
     v += atomic_load(&stats_[i], memory_order_relaxed);
     atomic_store(&stats_[i], v, memory_order_relaxed);
   }
 
-  void Set(AllocatorStat i, u64 v) {
+  void Sub(AllocatorStat i, uptr v) {
+    v = atomic_load(&stats_[i], memory_order_relaxed) - v;
     atomic_store(&stats_[i], v, memory_order_relaxed);
   }
 
-  u64 Get(AllocatorStat i) const {
+  void Set(AllocatorStat i, uptr v) {
+    atomic_store(&stats_[i], v, memory_order_relaxed);
+  }
+
+  uptr Get(AllocatorStat i) const {
     return atomic_load(&stats_[i], memory_order_relaxed);
   }
 
@@ -231,7 +234,7 @@  class AllocatorStats {
   friend class AllocatorGlobalStats;
   AllocatorStats *next_;
   AllocatorStats *prev_;
-  atomic_uint64_t stats_[AllocatorStatCount];
+  atomic_uintptr_t stats_[AllocatorStatCount];
 };
 
 // Global stats, used for aggregation and querying.
@@ -260,7 +263,7 @@  class AllocatorGlobalStats : public Allo
   }
 
   void Get(AllocatorStatCounters s) const {
-    internal_memset(s, 0, AllocatorStatCount * sizeof(u64));
+    internal_memset(s, 0, AllocatorStatCount * sizeof(uptr));
     SpinMutexLock l(&mu_);
     const AllocatorStats *stats = this;
     for (;;) {
@@ -270,6 +273,9 @@  class AllocatorGlobalStats : public Allo
       if (stats == this)
         break;
     }
+    // All stats must be positive.
+    for (int i = 0; i < AllocatorStatCount; i++)
+      s[i] = ((sptr)s[i]) > 0 ? s[i] : 1;
   }
 
  private:
@@ -522,7 +528,7 @@  class SizeClassAllocator64 {
         map_size += kUserMapSize;
       CHECK_GE(region->mapped_user + map_size, end_idx);
       MapWithCallback(region_beg + region->mapped_user, map_size);
-      stat->Add(AllocatorStatMmapped, map_size);
+      stat->Add(AllocatorStatMapped, map_size);
       region->mapped_user += map_size;
     }
     uptr total_count = (region->mapped_user - beg_idx - size)
@@ -841,7 +847,7 @@  class SizeClassAllocator32 {
     uptr res = reinterpret_cast<uptr>(MmapAlignedOrDie(kRegionSize, kRegionSize,
                                       "SizeClassAllocator32"));
     MapUnmapCallback().OnMap(res, kRegionSize);
-    stat->Add(AllocatorStatMmapped, kRegionSize);
+    stat->Add(AllocatorStatMapped, kRegionSize);
     CHECK_EQ(0U, (res & (kRegionSize - 1)));
     possible_regions.set(ComputeRegionId(res), static_cast<u8>(class_id));
     return res;
@@ -907,7 +913,7 @@  struct SizeClassAllocatorLocalCache {
   void *Allocate(SizeClassAllocator *allocator, uptr class_id) {
     CHECK_NE(class_id, 0UL);
     CHECK_LT(class_id, kNumClasses);
-    stats_.Add(AllocatorStatMalloced, SizeClassMap::Size(class_id));
+    stats_.Add(AllocatorStatAllocated, SizeClassMap::Size(class_id));
     PerClass *c = &per_class_[class_id];
     if (UNLIKELY(c->count == 0))
       Refill(allocator, class_id);
@@ -922,7 +928,7 @@  struct SizeClassAllocatorLocalCache {
     // If the first allocator call on a new thread is a deallocation, then
     // max_count will be zero, leading to check failure.
     InitCache();
-    stats_.Add(AllocatorStatFreed, SizeClassMap::Size(class_id));
+    stats_.Sub(AllocatorStatAllocated, SizeClassMap::Size(class_id));
     PerClass *c = &per_class_[class_id];
     CHECK_NE(c->max_count, 0UL);
     if (UNLIKELY(c->count == c->max_count))
@@ -1033,8 +1039,8 @@  class LargeMmapAllocator {
       stats.currently_allocated += map_size;
       stats.max_allocated = Max(stats.max_allocated, stats.currently_allocated);
       stats.by_size_log[size_log]++;
-      stat->Add(AllocatorStatMalloced, map_size);
-      stat->Add(AllocatorStatMmapped, map_size);
+      stat->Add(AllocatorStatAllocated, map_size);
+      stat->Add(AllocatorStatMapped, map_size);
     }
     return reinterpret_cast<void*>(res);
   }
@@ -1052,8 +1058,8 @@  class LargeMmapAllocator {
       chunks_sorted_ = false;
       stats.n_frees++;
       stats.currently_allocated -= h->map_size;
-      stat->Add(AllocatorStatFreed, h->map_size);
-      stat->Add(AllocatorStatUnmapped, h->map_size);
+      stat->Sub(AllocatorStatAllocated, h->map_size);
+      stat->Sub(AllocatorStatMapped, h->map_size);
     }
     MapUnmapCallback().OnUnmap(h->map_beg, h->map_size);
     UnmapOrDie(reinterpret_cast<void*>(h->map_beg), h->map_size);