1 //===-- DecodedThread.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DecodedThread.h"
10 
11 #include "lldb/Utility/StreamString.h"
12 
13 using namespace lldb_private;
14 using namespace lldb_private::trace_intel_pt;
15 using namespace llvm;
16 
17 char IntelPTError::ID;
18 
19 IntelPTError::IntelPTError(int libipt_error_code, lldb::addr_t address)
20     : m_libipt_error_code(libipt_error_code), m_address(address) {
21   assert(libipt_error_code < 0);
22 }
23 
24 void IntelPTError::log(llvm::raw_ostream &OS) const {
25   const char *libipt_error_message = pt_errstr(pt_errcode(m_libipt_error_code));
26   if (m_address != LLDB_INVALID_ADDRESS && m_address > 0) {
27     write_hex(OS, m_address, HexPrintStyle::PrefixLower, 18);
28     OS << "    ";
29   }
30   OS << "error: " << libipt_error_message;
31 }
32 
33 bool IntelPTInstruction::IsError() const { return (bool)m_error; }
34 
35 Expected<lldb::addr_t> IntelPTInstruction::GetLoadAddress() const {
36   if (IsError())
37     return ToError();
38   return m_pt_insn.ip;
39 }
40 
41 Error IntelPTInstruction::ToError() const {
42   if (!IsError())
43     return Error::success();
44 
45   if (m_error->isA<IntelPTError>())
46     return make_error<IntelPTError>(static_cast<IntelPTError &>(*m_error));
47   return make_error<StringError>(m_error->message(),
48                                  m_error->convertToErrorCode());
49 }
50 
51 size_t DecodedThread::GetLastPosition() const {
52   return m_instructions.empty() ? 0 : m_instructions.size() - 1;
53 }
54 
55 ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const {
56   return makeArrayRef(m_instructions);
57 }
58 
59 size_t DecodedThread::GetCursorPosition() const { return m_position; }
60 
61 size_t DecodedThread::SetCursorPosition(size_t new_position) {
62   m_position = std::min(new_position, GetLastPosition());
63   return m_position;
64 }
65