blob: 4711cf6589cc2cec9fe4e4c9565cea8ce54a34ef [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <pthread.h>
#include "base/profiler/thread_delegate_android.h"
#include "build/build_config.h"
// IMPORTANT NOTE: Some functions within this implementation are invoked while
// the target thread is suspended so it must not do any allocation from the
// heap, including indirectly via use of DCHECK/CHECK or other logging
// statements. Otherwise this code can deadlock on heap locks acquired by the
// target thread before it was suspended. These functions are commented with "NO
// HEAP ALLOCATIONS".
namespace base {
namespace {
uintptr_t GetThreadStackBaseAddress(PlatformThreadId thread_id) {
pthread_attr_t attr;
pthread_getattr_np(thread_id, &attr);
void* base_address;
size_t size;
pthread_attr_getstack(&attr, &base_address, &size);
return reinterpret_cast<uintptr_t>(base_address);
}
} // namespace
ThreadDelegateAndroid::ThreadDelegateAndroid(PlatformThreadId thread_id)
: thread_stack_base_address_(GetThreadStackBaseAddress(thread_id)) {}
uintptr_t ThreadDelegateAndroid::GetStackBaseAddress() const {
return thread_stack_base_address_;
}
std::vector<uintptr_t*> ThreadDelegateAndroid::GetRegistersToRewrite(
RegisterContext* thread_context) {
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
return {
reinterpret_cast<uintptr_t*>(&thread_context->arm_r0),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r1),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r2),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r3),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r4),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r5),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r6),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r7),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r8),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r9),
reinterpret_cast<uintptr_t*>(&thread_context->arm_r10),
reinterpret_cast<uintptr_t*>(&thread_context->arm_fp),
reinterpret_cast<uintptr_t*>(&thread_context->arm_ip),
reinterpret_cast<uintptr_t*>(&thread_context->arm_sp),
// arm_lr and arm_pc do not require rewriting because they contain
// addresses of executable code, not addresses in the stack.
};
#else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
return {};
#endif
}
} // namespace base