[PATCH] [BZ #10283] localedef: align fixed maps to SHMLBA

Mike Frysinger vapier@gentoo.org
Thu May 23 16:47:00 GMT 2013


Many Linux arches require fixed mmaps to be aligned higher than pagesize,
so use the SHMLBA define as it represents this quantity exactly.

This fixes spurious errors seen on those arches like:
cannot map archive header: Invalid argument

URL: http://sourceware.org/bugzilla/show_bug.cgi?id=10283
Reported-by: CHIKAMA Masaki <masaki.chikama@gmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>

2013-05-23  Mike Frysinger  <vapier@gentoo.org>

	* locale/programs/locarchive.c: Include sys/shm.h.
	(prepare_address_space): Align p to SHMLBA.
	(file_data_available_p): Replace pagesz with SHMLBA.
---
note: seems to be passing on x86_64, but need to do a build on an affected
	arch to make sure things are OK.

 locale/programs/locarchive.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c
index d31472d..09bd4c8 100644
--- a/locale/programs/locarchive.c
+++ b/locale/programs/locarchive.c
@@ -37,6 +37,7 @@
 #include <stdint.h>
 #include <sys/mman.h>
 #include <sys/param.h>
+#include <sys/shm.h>
 #include <sys/stat.h>
 
 #include "../../crypt/md5.h"
@@ -85,11 +86,14 @@ prepare_address_space (int fd, size_t total, size_t *reserved, int *xflags)
     {
       void *p = mmap64 (NULL, RESERVE_MMAP_SIZE, PROT_NONE, MAP_SHARED, fd, 0);
       if (p != MAP_FAILED)
-        {
-          *reserved = RESERVE_MMAP_SIZE;
-          *xflags = MAP_FIXED;
-          return p;
-        }
+	{
+	  /* Some arches require fixed mappings to be aligned higher than
+	     pagesize, and SHMLBA represents that size.  */
+	  size_t align_adjust = (uintptr_t)p & SHMLBA;
+	  *reserved = RESERVE_MMAP_SIZE - align_adjust;
+	  *xflags = MAP_FIXED;
+	  return p + align_adjust;
+	}
     }
 
   *reserved = total;
@@ -271,8 +275,7 @@ file_data_available_p (struct locarhandle *ah, uint32_t offset, uint32_t size)
   if (st.st_size > ah->reserved)
     return false;
 
-  const size_t pagesz = getpagesize ();
-  size_t start = ah->mmaped & ~(pagesz - 1);
+  size_t start = ah->mmaped & ~(SHMLBA - 1);
   void *p = mmap64 (ah->addr + start, st.st_size - start,
 		    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
 		    ah->fd, start);
-- 
1.8.2.1



More information about the Libc-alpha mailing list