1 //===-- Architecture.h ------------------------------------------*- C++ -*-===//
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 #ifndef LLDB_CORE_ARCHITECTURE_H
10 #define LLDB_CORE_ARCHITECTURE_H
11 
12 #include "lldb/Core/PluginInterface.h"
13 #include "lldb/Target/MemoryTagManager.h"
14 
15 namespace lldb_private {
16 
17 class Architecture : public PluginInterface {
18 public:
19   /// This is currently intended to handle cases where a
20   /// program stops at an instruction that won't get executed and it
21   /// allows the stop reason, like "breakpoint hit", to be replaced
22   /// with a different stop reason like "no stop reason".
23   ///
24   /// This is specifically used for ARM in Thumb code when we stop in
25   /// an IT instruction (if/then/else) where the instruction won't get
26   /// executed and therefore it wouldn't be correct to show the program
27   /// stopped at the current PC. The code is generic and applies to all
28   /// ARM CPUs.
29   virtual void OverrideStopInfo(Thread &thread) const = 0;
30 
31   /// This method is used to get the number of bytes that should be
32   /// skipped, from function start address, to reach the first
33   /// instruction after the prologue. If overrode, it must return
34   /// non-zero only if the current address matches one of the known
35   /// function entry points.
36   ///
37   /// This method is called only if the standard platform-independent
38   /// code fails to get the number of bytes to skip, giving the plugin
39   /// a chance to try to find the missing info.
40   ///
41   /// This is specifically used for PPC64, where functions may have
42   /// more than one entry point, global and local, so both should
43   /// be compared with current address, in order to find out the
44   /// number of bytes that should be skipped, in case we are stopped
45   /// at either function entry point.
46   virtual size_t GetBytesToSkip(Symbol &func, const Address &curr_addr) const {
47     return 0;
48   }
49 
50   /// Adjust function breakpoint address, if needed. In some cases,
51   /// the function start address is not the right place to set the
52   /// breakpoint, specially in functions with multiple entry points.
53   ///
54   /// This is specifically used for PPC64, for functions that have
55   /// both a global and a local entry point. In this case, the
56   /// breakpoint is adjusted to the first function address reached
57   /// by both entry points.
58   virtual void AdjustBreakpointAddress(const Symbol &func,
59                                        Address &addr) const {}
60 
61 
62   /// Get \a load_addr as a callable code load address for this target
63   ///
64   /// Take \a load_addr and potentially add any address bits that are
65   /// needed to make the address callable. For ARM this can set bit
66   /// zero (if it already isn't) if \a load_addr is a thumb function.
67   /// If \a addr_class is set to AddressClass::eInvalid, then the address
68   /// adjustment will always happen. If it is set to an address class
69   /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
70   /// returned.
71   virtual lldb::addr_t GetCallableLoadAddress(
72       lldb::addr_t addr, AddressClass addr_class = AddressClass::eInvalid) const {
73     return addr;
74   }
75 
76   /// Get \a load_addr as an opcode for this target.
77   ///
78   /// Take \a load_addr and potentially strip any address bits that are
79   /// needed to make the address point to an opcode. For ARM this can
80   /// clear bit zero (if it already isn't) if \a load_addr is a
81   /// thumb function and load_addr is in code.
82   /// If \a addr_class is set to AddressClass::eInvalid, then the address
83   /// adjustment will always happen. If it is set to an address class
84   /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
85   /// returned.
86 
87   virtual lldb::addr_t GetOpcodeLoadAddress(
88       lldb::addr_t addr, AddressClass addr_class = AddressClass::eInvalid) const {
89     return addr;
90   }
91 
92   // Get load_addr as breakable load address for this target. Take a addr and
93   // check if for any reason there is a better address than this to put a
94   // breakpoint on. If there is then return that address. For MIPS, if
95   // instruction at addr is a delay slot instruction then this method will find
96   // the address of its previous instruction and return that address.
97   virtual lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr,
98                                                Target &target) const {
99     return addr;
100   }
101 
102   // Returns a pointer to an object that can manage memory tags for this
103   // Architecture E.g. masking out tags, unpacking tag streams etc. Returns
104   // nullptr if the architecture does not have a memory tagging extension.
105   //
106   // The return pointer being valid does not mean that the current process has
107   // memory tagging enabled, just that a tagging technology exists for this
108   // architecture.
109   virtual const MemoryTagManager *GetMemoryTagManager() const {
110     return nullptr;
111   }
112 };
113 
114 } // namespace lldb_private
115 
116 #endif // LLDB_CORE_ARCHITECTURE_H
117