16a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//===-- tsan_stack_trace.cc -----------------------------------------------===//
26a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//
36a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//                     The LLVM Compiler Infrastructure
46a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//
56a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// This file is distributed under the University of Illinois Open Source
66a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// License. See LICENSE.TXT for details.
76a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//
86a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//===----------------------------------------------------------------------===//
96a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//
106a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// This file is a part of ThreadSanitizer (TSan), a race detector.
116a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//
126a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//===----------------------------------------------------------------------===//
136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "tsan_stack_trace.h"
146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "tsan_rtl.h"
156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "tsan_mman.h"
166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesnamespace __tsan {
186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
196d1862363c88c183b0ed7740fca876342cf0474bStephen HinesVarSizeStackTrace::VarSizeStackTrace()
206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    : StackTrace(nullptr, 0), trace_buffer(nullptr) {}
216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
226d1862363c88c183b0ed7740fca876342cf0474bStephen HinesVarSizeStackTrace::~VarSizeStackTrace() {
236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ResizeBuffer(0);
246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
266d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid VarSizeStackTrace::ResizeBuffer(uptr new_size) {
276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (trace_buffer) {
286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    internal_free(trace_buffer);
296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  }
306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  trace_buffer =
316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      (new_size > 0)
326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines          ? (uptr *)internal_alloc(MBlockStackTrace,
336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines                                   new_size * sizeof(trace_buffer[0]))
346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines          : nullptr;
356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  trace = trace_buffer;
366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  size = new_size;
376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
396d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid VarSizeStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) {
406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ResizeBuffer(cnt + !!extra_top_pc);
416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  internal_memcpy(trace_buffer, pcs, cnt * sizeof(trace_buffer[0]));
426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (extra_top_pc)
436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    trace_buffer[cnt] = extra_top_pc;
446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}  // namespace __tsan
47