Skip to content

Commit 008ab98

Browse files
authored
Merge pull request #6531 from markalle/patcher_additions
shmat/shmdt additions for patcher
2 parents 8961daa + eb88811 commit 008ab98

File tree

1 file changed

+98
-24
lines changed

1 file changed

+98
-24
lines changed

opal/mca/memory/patcher/memory_patcher_component.c

Lines changed: 98 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* reserved.
1616
* Copyright (c) 2016-2017 Research Organization for Information Science
1717
* and Technology (RIST). All rights reserved.
18-
* Copyright (c) 2016 IBM Corporation. All rights reserved.
18+
* Copyright (c) 2016-2019 IBM Corporation. All rights reserved.
1919
*
2020
* $COPYRIGHT$
2121
*
@@ -48,6 +48,9 @@
4848
#if defined(HAVE_LINUX_MMAN_H)
4949
#include <linux/mman.h>
5050
#endif
51+
#if defined(HAVE_SYS_IPC_H)
52+
#include <sys/ipc.h>
53+
#endif
5154

5255
#include "memory_patcher.h"
5356
#undef opal_memory_changed
@@ -104,15 +107,7 @@ opal_memory_patcher_component_t mca_memory_patcher_component = {
104107
* data. If this can be resolved the two levels can be joined.
105108
*/
106109

107-
/*
108-
* The following block of code is #if 0'ed out because we do not need
109-
* to intercept mmap() any more (mmap() only deals with memory
110-
* protection; it does not invalidate any rcache entries for a given
111-
* region). But if we do someday, this is the code that we'll need.
112-
* It's a little non-trivial, so we might as well keep it (and #if 0
113-
* it out).
114-
*/
115-
#if 0
110+
#if defined (SYS_mmap)
116111

117112
#if defined(HAVE___MMAP) && !HAVE_DECL___MMAP
118113
/* prototype for Apple's internal mmap function */
@@ -121,12 +116,11 @@ void *__mmap (void *start, size_t length, int prot, int flags, int fd, off_t off
121116

122117
static void *(*original_mmap)(void *, size_t, int, int, int, off_t);
123118

124-
static void *intercept_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
119+
static void *_intercept_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
125120
{
126-
OPAL_PATCHER_BEGIN;
127121
void *result = 0;
128122

129-
if (prot == PROT_NONE) {
123+
if ((flags & MAP_FIXED) && (start != NULL)) {
130124
opal_mem_hooks_release_hook (start, length, true);
131125
}
132126

@@ -137,19 +131,20 @@ static void *intercept_mmap(void *start, size_t length, int prot, int flags, int
137131
#else
138132
result = (void*)(intptr_t) memory_patcher_syscall(SYS_mmap, start, length, prot, flags, fd, offset);
139133
#endif
140-
141-
// I thought we had some issue in the past with the above line for IA32,
142-
// like maybe syscall() wouldn't handle that many arguments. But just now
143-
// I used gcc -m32 and it worked on a recent system. But there's a possibility
144-
// that older ia32 systems may need some other code to make the above syscall.
145134
} else {
146135
result = original_mmap (start, length, prot, flags, fd, offset);
147136
}
148137

149-
OPAL_PATCHER_END;
150138
return result;
151139
}
152140

141+
static void *intercept_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
142+
{
143+
OPAL_PATCHER_BEGIN;
144+
void *result = _intercept_mmap (start, length, prot, flags, fd, offset);
145+
OPAL_PATCHER_END;
146+
return result;
147+
}
153148
#endif
154149

155150
#if defined (SYS_munmap)
@@ -256,6 +251,9 @@ static int _intercept_madvise (void *start, size_t length, int advice)
256251
int result = 0;
257252

258253
if (advice == MADV_DONTNEED ||
254+
#ifdef MADV_FREE
255+
advice == MADV_FREE ||
256+
#endif
259257
#ifdef MADV_REMOVE
260258
advice == MADV_REMOVE ||
261259
#endif
@@ -341,7 +339,12 @@ static int intercept_brk (void *addr)
341339

342340
#endif
343341

344-
#if defined(SYS_shmdt) && defined(__linux__)
342+
#define HAS_SHMDT (defined(SYS_shmdt) || \
343+
(defined(IPCOP_shmdt) && defined(SYS_ipc)))
344+
#define HAS_SHMAT (defined(SYS_shmat) || \
345+
(defined(IPCOP_shmat) && defined(SYS_ipc)))
346+
347+
#if (HAS_SHMDT || HAS_SHMAT) && defined(__linux__)
345348

346349
#include <stdio.h>
347350
#include <fcntl.h>
@@ -404,6 +407,68 @@ static size_t memory_patcher_get_shm_seg_size (const void *shmaddr)
404407
return seg_size;
405408
}
406409

410+
static size_t get_shm_size(int shmid)
411+
{
412+
struct shmid_ds ds;
413+
int ret;
414+
415+
ret = shmctl(shmid, IPC_STAT, &ds);
416+
if (ret < 0) {
417+
return 0;
418+
}
419+
420+
return ds.shm_segsz;
421+
}
422+
#endif
423+
424+
#if HAS_SHMAT && defined(__linux__)
425+
static void *(*original_shmat)(int shmid, const void *shmaddr, int shmflg);
426+
427+
static void *_intercept_shmat(int shmid, const void *shmaddr, int shmflg)
428+
{
429+
void *result = 0;
430+
431+
size_t size = get_shm_size(shmid);
432+
433+
if ((shmflg & SHM_REMAP) && (shmaddr != NULL)) {
434+
// I don't really know what REMAP combined with SHM_RND does, so I'll just
435+
// guess it remaps all the way down to the lower attach_addr, and all the
436+
// way up to the original shmaddr+size
437+
uintptr_t attach_addr = (uintptr_t)shmaddr;
438+
439+
if (shmflg & SHM_RND) {
440+
attach_addr -= ((uintptr_t)shmaddr) % SHMLBA;
441+
size += ((uintptr_t)shmaddr) % SHMLBA;
442+
}
443+
opal_mem_hooks_release_hook ((void*)attach_addr, size, false);
444+
}
445+
446+
if (!original_shmat) {
447+
#if defined(SYS_shmat)
448+
result = memory_patcher_syscall(SYS_shmat, shmid, shmaddr, shmflg);
449+
#else // IPCOP_shmat
450+
unsigned long ret;
451+
ret = memory_patcher_syscall(SYS_ipc, IPCOP_shmat,
452+
shmid, shmflg, &shmaddr, shmaddr);
453+
result = (ret > -(unsigned long)SHMLBA) ? (void *)ret : (void *)shmaddr;
454+
#endif
455+
} else {
456+
result = original_shmat (shmid, shmaddr, shmflg);
457+
}
458+
459+
return result;
460+
}
461+
462+
static void* intercept_shmat (int shmid, const void * shmaddr, int shmflg)
463+
{
464+
OPAL_PATCHER_BEGIN;
465+
void *result = _intercept_shmat (shmid, shmaddr, shmflg);
466+
OPAL_PATCHER_END;
467+
return result;
468+
}
469+
#endif
470+
471+
#if HAS_SHMDT && defined(__linux__)
407472
static int (*original_shmdt) (const void *);
408473

409474
static int _intercept_shmdt (const void *shmaddr)
@@ -417,7 +482,11 @@ static int _intercept_shmdt (const void *shmaddr)
417482
if (original_shmdt) {
418483
result = original_shmdt (shmaddr);
419484
} else {
485+
#if defined(SYS_shmdt)
420486
result = memory_patcher_syscall (SYS_shmdt, shmaddr);
487+
#else // IPCOP_shmdt
488+
result = memory_patcher_syscall(SYS_ipc, IPCOP_shmdt, 0, 0, 0, shmaddr);
489+
#endif
421490
}
422491

423492
return result;
@@ -478,9 +547,7 @@ static int patcher_open (void)
478547
/* set memory hooks support level */
479548
opal_mem_hooks_set_support (OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_MUNMAP_SUPPORT);
480549

481-
#if 0
482-
/* See above block to see why mmap() functionality is #if 0'ed
483-
out */
550+
#if defined (SYS_mmap)
484551
rc = opal_patcher->patch_symbol ("mmap", (uintptr_t) intercept_mmap, (uintptr_t *) &original_mmap);
485552
if (OPAL_SUCCESS != rc) {
486553
return rc;
@@ -508,7 +575,14 @@ static int patcher_open (void)
508575
}
509576
#endif
510577

511-
#if defined(SYS_shmdt) && defined(__linux__)
578+
#if HAS_SHMAT && defined(__linux__)
579+
rc = opal_patcher->patch_symbol ("shmat", (uintptr_t) intercept_shmat, (uintptr_t *) &original_shmat);
580+
if (OPAL_SUCCESS != rc) {
581+
return rc;
582+
}
583+
#endif
584+
585+
#if HAS_SHMDT && defined(__linux__)
512586
rc = opal_patcher->patch_symbol ("shmdt", (uintptr_t) intercept_shmdt, (uintptr_t *) &original_shmdt);
513587
if (OPAL_SUCCESS != rc) {
514588
return rc;

0 commit comments

Comments
 (0)