15
15
* reserved.
16
16
* Copyright (c) 2016-2017 Research Organization for Information Science
17
17
* 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.
19
19
*
20
20
* $COPYRIGHT$
21
21
*
48
48
#if defined(HAVE_LINUX_MMAN_H )
49
49
#include <linux/mman.h>
50
50
#endif
51
+ #if defined(HAVE_SYS_IPC_H )
52
+ #include <sys/ipc.h>
53
+ #endif
51
54
52
55
#include "memory_patcher.h"
53
56
#undef opal_memory_changed
@@ -104,15 +107,7 @@ opal_memory_patcher_component_t mca_memory_patcher_component = {
104
107
* data. If this can be resolved the two levels can be joined.
105
108
*/
106
109
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 )
116
111
117
112
#if defined(HAVE___MMAP ) && !HAVE_DECL___MMAP
118
113
/* 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
121
116
122
117
static void * (* original_mmap )(void * , size_t , int , int , int , off_t );
123
118
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 )
125
120
{
126
- OPAL_PATCHER_BEGIN ;
127
121
void * result = 0 ;
128
122
129
- if (prot == PROT_NONE ) {
123
+ if (( flags & MAP_FIXED ) && ( start != NULL ) ) {
130
124
opal_mem_hooks_release_hook (start , length , true);
131
125
}
132
126
@@ -137,19 +131,20 @@ static void *intercept_mmap(void *start, size_t length, int prot, int flags, int
137
131
#else
138
132
result = (void * )(intptr_t ) memory_patcher_syscall (SYS_mmap , start , length , prot , flags , fd , offset );
139
133
#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.
145
134
} else {
146
135
result = original_mmap (start , length , prot , flags , fd , offset );
147
136
}
148
137
149
- OPAL_PATCHER_END ;
150
138
return result ;
151
139
}
152
140
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
+ }
153
148
#endif
154
149
155
150
#if defined (SYS_munmap )
@@ -256,6 +251,9 @@ static int _intercept_madvise (void *start, size_t length, int advice)
256
251
int result = 0 ;
257
252
258
253
if (advice == MADV_DONTNEED ||
254
+ #ifdef MADV_FREE
255
+ advice == MADV_FREE ||
256
+ #endif
259
257
#ifdef MADV_REMOVE
260
258
advice == MADV_REMOVE ||
261
259
#endif
@@ -341,7 +339,12 @@ static int intercept_brk (void *addr)
341
339
342
340
#endif
343
341
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__ )
345
348
346
349
#include <stdio.h>
347
350
#include <fcntl.h>
@@ -404,6 +407,68 @@ static size_t memory_patcher_get_shm_seg_size (const void *shmaddr)
404
407
return seg_size ;
405
408
}
406
409
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__ )
407
472
static int (* original_shmdt ) (const void * );
408
473
409
474
static int _intercept_shmdt (const void * shmaddr )
@@ -417,7 +482,11 @@ static int _intercept_shmdt (const void *shmaddr)
417
482
if (original_shmdt ) {
418
483
result = original_shmdt (shmaddr );
419
484
} else {
485
+ #if defined(SYS_shmdt )
420
486
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
421
490
}
422
491
423
492
return result ;
@@ -478,9 +547,7 @@ static int patcher_open (void)
478
547
/* set memory hooks support level */
479
548
opal_mem_hooks_set_support (OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_MUNMAP_SUPPORT );
480
549
481
- #if 0
482
- /* See above block to see why mmap() functionality is #if 0'ed
483
- out */
550
+ #if defined (SYS_mmap )
484
551
rc = opal_patcher -> patch_symbol ("mmap" , (uintptr_t ) intercept_mmap , (uintptr_t * ) & original_mmap );
485
552
if (OPAL_SUCCESS != rc ) {
486
553
return rc ;
@@ -508,7 +575,14 @@ static int patcher_open (void)
508
575
}
509
576
#endif
510
577
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__ )
512
586
rc = opal_patcher -> patch_symbol ("shmdt" , (uintptr_t ) intercept_shmdt , (uintptr_t * ) & original_shmdt );
513
587
if (OPAL_SUCCESS != rc ) {
514
588
return rc ;
0 commit comments