1 /* Copyright (c) 2015. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 #ifndef SIMGRID_MC_UNW_H
8 #define SIMGRID_MC_UNW_H
11 * Libunwind implementation for the model-checker
13 * Libunwind provides an pluggable stack unwinding API: the way the current
14 * registers and memory is accessed, the way unwinding informations is found
17 * This component implements the libunwind API for he model-checker:
19 * * reading memory from a simgrid::mc::AddressSpace*;
21 * * reading stack registers from a saved snapshot (context).
23 * Parts of the libunwind information fetching is currently handled by the
24 * standard `libunwind` implementations (either the local one or the ptrace one)
25 * because parsing `.eh_frame` section is not fun and `libdw` does not help
29 #include <sys/types.h>
33 #include <libunwind.h>
35 #include "src/mc/mc_forward.hpp"
40 XBT_PRIVATE unw_addr_space_t create_addr_space();
41 XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid);
50 simgrid::mc::AddressSpace* addressSpace_ = nullptr;
51 simgrid::mc::Process* process_ = nullptr;
52 unw_context_t unwindContext_;
55 ~UnwindContext() { clear(); }
56 void initialize(simgrid::mc::Process* process, unw_context_t* c);
58 unw_cursor_t cursor();
60 private: // Methods and virtual table for libunwind
61 static int find_proc_info(unw_addr_space_t as,
62 unw_word_t ip, unw_proc_info_t *pip,
63 int need_unwind_info, void* arg) noexcept;
64 static void put_unwind_info(unw_addr_space_t as,
65 unw_proc_info_t *pip, void* arg) noexcept;
66 static int get_dyn_info_list_addr(unw_addr_space_t as,
67 unw_word_t *dilap, void* arg) noexcept;
68 static int access_mem(unw_addr_space_t as,
69 unw_word_t addr, unw_word_t *valp,
70 int write, void* arg) noexcept;
71 static void* get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept;
72 static int access_reg(unw_addr_space_t as,
73 unw_regnum_t regnum, unw_word_t *valp,
74 int write, void* arg) noexcept;
75 static int access_fpreg(unw_addr_space_t as,
76 unw_regnum_t regnum, unw_fpreg_t *fpvalp,
77 int write, void* arg) noexcept;
78 static int resume(unw_addr_space_t as,
79 unw_cursor_t *cp, void* arg) noexcept;
80 static int get_proc_name(unw_addr_space_t as,
81 unw_word_t addr, char *bufp,
82 size_t buf_len, unw_word_t *offp,
84 static unw_accessors_t accessors;
86 // Create a libunwind address space:
87 static unw_addr_space_t createUnwindAddressSpace();