17d62b00eSchristos /* RAII type to create a temporary mock context. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 2020-2023 Free Software Foundation, Inc. 47d62b00eSchristos 57d62b00eSchristos This file is part of GDB. 67d62b00eSchristos 77d62b00eSchristos This program is free software; you can redistribute it and/or modify 87d62b00eSchristos it under the terms of the GNU General Public License as published by 97d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 107d62b00eSchristos (at your option) any later version. 117d62b00eSchristos 127d62b00eSchristos This program is distributed in the hope that it will be useful, 137d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157d62b00eSchristos GNU General Public License for more details. 167d62b00eSchristos 177d62b00eSchristos You should have received a copy of the GNU General Public License 187d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #ifndef SCOPED_MOCK_CONTEXT_H 217d62b00eSchristos #define SCOPED_MOCK_CONTEXT_H 227d62b00eSchristos 237d62b00eSchristos #include "inferior.h" 247d62b00eSchristos #include "gdbthread.h" 257d62b00eSchristos #include "progspace.h" 267d62b00eSchristos #include "progspace-and-thread.h" 277d62b00eSchristos 287d62b00eSchristos #if GDB_SELF_TEST 297d62b00eSchristos namespace selftests { 307d62b00eSchristos 317d62b00eSchristos /* RAII type to create (and switch to) a temporary mock context. An 327d62b00eSchristos inferior with a thread, with a process_stratum target pushed. */ 337d62b00eSchristos 347d62b00eSchristos template<typename Target> 357d62b00eSchristos struct scoped_mock_context 367d62b00eSchristos { 377d62b00eSchristos /* Order here is important. */ 387d62b00eSchristos 397d62b00eSchristos Target mock_target; 407d62b00eSchristos ptid_t mock_ptid {1, 1}; 41*6881a400Schristos program_space mock_pspace {new address_space ()}; 427d62b00eSchristos inferior mock_inferior {mock_ptid.pid ()}; 437d62b00eSchristos thread_info mock_thread {&mock_inferior, mock_ptid}; 447d62b00eSchristos 457d62b00eSchristos scoped_restore_current_pspace_and_thread restore_pspace_thread; 467d62b00eSchristos 477d62b00eSchristos explicit scoped_mock_context (gdbarch *gdbarch) 487d62b00eSchristos { 49*6881a400Schristos /* Add the mock inferior to the inferior list so that look ups by 50*6881a400Schristos target+ptid can find it. */ 51*6881a400Schristos inferior_list.push_back (mock_inferior); 52*6881a400Schristos 53*6881a400Schristos mock_inferior.thread_list.push_back (mock_thread); 54*6881a400Schristos mock_inferior.ptid_thread_map[mock_ptid] = &mock_thread; 557d62b00eSchristos mock_inferior.gdbarch = gdbarch; 567d62b00eSchristos mock_inferior.aspace = mock_pspace.aspace; 577d62b00eSchristos mock_inferior.pspace = &mock_pspace; 587d62b00eSchristos 597d62b00eSchristos /* Switch to the mock inferior. */ 607d62b00eSchristos switch_to_inferior_no_thread (&mock_inferior); 617d62b00eSchristos 627d62b00eSchristos /* Push the process_stratum target so we can mock accessing 637d62b00eSchristos registers. */ 647d62b00eSchristos gdb_assert (mock_target.stratum () == process_stratum); 65*6881a400Schristos mock_inferior.push_target (&mock_target); 667d62b00eSchristos 677d62b00eSchristos /* Switch to the mock thread. */ 687d62b00eSchristos switch_to_thread (&mock_thread); 697d62b00eSchristos } 707d62b00eSchristos 717d62b00eSchristos ~scoped_mock_context () 727d62b00eSchristos { 73*6881a400Schristos inferior_list.erase (inferior_list.iterator_to (mock_inferior)); 74*6881a400Schristos mock_inferior.pop_all_targets_at_and_above (process_stratum); 757d62b00eSchristos } 767d62b00eSchristos }; 777d62b00eSchristos 787d62b00eSchristos } // namespace selftests 797d62b00eSchristos #endif /* GDB_SELF_TEST */ 807d62b00eSchristos 817d62b00eSchristos #endif /* !defined (SCOPED_MOCK_CONTEXT_H) */ 82