+// ***** Helper stuff
+
+#define SO_RE "\\.so[\\.0-9]*$"
+#define VERSION_RE "-[\\.0-9-]*$"
+
+static const char *const FILTERED_LIBS[] = {
+ "ld",
+ "libbz2",
+ "libboost_chrono",
+ "libboost_context",
+ "libboost_system",
+ "libboost_thread",
+ "libc",
+ "libc++",
+ "libcdt",
+ "libcgraph",
+ "libdl",
+ "libdw",
+ "libelf",
+ "libgcc_s",
+ "liblua5.1",
+ "liblzma",
+ "libm",
+ "libpthread",
+ "librt",
+ "libsigc",
+ "libstdc++",
+ "libunwind",
+ "libunwind-x86_64",
+ "libunwind-x86",
+ "libunwind-ptrace",
+ "libz"
+};
+
+static bool MC_is_simgrid_lib(const char* libname)
+{
+ return !strcmp(libname, "libsimgrid");
+}
+
+static bool MC_is_filtered_lib(const char* libname)
+{
+ for (const char* filtered_lib : FILTERED_LIBS)
+ if (strcmp(libname, filtered_lib)==0)
+ return true;
+ return false;
+}
+
+struct s_mc_memory_map_re {
+ regex_t so_re;
+ regex_t version_re;
+};
+
+static char* MC_get_lib_name(const char* pathname, struct s_mc_memory_map_re* res)
+{
+ const char* map_basename = basename((char*) pathname);
+
+ regmatch_t match;
+ if(regexec(&res->so_re, map_basename, 1, &match, 0))
+ return NULL;
+
+ char* libname = strndup(map_basename, match.rm_so);
+
+ // Strip the version suffix:
+ if(libname && !regexec(&res->version_re, libname, 1, &match, 0)) {
+ char* temp = libname;
+ libname = strndup(temp, match.rm_so);
+ free(temp);
+ }
+
+ return libname;
+}
+
+static ssize_t pread_whole(int fd, void *buf, size_t count, std::uint64_t offset)
+{
+ char* buffer = (char*) buf;
+ ssize_t real_count = count;
+ while (count) {
+ ssize_t res = pread(fd, buffer, count, (std::int64_t) offset);
+ if (res > 0) {
+ count -= res;
+ buffer += res;
+ offset += res;
+ } else if (res==0) {
+ return -1;
+ } else if (errno != EINTR) {
+ return -1;
+ }
+ }
+ return real_count;
+}
+
+static ssize_t pwrite_whole(int fd, const void *buf, size_t count, off_t offset)
+{
+ const char* buffer = (const char*) buf;
+ ssize_t real_count = count;
+ while (count) {
+ ssize_t res = pwrite(fd, buffer, count, offset);
+ if (res > 0) {
+ count -= res;
+ buffer += res;
+ offset += res;
+ } else if (res==0) {
+ return -1;
+ } else if (errno != EINTR) {
+ return -1;
+ }
+ }
+ return real_count;
+}
+
+static pthread_once_t zero_buffer_flag = PTHREAD_ONCE_INIT;
+static const void* zero_buffer;
+static const size_t zero_buffer_size = 10 * 4096;
+
+static void MC_zero_buffer_init(void)
+{
+ int fd = open("/dev/zero", O_RDONLY);
+ if (fd<0)
+ xbt_die("Could not open /dev/zero");
+ zero_buffer = mmap(NULL, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (zero_buffer == MAP_FAILED)
+ xbt_die("Could not map the zero buffer");
+ close(fd);
+}