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 * 
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
122117static  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__ )
407472static  int  (* original_shmdt ) (const  void  * );
408473
409474static  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