]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make client sys_shmat work properly on arm-linux by taking into
authorJulian Seward <jseward@acm.org>
Wed, 6 Oct 2010 15:24:39 +0000 (15:24 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 6 Oct 2010 15:24:39 +0000 (15:24 +0000)
account rounding requirements to SHMLBA.  Modified version of a patch
by Kirill Batuzov, batuzovk@ispras.ru.  This fixes the main bug in
#222545.  Temporarily breaks the build on all other platforms though.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11399

coregrind/m_syswrap/syswrap-arm-linux.c
coregrind/m_syswrap/syswrap-generic.c
include/vki/vki-arm-linux.h
include/vki/vki-linux.h

index 159a011183458725c940d25e453377e1ab57545e..3d1f3b514b54cca922273553f1be7ff349463f7e 100644 (file)
@@ -831,6 +831,12 @@ PRE(wrap_sys_shmat)
    PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    PRE_REG_READ3(long, "shmat",
                  int, shmid, const void *, shmaddr, int, shmflg);
+   /* Round the attach address down to an VKI_SHMLBA boundary if the
+      client requested rounding.  See #222545.  This is necessary only
+      on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
+      other linux targets it is the same as the page size. */
+   if (ARG3 & VKI_SHM_RND)
+      ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
    arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
    if (arg2tmp == 0)
       SET_STATUS_Failure( VKI_EINVAL );
index 9c00c57852fb2e217204fb4d2184f55666a66bfe..22eae2891b5b4e5e60fcc15b992a25172025a1f4 100644 (file)
@@ -1741,9 +1741,26 @@ ML_(generic_PRE_sys_shmat) ( ThreadId tid,
    UWord tmp;
    Bool  ok;
    if (arg1 == 0) {
+      /* arm-linux only: work around the fact that
+         VG_(am_get_advisory_client_simple) produces something that is
+         VKI_PAGE_SIZE aligned, whereas what we want is something
+         VKI_SHMLBA aligned, and VKI_SHMLBA >= VKI_PAGE_SIZE.  Hence
+         increase the request size by VKI_SHMLBA - VKI_PAGE_SIZE and
+         then round the result up to the next VKI_SHMLBA boundary.
+         See bug 222545 comment 15.  So far, arm-linux is the only
+         platform where this is known to be necessary. */
+      vg_assert(VKI_SHMLBA >= VKI_PAGE_SIZE);
+      if (VKI_SHMLBA > VKI_PAGE_SIZE) {
+         segmentSize += VKI_SHMLBA - VKI_PAGE_SIZE;
+      }
       tmp = VG_(am_get_advisory_client_simple)(0, segmentSize, &ok);
-      if (ok)
-         arg1 = tmp;
+      if (ok) {
+         if (VKI_SHMLBA > VKI_PAGE_SIZE) {
+            arg1 = VG_ROUNDUP(tmp, VKI_SHMLBA);
+         } else {
+            arg1 = tmp;
+         }
+      }
    }
    else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
       arg1 = 0;
index 9e6ff1ea7223a7bdae94eeb16367e36bceffbe59..508be437910828ab385e7c2dc3a3ed938f65c98c 100644 (file)
@@ -731,6 +731,8 @@ struct vki_ipc_kludge {
 #define VKI_SHMGET             23
 #define VKI_SHMCTL             24
 
+#define VKI_SHMLBA  (4 * VKI_PAGE_SIZE)
+
 
 //----------------------------------------------------------------------
 // From linux-2.6.8.1/include/asm-i386/shmbuf.h
index 6b676e6aeb0efeb41479835638b2922f1d9fd09f..537f0e09dd8b7356f56b982cea528b51f87b609a 100644 (file)
@@ -1451,6 +1451,7 @@ struct vki_shmid_ds {
 };
 
 #define VKI_SHM_RDONLY  010000  /* read-only access */
+#define VKI_SHM_RND     020000  /* round attach address to SHMLBA boundary */
 
 #define VKI_SHM_STAT   13
 #define VKI_SHM_INFO   14