Skip to content

Commit 13e37d4

Browse files
committedOct 25, 2017
Move StopInfoOverride callback to the new architecture plugin
This creates a new Architecture plugin and moves the stop info override callback to this place. The motivation for this is to remove complex dependencies from the ArchSpec class because it is used in a lot of places that (should) know nothing about Process instances and StopInfo objects. I also add a test for the functionality covered by the override callback. Differential Revision: https://reviews.llvm.org/D31172 llvm-svn: 316609
1 parent c2400fc commit 13e37d4

File tree

19 files changed

+428
-203
lines changed

19 files changed

+428
-203
lines changed
 

‎lldb/include/lldb/Core/ArchSpec.h

+2-39
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "lldb/Utility/ConstString.h"
1616
#include "lldb/lldb-enumerations.h"
1717
#include "lldb/lldb-private-enumerations.h"
18+
#include "lldb/lldb-forward.h"
1819
#include "llvm/ADT/StringRef.h" // for StringRef
1920
#include "llvm/ADT/Triple.h"
2021

@@ -23,19 +24,6 @@
2324
#include <stddef.h> // for size_t
2425
#include <stdint.h> // for uint32_t
2526

26-
namespace lldb_private {
27-
class Platform;
28-
}
29-
namespace lldb_private {
30-
class Stream;
31-
}
32-
namespace lldb_private {
33-
class StringList;
34-
}
35-
namespace lldb_private {
36-
class Thread;
37-
}
38-
3927
namespace lldb_private {
4028

4129
//----------------------------------------------------------------------
@@ -258,8 +246,6 @@ class ArchSpec {
258246

259247
};
260248

261-
typedef void (*StopInfoOverrideCallbackType)(lldb_private::Thread &thread);
262-
263249
//------------------------------------------------------------------
264250
/// Default constructor.
265251
///
@@ -574,34 +560,11 @@ class ArchSpec {
574560
//------------------------------------------------------------------
575561
bool IsCompatibleMatch(const ArchSpec &rhs) const;
576562

577-
//------------------------------------------------------------------
578-
/// Get a stop info override callback for the current architecture.
579-
///
580-
/// Most platform specific code should go in lldb_private::Platform,
581-
/// but there are cases where no matter which platform you are on
582-
/// certain things hold true.
583-
///
584-
/// This callback is currently intended to handle cases where a
585-
/// program stops at an instruction that won't get executed and it
586-
/// allows the stop reasonm, like "breakpoint hit", to be replaced
587-
/// with a different stop reason like "no stop reason".
588-
///
589-
/// This is specifically used for ARM in Thumb code when we stop in
590-
/// an IT instruction (if/then/else) where the instruction won't get
591-
/// executed and therefore it wouldn't be correct to show the program
592-
/// stopped at the current PC. The code is generic and applies to all
593-
/// ARM CPUs.
594-
///
595-
/// @return NULL or a valid stop info override callback for the
596-
/// current architecture.
597-
//------------------------------------------------------------------
598-
StopInfoOverrideCallbackType GetStopInfoOverrideCallback() const;
599-
600563
bool IsFullySpecifiedTriple() const;
601564

602565
void PiecewiseTripleCompare(const ArchSpec &other, bool &arch_different,
603566
bool &vendor_different, bool &os_different,
604-
bool &os_version_different, bool &env_different);
567+
bool &os_version_different, bool &env_different) const;
605568

606569
//------------------------------------------------------------------
607570
/// Detect whether this architecture uses thumb code exclusively

‎lldb/include/lldb/Core/Architecture.h

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===-- Architecture.h ------------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLDB_CORE_ARCHITECTURE_H
11+
#define LLDB_CORE_ARCHITECTURE_H
12+
13+
#include "lldb/Core/PluginInterface.h"
14+
15+
namespace lldb_private {
16+
17+
class Architecture : public PluginInterface {
18+
public:
19+
Architecture() = default;
20+
virtual ~Architecture() = default;
21+
22+
//------------------------------------------------------------------
23+
/// This is currently intended to handle cases where a
24+
/// program stops at an instruction that won't get executed and it
25+
/// allows the stop reasonm, like "breakpoint hit", to be replaced
26+
/// with a different stop reason like "no stop reason".
27+
///
28+
/// This is specifically used for ARM in Thumb code when we stop in
29+
/// an IT instruction (if/then/else) where the instruction won't get
30+
/// executed and therefore it wouldn't be correct to show the program
31+
/// stopped at the current PC. The code is generic and applies to all
32+
/// ARM CPUs.
33+
//------------------------------------------------------------------
34+
virtual void OverrideStopInfo(Thread &thread) = 0;
35+
36+
private:
37+
Architecture(const Architecture &) = delete;
38+
void operator=(const Architecture &) = delete;
39+
};
40+
41+
} // namespace lldb_private
42+
43+
#endif // LLDB_CORE_ARCHITECTURE_H

‎lldb/include/lldb/Core/PluginManager.h

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef liblldb_PluginManager_h_
1111
#define liblldb_PluginManager_h_
1212

13+
#include "lldb/Core/Architecture.h"
1314
#include "lldb/Utility/FileSpec.h"
1415
#include "lldb/Utility/Status.h" // for Status
1516
#include "lldb/lldb-enumerations.h" // for ScriptLanguage
@@ -53,6 +54,21 @@ class PluginManager {
5354
static ABICreateInstance
5455
GetABICreateCallbackForPluginName(const ConstString &name);
5556

57+
//------------------------------------------------------------------
58+
// Architecture
59+
//------------------------------------------------------------------
60+
using ArchitectureCreateInstance =
61+
std::unique_ptr<Architecture> (*)(const ArchSpec &);
62+
63+
static void RegisterPlugin(const ConstString &name,
64+
llvm::StringRef description,
65+
ArchitectureCreateInstance create_callback);
66+
67+
static void UnregisterPlugin(ArchitectureCreateInstance create_callback);
68+
69+
static std::unique_ptr<Architecture>
70+
CreateArchitectureInstance(const ArchSpec &arch);
71+
5672
//------------------------------------------------------------------
5773
// Disassembler
5874
//------------------------------------------------------------------

‎lldb/include/lldb/Target/Process.h

-5
Original file line numberDiff line numberDiff line change
@@ -2514,10 +2514,6 @@ class Process : public std::enable_shared_from_this<Process>,
25142514

25152515
OperatingSystem *GetOperatingSystem() { return m_os_ap.get(); }
25162516

2517-
ArchSpec::StopInfoOverrideCallbackType GetStopInfoOverrideCallback() const {
2518-
return m_stop_info_override_callback;
2519-
}
2520-
25212517
virtual LanguageRuntime *GetLanguageRuntime(lldb::LanguageType language,
25222518
bool retry_if_null = true);
25232519

@@ -3106,7 +3102,6 @@ class Process : public std::enable_shared_from_this<Process>,
31063102
std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
31073103
ProcessRunLock m_public_run_lock;
31083104
ProcessRunLock m_private_run_lock;
3109-
ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback;
31103105
bool m_currently_handling_do_on_removals;
31113106
bool m_resume_requested; // If m_currently_handling_event or
31123107
// m_currently_handling_do_on_removals are true,

‎lldb/include/lldb/Target/Target.h

+17-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "lldb/Breakpoint/BreakpointName.h"
2525
#include "lldb/Breakpoint/WatchpointList.h"
2626
#include "lldb/Core/ArchSpec.h"
27+
#include "lldb/Core/Architecture.h"
2728
#include "lldb/Core/Broadcaster.h"
2829
#include "lldb/Core/Disassembler.h"
2930
#include "lldb/Core/ModuleList.h"
@@ -917,7 +918,7 @@ class Target : public std::enable_shared_from_this<Target>,
917918
bool
918919
ModuleIsExcludedForUnconstrainedSearches(const lldb::ModuleSP &module_sp);
919920

920-
const ArchSpec &GetArchitecture() const { return m_arch; }
921+
const ArchSpec &GetArchitecture() const { return m_arch.GetSpec(); }
921922

922923
//------------------------------------------------------------------
923924
/// Set the architecture for this target.
@@ -948,6 +949,8 @@ class Target : public std::enable_shared_from_this<Target>,
948949

949950
bool MergeArchitecture(const ArchSpec &arch_spec);
950951

952+
Architecture *GetArchitecturePlugin() { return m_arch.GetPlugin(); }
953+
951954
Debugger &GetDebugger() { return m_debugger; }
952955

953956
size_t ReadMemoryFromFileCache(const Address &addr, void *dst, size_t dst_len,
@@ -1241,14 +1244,26 @@ class Target : public std::enable_shared_from_this<Target>,
12411244
const lldb::ModuleSP &new_module_sp) override;
12421245
void WillClearList(const ModuleList &module_list) override;
12431246

1247+
class Arch {
1248+
public:
1249+
explicit Arch(const ArchSpec &spec);
1250+
const Arch &operator=(const ArchSpec &spec);
1251+
1252+
const ArchSpec &GetSpec() const { return m_spec; }
1253+
Architecture *GetPlugin() const { return m_plugin_up.get(); }
1254+
1255+
private:
1256+
ArchSpec m_spec;
1257+
std::unique_ptr<Architecture> m_plugin_up;
1258+
};
12441259
//------------------------------------------------------------------
12451260
// Member variables.
12461261
//------------------------------------------------------------------
12471262
Debugger &m_debugger;
12481263
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
12491264
std::recursive_mutex m_mutex; ///< An API mutex that is used by the lldb::SB*
12501265
/// classes make the SB interface thread safe
1251-
ArchSpec m_arch;
1266+
Arch m_arch;
12521267
ModuleList m_images; ///< The list of images for this process (shared
12531268
/// libraries and anything dynamically loaded).
12541269
SectionLoadHistory m_section_load_history;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
LEVEL = ../../make
2+
3+
C_SOURCES := main.c
4+
CFLAGS_EXTRAS = -mthumb
5+
6+
include $(LEVEL)/Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
Test that breakpoints in an IT instruction don't fire if their condition is
3+
false.
4+
"""
5+
from __future__ import print_function
6+
7+
8+
import lldb
9+
import os
10+
import time
11+
from lldbsuite.test.decorators import *
12+
from lldbsuite.test.lldbtest import *
13+
from lldbsuite.test import lldbutil
14+
15+
16+
class TestBreakpointIt(TestBase):
17+
18+
mydir = TestBase.compute_mydir(__file__)
19+
NO_DEBUG_INFO_TESTCASE = True
20+
21+
@skipIf(archs=no_match(["arm"]))
22+
def test_false(self):
23+
self.build()
24+
exe = os.path.join(os.getcwd(), "a.out")
25+
26+
self.runCmd("target create %s" % exe)
27+
lldbutil.run_break_set_by_symbol(self, "bkpt_false",
28+
extra_options="--skip-prologue 0")
29+
30+
self.runCmd("run")
31+
self.assertEqual(self.process().GetState(), lldb.eStateExited,
32+
"Breakpoint does not get hit")
33+
34+
@skipIf(archs=no_match(["arm"]))
35+
def test_true(self):
36+
self.build()
37+
exe = os.path.join(os.getcwd(), "a.out")
38+
39+
self.runCmd("target create %s" % exe)
40+
bpid = lldbutil.run_break_set_by_symbol(self, "bkpt_true",
41+
extra_options="--skip-prologue 0")
42+
43+
self.runCmd("run")
44+
self.assertIsNotNone(lldbutil.get_one_thread_stopped_at_breakpoint_id(
45+
self.process(), bpid))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
int main() {
2+
int value;
3+
asm (
4+
"cmp %1, %2\n\t"
5+
"ite ne\n\t"
6+
".thumb_func\n\t"
7+
"bkpt_true:\n\t"
8+
"movne %0, %1\n\t"
9+
".thumb_func\n\t"
10+
"bkpt_false:\n\t"
11+
"moveq %0, %2\n\t"
12+
: "=r" (value) : "r"(42), "r"(47));
13+
return value;
14+
}

‎lldb/source/API/SystemInitializerFull.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
4343
#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
4444
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
45+
#include "Plugins/Architecture/Arm/ArchitectureArm.h"
4546
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
4647
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h"
4748
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
@@ -50,9 +51,9 @@
5051
#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
5152
#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
5253
#include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h"
54+
#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
5355
#include "Plugins/InstrumentationRuntime/TSan/TSanRuntime.h"
5456
#include "Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h"
55-
#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
5657
#include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
5758
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
5859
#include "Plugins/Language/Go/GoLanguage.h"
@@ -304,6 +305,9 @@ void SystemInitializerFull::Initialize() {
304305
ABISysV_mips::Initialize();
305306
ABISysV_mips64::Initialize();
306307
ABISysV_s390x::Initialize();
308+
309+
ArchitectureArm::Initialize();
310+
307311
DisassemblerLLVMC::Initialize();
308312

309313
JITLoaderGDB::Initialize();

0 commit comments

Comments
 (0)
Please sign in to comment.